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:
Bob Wilson 2010-08-11 23:10:46 +00:00
parent d29583bd32
commit eaf1c98a7c
9 changed files with 80 additions and 44 deletions

View File

@ -122,6 +122,8 @@ namespace {
const char *Modifier = 0);
void printBitfieldInvMaskImmOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printSatShiftOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
void printThumbS4ImmOperand(const MachineInstr *MI, int OpNum,
raw_ostream &O);
@ -669,6 +671,25 @@ ARMAsmPrinter::printBitfieldInvMaskImmOperand(const MachineInstr *MI, int Op,
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,

View File

@ -1247,9 +1247,7 @@ void ARMCodeEmitter::emitSaturateInstruction(const MachineInstr &MI) {
// Encode saturate bit position.
unsigned Pos = MI.getOperand(1).getImm();
if (TID.Opcode == ARM::SSATlsl ||
TID.Opcode == ARM::SSATasr ||
TID.Opcode == ARM::SSAT16)
if (TID.Opcode == ARM::SSAT || TID.Opcode == ARM::SSAT16)
Pos -= 1;
assert((Pos < 16 || (Pos < 32 &&
TID.Opcode != ARM::SSAT16 &&
@ -1262,9 +1260,12 @@ void ARMCodeEmitter::emitSaturateInstruction(const MachineInstr &MI) {
// Encode shift_imm.
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();
if (ShiftAmt == 32 &&
(TID.Opcode == ARM::SSATasr || TID.Opcode == ARM::USATasr))
if (ShiftAmt == 32 && Opc == ARM_AM::asr)
ShiftAmt = 0;
assert(ShiftAmt < 32 && "shift_imm range is 0 to 31!");
Binary |= ShiftAmt << ARMII::ShiftShift;

View File

@ -1810,20 +1810,15 @@ def USADA8 : AI<(outs GPR:$dst), (ins GPR:$a, GPR:$b, GPR:$acc),
// Signed/Unsigned saturate -- for disassembly only
def SSATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
SatFrm, NoItinerary,
"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 sat_shift : Operand<i32> {
let PrintMethod = "printSatShiftOperand";
}
def SSATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
SatFrm, NoItinerary,
"ssat", "\t$dst, $bit_pos, $a, asr $shamt",
def SSAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, sat_shift:$sh),
SatFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh",
[/* For disassembly only; pattern left blank */]> {
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,
@ -1833,20 +1828,11 @@ def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
let Inst{7-4} = 0b0011;
}
def USATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
SatFrm, NoItinerary,
"usat", "\t$dst, $bit_pos, $a, lsl $shamt",
def USAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, sat_shift:$sh),
SatFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
[/* For disassembly only; pattern left blank */]> {
let Inst{27-21} = 0b0110111;
let Inst{6-4} = 0b001;
}
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;
let Inst{5-4} = 0b01;
}
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;
}
def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSATlsl imm:$pos, GPR:$a, 0)>;
def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USATlsl 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), (USAT imm:$pos, GPR:$a, 0)>;
//===----------------------------------------------------------------------===//
// Bitwise Instructions.

View File

@ -472,6 +472,25 @@ void ARMInstPrinter::printBitfieldInvMaskImmOperand (const MCInst *MI,
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,
raw_ostream &O) {
O << "{";

View File

@ -57,6 +57,7 @@ public:
void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum,
raw_ostream &O);
void printSatShiftOperand(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);

View File

@ -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.
// As a result, the decoder fails to deocode SSAT properly.
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.
// As a result, the decoder fails to decode STRHT/LDRHT/LDRSHT/LDRSBT.

View File

@ -1466,9 +1466,7 @@ static bool DisassembleSatFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
decodeRd(insn))));
unsigned Pos = slice(insn, 20, 16);
if (Opcode == ARM::SSATlsl ||
Opcode == ARM::SSATasr ||
Opcode == ARM::SSAT16)
if (Opcode == ARM::SSAT || Opcode == ARM::SSAT16)
Pos += 1;
MI.addOperand(MCOperand::CreateImm(Pos));
@ -1476,12 +1474,17 @@ static bool DisassembleSatFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
decodeRm(insn))));
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.
unsigned ShAmt = slice(insn, 11, 7);
if (ShAmt == 0) {
// A8.6.183. Possible ASR shift amount of 32...
if ((Opcode == ARM::SSATasr || Opcode == ARM::USATasr) && ShAmt == 0)
if (Opc == ARM_AM::asr)
ShAmt = 32;
MI.addOperand(MCOperand::CreateImm(ShAmt));
else
Opc = ARM_AM::no_shift;
}
MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(Opc, ShAmt)));
}
return true;
}

View File

@ -78,6 +78,10 @@
# CHECK: ssat r8, #1, r10, lsl #8
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}
0xf0 0x40 0x2a 0xe9

View File

@ -607,6 +607,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
IMM("jt2block_operand");
IMM("t_imm_s4");
IMM("pclabel");
IMM("sat_shift");
MISC("brtarget", "kOperandTypeARMBranchTarget"); // ?
MISC("so_reg", "kOperandTypeARMSoReg"); // R, R, I