llvm.org GIT mirror llvm / eaf1c98
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 Bob Wilson 10 years ago
9 changed file(s) with 82 addition(s) and 46 deletion(s). Raw diff Collapse all Expand all
119119 void printAddrModePCOperand(const MachineInstr *MI, int OpNum,
120120 raw_ostream &O,
121121 const char *Modifier = 0);
122 void printBitfieldInvMaskImmOperand (const MachineInstr *MI, int OpNum,
123 raw_ostream &O);
122 void printBitfieldInvMaskImmOperand(const MachineInstr *MI, int OpNum,
123 raw_ostream &O);
124 void printSatShiftOperand(const MachineInstr *MI, int OpNum,
125 raw_ostream &O);
124126
125127 void printThumbS4ImmOperand(const MachineInstr *MI, int OpNum,
126128 raw_ostream &O);
666668 int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
667669 assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
668670 O << "#" << lsb << ", #" << width;
671 }
672
673 void ARMAsmPrinter::printSatShiftOperand(const MachineInstr *MI, int OpNum,
674 raw_ostream &O) {
675 unsigned ShiftOp = MI->getOperand(OpNum).getImm();
676 ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
677 switch (Opc) {
678 case ARM_AM::no_shift:
679 return;
680 case ARM_AM::lsl:
681 O << ", lsl #";
682 break;
683 case ARM_AM::asr:
684 O << ", asr #";
685 break;
686 default:
687 assert(0 && "unexpected shift opcode for saturate shift operand");
688 }
689 O << ARM_AM::getSORegOffset(ShiftOp);
669690 }
670691
671692 //===--------------------------------------------------------------------===//
12461246
12471247 // Encode saturate bit position.
12481248 unsigned Pos = MI.getOperand(1).getImm();
1249 if (TID.Opcode == ARM::SSATlsl ||
1250 TID.Opcode == ARM::SSATasr ||
1251 TID.Opcode == ARM::SSAT16)
1249 if (TID.Opcode == ARM::SSAT || TID.Opcode == ARM::SSAT16)
12521250 Pos -= 1;
12531251 assert((Pos < 16 || (Pos < 32 &&
12541252 TID.Opcode != ARM::SSAT16 &&
12611259
12621260 // Encode shift_imm.
12631261 if (TID.getNumOperands() == 4) {
1262 unsigned ShiftOp = MI.getOperand(3).getImm();
1263 ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
1264 if (Opc == ARM_AM::asr)
1265 Binary |= (1 << 6);
12641266 unsigned ShiftAmt = MI.getOperand(3).getImm();
1265 if (ShiftAmt == 32 &&
1266 (TID.Opcode == ARM::SSATasr || TID.Opcode == ARM::USATasr))
1267 if (ShiftAmt == 32 && Opc == ARM_AM::asr)
12671268 ShiftAmt = 0;
12681269 assert(ShiftAmt < 32 && "shift_imm range is 0 to 31!");
12691270 Binary |= ShiftAmt << ARMII::ShiftShift;
18091809
18101810 // Signed/Unsigned saturate -- for disassembly only
18111811
1812 def SSATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1813 SatFrm, NoItinerary,
1814 "ssat", "\t$dst, $bit_pos, $a, lsl $shamt",
1815 [/* For disassembly only; pattern left blank */]> {
1812 def sat_shift : Operand> {
1813 let PrintMethod = "printSatShiftOperand";
1814 }
1815
1816 def SSAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, sat_shift:$sh),
1817 SatFrm, NoItinerary, "ssat", "\t$dst, $bit_pos, $a$sh",
1818 [/* For disassembly only; pattern left blank */]> {
18161819 let Inst{27-21} = 0b0110101;
1817 let Inst{6-4} = 0b001;
1818 }
1819
1820 def SSATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1821 SatFrm, NoItinerary,
1822 "ssat", "\t$dst, $bit_pos, $a, asr $shamt",
1823 [/* For disassembly only; pattern left blank */]> {
1824 let Inst{27-21} = 0b0110101;
1825 let Inst{6-4} = 0b101;
1820 let Inst{5-4} = 0b01;
18261821 }
18271822
18281823 def SSAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
18321827 let Inst{7-4} = 0b0011;
18331828 }
18341829
1835 def USATlsl : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1836 SatFrm, NoItinerary,
1837 "usat", "\t$dst, $bit_pos, $a, lsl $shamt",
1838 [/* For disassembly only; pattern left blank */]> {
1830 def USAT : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, sat_shift:$sh),
1831 SatFrm, NoItinerary, "usat", "\t$dst, $bit_pos, $a$sh",
1832 [/* For disassembly only; pattern left blank */]> {
18391833 let Inst{27-21} = 0b0110111;
1840 let Inst{6-4} = 0b001;
1841 }
1842
1843 def USATasr : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a, i32imm:$shamt),
1844 SatFrm, NoItinerary,
1845 "usat", "\t$dst, $bit_pos, $a, asr $shamt",
1846 [/* For disassembly only; pattern left blank */]> {
1847 let Inst{27-21} = 0b0110111;
1848 let Inst{6-4} = 0b101;
1834 let Inst{5-4} = 0b01;
18491835 }
18501836
18511837 def USAT16 : AI<(outs GPR:$dst), (ins i32imm:$bit_pos, GPR:$a), SatFrm,
18551841 let Inst{7-4} = 0b0011;
18561842 }
18571843
1858 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSATlsl imm:$pos, GPR:$a, 0)>;
1859 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USATlsl imm:$pos, GPR:$a, 0)>;
1844 def : ARMV6Pat<(int_arm_ssat GPR:$a, imm:$pos), (SSAT imm:$pos, GPR:$a, 0)>;
1845 def : ARMV6Pat<(int_arm_usat GPR:$a, imm:$pos), (USAT imm:$pos, GPR:$a, 0)>;
18601846
18611847 //===----------------------------------------------------------------------===//
18621848 // Bitwise Instructions.
460460 assert(0 && "FIXME: Implement printAddrModePCOperand");
461461 }
462462
463 void ARMInstPrinter::printBitfieldInvMaskImmOperand (const MCInst *MI,
464 unsigned OpNum,
465 raw_ostream &O) {
463 void ARMInstPrinter::printBitfieldInvMaskImmOperand(const MCInst *MI,
464 unsigned OpNum,
465 raw_ostream &O) {
466466 const MCOperand &MO = MI->getOperand(OpNum);
467467 uint32_t v = ~MO.getImm();
468468 int32_t lsb = CountTrailingZeros_32(v);
469469 int32_t width = (32 - CountLeadingZeros_32 (v)) - lsb;
470470 assert(MO.isImm() && "Not a valid bf_inv_mask_imm value!");
471471 O << '#' << lsb << ", #" << width;
472 }
473
474 void ARMInstPrinter::printSatShiftOperand(const MCInst *MI, unsigned OpNum,
475 raw_ostream &O) {
476 unsigned ShiftOp = MI->getOperand(OpNum).getImm();
477 ARM_AM::ShiftOpc Opc = ARM_AM::getSORegShOp(ShiftOp);
478 switch (Opc) {
479 case ARM_AM::no_shift:
480 return;
481 case ARM_AM::lsl:
482 O << ", lsl #";
483 break;
484 case ARM_AM::asr:
485 O << ", asr #";
486 break;
487 default:
488 assert(0 && "unexpected shift opcode for saturate shift operand");
489 }
490 O << ARM_AM::getSORegOffset(ShiftOp);
472491 }
473492
474493 void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
5656
5757 void printBitfieldInvMaskImmOperand(const MCInst *MI, unsigned OpNum,
5858 raw_ostream &O);
59 void printSatShiftOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
5960
6061 void printThumbS4ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
6162 void printThumbITMask(const MCInst *MI, unsigned OpNum, raw_ostream &O);
105105 // Ditto for STRT, which is a super-instruction for A8.6.210 Encoding A1 & A2.
106106 // As a result, the decoder fails to deocode SSAT properly.
107107 if (slice(insn, 27, 21) == 0x35 && slice(insn, 5, 4) == 1)
108 return slice(insn, 6, 6) == 0 ? ARM::SSATlsl : ARM::SSATasr;
108 return ARM::SSAT;
109109
110110 // Ditto for RSCrs, which is a super-instruction for A8.6.146 & A8.6.147.
111111 // As a result, the decoder fails to decode STRHT/LDRHT/LDRSHT/LDRSBT.
14651465 decodeRd(insn))));
14661466
14671467 unsigned Pos = slice(insn, 20, 16);
1468 if (Opcode == ARM::SSATlsl ||
1469 Opcode == ARM::SSATasr ||
1470 Opcode == ARM::SSAT16)
1468 if (Opcode == ARM::SSAT || Opcode == ARM::SSAT16)
14711469 Pos += 1;
14721470 MI.addOperand(MCOperand::CreateImm(Pos));
14731471
14751473 decodeRm(insn))));
14761474
14771475 if (NumOpsAdded == 4) {
1476 ARM_AM::ShiftOpc Opc = (slice(insn, 6, 6) != 0 ? ARM_AM::asr : ARM_AM::lsl);
14781477 // Inst{11-7} encodes the imm5 shift amount.
14791478 unsigned ShAmt = slice(insn, 11, 7);
1480 // A8.6.183. Possible ASR shift amount of 32...
1481 if ((Opcode == ARM::SSATasr || Opcode == ARM::USATasr) && ShAmt == 0)
1482 ShAmt = 32;
1483 MI.addOperand(MCOperand::CreateImm(ShAmt));
1479 if (ShAmt == 0) {
1480 // A8.6.183. Possible ASR shift amount of 32...
1481 if (Opc == ARM_AM::asr)
1482 ShAmt = 32;
1483 else
1484 Opc = ARM_AM::no_shift;
1485 }
1486 MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(Opc, ShAmt)));
14841487 }
14851488 return true;
14861489 }
7777 # CHECK: ssat r8, #1, r10, lsl #8
7878 0x1a 0x84 0xa0 0xe6
7979
80 # CHECK-NOT: ssatmi r0, #17, r12, lsl #0
81 # CHECK: ssatmi r0, #17, r12
82 0x1c 0x00 0xb0 0x46
83
8084 # CHECK: stmdb r10!, {r4, r5, r6, r7, lr}
8185 0xf0 0x40 0x2a 0xe9
8286
606606 IMM("jt2block_operand");
607607 IMM("t_imm_s4");
608608 IMM("pclabel");
609 IMM("sat_shift");
609610
610611 MISC("brtarget", "kOperandTypeARMBranchTarget"); // ?
611612 MISC("so_reg", "kOperandTypeARMSoReg"); // R, R, I