mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 21:29:41 +00:00
Move the ARM SSAT and USAT optional shift amount operand out of the
instruction opcode. This also fixes part of PR7792. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@110875 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
d29583bd32
commit
eaf1c98a7c
@ -120,8 +120,10 @@ namespace {
|
|||||||
void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
|
void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
|
||||||
raw_ostream &O,
|
raw_ostream &O,
|
||||||
const char *Modifier = 0);
|
const char *Modifier = 0);
|
||||||
void printBitfieldInvMaskImmOperand (const MachineInstr *MI, int OpNum,
|
void printBitfieldInvMaskImmOperand(const MachineInstr *MI, int OpNum,
|
||||||
raw_ostream &O);
|
raw_ostream &O);
|
||||||
|
void printSatShiftOperand(const MachineInstr *MI, int OpNum,
|
||||||
|
raw_ostream &O);
|
||||||
|
|
||||||
void printThumbS4ImmOperand(const MachineInstr *MI, int OpNum,
|
void printThumbS4ImmOperand(const MachineInstr *MI, int OpNum,
|
||||||
raw_ostream &O);
|
raw_ostream &O);
|
||||||
@ -669,6 +671,25 @@ ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op,
|
|||||||
O << "#" << lsb << ", #" << width;
|
O << "#" << lsb << ", #" << width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMAsmPrinter::printSatShiftOperand(const MachineInstr *MI, int OpNum,
|
||||||
|
raw_ostream &O) {
|
||||||
|
unsigned ShiftOp = MI->getOperand(OpNum).getImm();
|
||||||
|
ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
|
||||||
|
switch (Opc) {
|
||||||
|
case ARM_AM::no_shift:
|
||||||
|
return;
|
||||||
|
case ARM_AM::lsl:
|
||||||
|
O << ", lsl #";
|
||||||
|
break;
|
||||||
|
case ARM_AM::asr:
|
||||||
|
O << ", asr #";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0 && "unexpected shift opcode for saturate shift operand");
|
||||||
|
}
|
||||||
|
O << ARM_AM::getSORegOffset(ShiftOp);
|
||||||
|
}
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
||||||
void ARMAsmPrinter::printThumbS4ImmOperand(const MachineInstr *MI, int Op,
|
void ARMAsmPrinter::printThumbS4ImmOperand(const MachineInstr *MI, int Op,
|
||||||
|
@ -1247,9 +1247,7 @@ void ARMCodeEmitter::emitSaturateInstruction(const MachineInstr &MI) {
|
|||||||
|
|
||||||
// Encode saturate bit position.
|
// Encode saturate bit position.
|
||||||
unsigned Pos = MI.getOperand(1).getImm();
|
unsigned Pos = MI.getOperand(1).getImm();
|
||||||
if (TID.Opcode == ARM::SSATlsl ||
|
if (TID.Opcode == ARM::SSAT || TID.Opcode == ARM::SSAT16)
|
||||||
TID.Opcode == ARM::SSATasr ||
|
|
||||||
TID.Opcode == ARM::SSAT16)
|
|
||||||
Pos -= 1;
|
Pos -= 1;
|
||||||
assert((Pos < 16 || (Pos < 32 &&
|
assert((Pos < 16 || (Pos < 32 &&
|
||||||
TID.Opcode != ARM::SSAT16 &&
|
TID.Opcode != ARM::SSAT16 &&
|
||||||
@ -1262,9 +1260,12 @@ void ARMCodeEmitter::emitSaturateInstruction(const MachineInstr &MI) {
|
|||||||
|
|
||||||
// Encode shift_imm.
|
// Encode shift_imm.
|
||||||
if (TID.getNumOperands() == 4) {
|
if (TID.getNumOperands() == 4) {
|
||||||
|
unsigned ShiftOp = MI.getOperand(3).getImm();
|
||||||
|
ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
|
||||||
|
if (Opc == ARM_AM::asr)
|
||||||
|
Binary |= (1 << 6);
|
||||||
unsigned ShiftAmt = MI.getOperand(3).getImm();
|
unsigned ShiftAmt = MI.getOperand(3).getImm();
|
||||||
if (ShiftAmt == 32 &&
|
if (ShiftAmt == 32 && Opc == ARM_AM::asr)
|
||||||
(TID.Opcode == ARM::SSATasr || TID.Opcode == ARM::USATasr))
|
|
||||||
ShiftAmt = 0;
|
ShiftAmt = 0;
|
||||||
assert(ShiftAmt < 32 && "shift_imm range is 0 to 31!");
|
assert(ShiftAmt < 32 && "shift_imm range is 0 to 31!");
|
||||||
Binary |= ShiftAmt << ARMII::ShiftShift;
|
Binary |= ShiftAmt << ARMII::ShiftShift;
|
||||||
|
@ -1810,20 +1810,15 @@ def USADA8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
|
|||||||
|
|
||||||
// Signed/Unsigned saturate -- for disassembly only
|
// Signed/Unsigned saturate -- for disassembly only
|
||||||
|
|
||||||
def SSATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
|
def sat_shift : Operand<i32> {
|
||||||
SatFrm, NoItinerary,
|
let PrintMethod = "printSatShiftOperand";
|
||||||
"ssat", "\t$dst, $bit_pos, $a, lsl $shamt",
|
|
||||||
[/* For disassembly only; pattern left blank */]> {
|
|
||||||
let Inst{27-21} = 0b0110101;
|
|
||||||
let Inst{6-4} = 0b001;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def SSATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
|
def SSAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, sat_shift:$sh),
|
||||||
SatFrm, NoItinerary,
|
SatFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh",
|
||||||
"ssat", "\t$dst, $bit_pos, $a, asr $shamt",
|
[/* For disassembly only; pattern left blank */]> {
|
||||||
[/* For disassembly only; pattern left blank */]> {
|
|
||||||
let Inst{27-21} = 0b0110101;
|
let Inst{27-21} = 0b0110101;
|
||||||
let Inst{6-4} = 0b101;
|
let Inst{5-4} = 0b01;
|
||||||
}
|
}
|
||||||
|
|
||||||
def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
|
def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
|
||||||
@ -1833,20 +1828,11 @@ def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
|
|||||||
let Inst{7-4} = 0b0011;
|
let Inst{7-4} = 0b0011;
|
||||||
}
|
}
|
||||||
|
|
||||||
def USATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
|
def USAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, sat_shift:$sh),
|
||||||
SatFrm, NoItinerary,
|
SatFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
|
||||||
"usat", "\t$dst, $bit_pos, $a, lsl $shamt",
|
[/* For disassembly only; pattern left blank */]> {
|
||||||
[/* For disassembly only; pattern left blank */]> {
|
|
||||||
let Inst{27-21} = 0b0110111;
|
let Inst{27-21} = 0b0110111;
|
||||||
let Inst{6-4} = 0b001;
|
let Inst{5-4} = 0b01;
|
||||||
}
|
|
||||||
|
|
||||||
def USATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
|
|
||||||
SatFrm, NoItinerary,
|
|
||||||
"usat", "\t$dst, $bit_pos, $a, asr $shamt",
|
|
||||||
[/* For disassembly only; pattern left blank */]> {
|
|
||||||
let Inst{27-21} = 0b0110111;
|
|
||||||
let Inst{6-4} = 0b101;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
|
def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
|
||||||
@ -1856,8 +1842,8 @@ def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
|
|||||||
let Inst{7-4} = 0b0011;
|
let Inst{7-4} = 0b0011;
|
||||||
}
|
}
|
||||||
|
|
||||||
def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSATlsl imm:$pos, GPR:$a, 0)>;
|
def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
|
||||||
def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USATlsl imm:$pos, GPR:$a, 0)>;
|
def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Bitwise Instructions.
|
// Bitwise Instructions.
|
||||||
|
@ -461,9 +461,9 @@ void ARMInstPrinter::printAddrModePCOperand(const MCInst *MI, unsigned OpNum,
|
|||||||
assert(0 && "FIXME: Implement printAddrModePCOperand");
|
assert(0 && "FIXME: Implement printAddrModePCOperand");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ARMInstPrinter::printBitfieldInvMaskImmOperand (const MCInst *MI,
|
void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI,
|
||||||
unsigned OpNum,
|
unsigned OpNum,
|
||||||
raw_ostream &O) {
|
raw_ostream &O) {
|
||||||
const MCOperand &MO = MI->getOperand(OpNum);
|
const MCOperand &MO = MI->getOperand(OpNum);
|
||||||
uint32_t v = ~MO.getImm();
|
uint32_t v = ~MO.getImm();
|
||||||
int32_t lsb = CountTrailingZeros_32(v);
|
int32_t lsb = CountTrailingZeros_32(v);
|
||||||
@ -472,6 +472,25 @@ void ARMInstPrinter::printBitfieldInvMaskImmOperand (const MCInst *MI,
|
|||||||
O << '#' << lsb << ", #" << width;
|
O << '#' << lsb << ", #" << width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ARMInstPrinter::printSatShiftOperand(const MCInst *MI, unsigned OpNum,
|
||||||
|
raw_ostream &O) {
|
||||||
|
unsigned ShiftOp = MI->getOperand(OpNum).getImm();
|
||||||
|
ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
|
||||||
|
switch (Opc) {
|
||||||
|
case ARM_AM::no_shift:
|
||||||
|
return;
|
||||||
|
case ARM_AM::lsl:
|
||||||
|
O << ", lsl #";
|
||||||
|
break;
|
||||||
|
case ARM_AM::asr:
|
||||||
|
O << ", asr #";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0 && "unexpected shift opcode for saturate shift operand");
|
||||||
|
}
|
||||||
|
O << ARM_AM::getSORegOffset(ShiftOp);
|
||||||
|
}
|
||||||
|
|
||||||
void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
|
void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
|
||||||
raw_ostream &O) {
|
raw_ostream &O) {
|
||||||
O << "{";
|
O << "{";
|
||||||
|
@ -57,6 +57,7 @@ public:
|
|||||||
|
|
||||||
void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum,
|
void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum,
|
||||||
raw_ostream &O);
|
raw_ostream &O);
|
||||||
|
void printSatShiftOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||||
|
|
||||||
void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||||
void printThumbITMask(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
void printThumbITMask(const MCInst *MI, unsigned OpNum, raw_ostream &O);
|
||||||
|
@ -106,7 +106,7 @@ static unsigned decodeARMInstruction(uint32_t &insn) {
|
|||||||
// Ditto for STRT, which is a super-instruction for A8.6.210 Encoding A1 & A2.
|
// Ditto for STRT, which is a super-instruction for A8.6.210 Encoding A1 & A2.
|
||||||
// As a result, the decoder fails to deocode SSAT properly.
|
// As a result, the decoder fails to deocode SSAT properly.
|
||||||
if (slice(insn, 27, 21) == 0x35 && slice(insn, 5, 4) == 1)
|
if (slice(insn, 27, 21) == 0x35 && slice(insn, 5, 4) == 1)
|
||||||
return slice(insn, 6, 6) == 0 ? ARM::SSATlsl : ARM::SSATasr;
|
return ARM::SSAT;
|
||||||
|
|
||||||
// Ditto for RSCrs, which is a super-instruction for A8.6.146 & A8.6.147.
|
// Ditto for RSCrs, which is a super-instruction for A8.6.146 & A8.6.147.
|
||||||
// As a result, the decoder fails to decode STRHT/LDRHT/LDRSHT/LDRSBT.
|
// As a result, the decoder fails to decode STRHT/LDRHT/LDRSHT/LDRSBT.
|
||||||
|
@ -1466,9 +1466,7 @@ static bool DisassembleSatFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
|
|||||||
decodeRd(insn))));
|
decodeRd(insn))));
|
||||||
|
|
||||||
unsigned Pos = slice(insn, 20, 16);
|
unsigned Pos = slice(insn, 20, 16);
|
||||||
if (Opcode == ARM::SSATlsl ||
|
if (Opcode == ARM::SSAT || Opcode == ARM::SSAT16)
|
||||||
Opcode == ARM::SSATasr ||
|
|
||||||
Opcode == ARM::SSAT16)
|
|
||||||
Pos += 1;
|
Pos += 1;
|
||||||
MI.addOperand(MCOperand::CreateImm(Pos));
|
MI.addOperand(MCOperand::CreateImm(Pos));
|
||||||
|
|
||||||
@ -1476,12 +1474,17 @@ static bool DisassembleSatFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
|
|||||||
decodeRm(insn))));
|
decodeRm(insn))));
|
||||||
|
|
||||||
if (NumOpsAdded == 4) {
|
if (NumOpsAdded == 4) {
|
||||||
|
ARM_AM::ShiftOpc Opc = (slice(insn, 6, 6) != 0 ? ARM_AM::asr : ARM_AM::lsl);
|
||||||
// Inst{11-7} encodes the imm5 shift amount.
|
// Inst{11-7} encodes the imm5 shift amount.
|
||||||
unsigned ShAmt = slice(insn, 11, 7);
|
unsigned ShAmt = slice(insn, 11, 7);
|
||||||
// A8.6.183. Possible ASR shift amount of 32...
|
if (ShAmt == 0) {
|
||||||
if ((Opcode == ARM::SSATasr || Opcode == ARM::USATasr) && ShAmt == 0)
|
// A8.6.183. Possible ASR shift amount of 32...
|
||||||
ShAmt = 32;
|
if (Opc == ARM_AM::asr)
|
||||||
MI.addOperand(MCOperand::CreateImm(ShAmt));
|
ShAmt = 32;
|
||||||
|
else
|
||||||
|
Opc = ARM_AM::no_shift;
|
||||||
|
}
|
||||||
|
MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(Opc, ShAmt)));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -78,6 +78,10 @@
|
|||||||
# CHECK: ssat r8, #1, r10, lsl #8
|
# CHECK: ssat r8, #1, r10, lsl #8
|
||||||
0x1a 0x84 0xa0 0xe6
|
0x1a 0x84 0xa0 0xe6
|
||||||
|
|
||||||
|
# CHECK-NOT: ssatmi r0, #17, r12, lsl #0
|
||||||
|
# CHECK: ssatmi r0, #17, r12
|
||||||
|
0x1c 0x00 0xb0 0x46
|
||||||
|
|
||||||
# CHECK: stmdb r10!, {r4, r5, r6, r7, lr}
|
# CHECK: stmdb r10!, {r4, r5, r6, r7, lr}
|
||||||
0xf0 0x40 0x2a 0xe9
|
0xf0 0x40 0x2a 0xe9
|
||||||
|
|
||||||
|
@ -607,6 +607,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
|
|||||||
IMM("jt2block_operand");
|
IMM("jt2block_operand");
|
||||||
IMM("t_imm_s4");
|
IMM("t_imm_s4");
|
||||||
IMM("pclabel");
|
IMM("pclabel");
|
||||||
|
IMM("sat_shift");
|
||||||
|
|
||||||
MISC("brtarget", "kOperandTypeARMBranchTarget"); // ?
|
MISC("brtarget", "kOperandTypeARMBranchTarget"); // ?
|
||||||
MISC("so_reg", "kOperandTypeARMSoReg"); // R, R, I
|
MISC("so_reg", "kOperandTypeARMSoReg"); // R, R, I
|
||||||
|
Loading…
x
Reference in New Issue
Block a user