ARM PKH shift ammount operand printing tweaks.
authorJim Grosbach <grosbach@apple.com>
Wed, 20 Jul 2011 21:40:26 +0000 (21:40 +0000)
committerJim Grosbach <grosbach@apple.com>
Wed, 20 Jul 2011 21:40:26 +0000 (21:40 +0000)
Move the shift operator and special value (32 encoded as 0 for PKHTB) handling
into the instruction printer. This cleans up a bit of the disassembler
special casing for these instructions, more easily handles not printing the
operand at all for "lsl #0" and prepares for correct asm parsing of these
operands.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135626 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrFormats.td
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
lib/Target/ARM/InstPrinter/ARMInstPrinter.cpp
lib/Target/ARM/InstPrinter/ARMInstPrinter.h
utils/TableGen/EDEmitter.cpp

index 7960644e1752122901b3c023ee632c7812151866..ac00591f159bcdf9b5935e1fda2b2966bf8bd23b 100644 (file)
@@ -847,8 +847,12 @@ class AMiscA1I<bits<8> opcod, bits<4> opc7_4, dag oops, dag iops,
 }
 
 // PKH instructions
-def pkh_lsl_amt : ImmLeaf<i32, [{ return Imm >= 0 && Imm < 32; }]>;
-def pkh_asr_amt : ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]>;
+def pkh_lsl_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 32; }]>{
+  let PrintMethod = "printPKHLSLShiftImm";
+}
+def pkh_asr_amt: Operand<i32>, ImmLeaf<i32, [{ return Imm > 0 && Imm <= 32; }]>{
+  let PrintMethod = "printPKHASRShiftImm";
+}
 
 class APKHI<bits<8> opcod, bit tb, dag oops, dag iops, InstrItinClass itin,
             string opc, string asm, list<dag> pattern>
index 76714d550fb11af5a0ffbf5548742d425955af1c..739a73309e097804dbcab3bc04caac1aff09da74 100644 (file)
@@ -3112,8 +3112,8 @@ def : ARMV6Pat<(or (sra (shl GPR:$Rm, (i32 24)), (i32 16)),
                (REVSH GPR:$Rm)>;
 
 def PKHBT : APKHI<0b01101000, 0, (outs GPR:$Rd),
-                              (ins GPR:$Rn, GPR:$Rm, i32imm:$sh),
-               IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm, lsl $sh",
+                              (ins GPR:$Rn, GPR:$Rm, pkh_lsl_amt:$sh),
+               IIC_iALUsi, "pkhbt", "\t$Rd, $Rn, $Rm$sh",
                [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF),
                                   (and (shl GPR:$Rm, pkh_lsl_amt:$sh),
                                        0xFFFF0000)))]>,
@@ -3128,8 +3128,8 @@ def : ARMV6Pat<(or (and GPR:$Rn, 0xFFFF), (shl GPR:$Rm, imm16_31:$sh)),
 // Note: Shifts of 1-15 bits will be transformed to srl instead of sra and
 // will match the pattern below.
 def PKHTB : APKHI<0b01101000, 1, (outs GPR:$Rd),
-                              (ins GPR:$Rn, GPR:$Rm, i32imm:$sh),
-               IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm, asr $sh",
+                              (ins GPR:$Rn, GPR:$Rm, pkh_asr_amt:$sh),
+               IIC_iBITsi, "pkhtb", "\t$Rd, $Rn, $Rm$sh",
                [(set GPR:$Rd, (or (and GPR:$Rn, 0xFFFF0000),
                                   (and (sra GPR:$Rm, pkh_asr_amt:$sh),
                                        0xFFFF)))]>,
index 320679ea88a5b82d0dca8f37888cb07cb3acf906..22aa10c77160f02a30428fbdb34f1645bf10d78f 100644 (file)
@@ -1632,16 +1632,11 @@ static bool DisassembleArithMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
       && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
     // Extract the 5-bit immediate field Inst{11-7}.
     unsigned ShiftAmt = (insn >> ARMII::ShiftShift) & 0x1F;
-    ARM_AM::ShiftOpc Opc = ARM_AM::no_shift;
-    if (Opcode == ARM::PKHBT)
-      Opc = ARM_AM::lsl;
-    else if (Opcode == ARM::PKHTB)
-      Opc = ARM_AM::asr;
-    getImmShiftSE(Opc, ShiftAmt);
     if (Opcode == ARM::PKHBT || Opcode == ARM::PKHTB)
       MI.addOperand(MCOperand::CreateImm(ShiftAmt));
      else
-      MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(Opc, ShiftAmt)));
+      MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ARM_AM::no_shift,
+                                                             ShiftAmt)));
     ++OpIdx;
   }
 
index 9d1fdc1feb12fa6c505b2213fa9b1e744f8ea35f..4f97def26e27b00433f4311a2af03d8bf249697a 100644 (file)
@@ -1498,16 +1498,17 @@ static bool DisassembleThumb2DPSoReg(MCInst &MI, unsigned Opcode, uint32_t insn,
       MI.addOperand(MCOperand::CreateImm(Imm));
     } else {
       // Build the constant shift specifier operand.
-      unsigned bits2 = getShiftTypeBits(insn);
       unsigned imm5 = getShiftAmtBits(insn);
-      ARM_AM::ShiftOpc ShOp = ARM_AM::no_shift;
-      unsigned ShAmt = decodeImmShift(bits2, imm5, ShOp);
       // The PKHBT/PKHTB instructions have an implied shift type and so just
       // use a plain immediate for the amount.
       if (Opcode == ARM::t2PKHBT || Opcode == ARM::t2PKHTB)
-        MI.addOperand(MCOperand::CreateImm(ShAmt));
-      else
+        MI.addOperand(MCOperand::CreateImm(imm5));
+      else {
+        ARM_AM::ShiftOpc ShOp = ARM_AM::no_shift;
+        unsigned bits2 = getShiftTypeBits(insn);
+        unsigned ShAmt = decodeImmShift(bits2, imm5, ShOp);
         MI.addOperand(MCOperand::CreateImm(ARM_AM::getSORegOpc(ShOp, ShAmt)));
+      }
     }
     ++OpIdx;
   }
index 4a178dc9215e8f2ec3efbbdc445b6b4c0b6b477c..e49825381d2efc7d21c9a1ff25d7693d22575227 100644 (file)
@@ -441,6 +441,25 @@ void ARMInstPrinter::printShiftImmOperand(const MCInst *MI, unsigned OpNum,
   O << ARM_AM::getSORegOffset(ShiftOp);
 }
 
+void ARMInstPrinter::printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum,
+                                         raw_ostream &O) {
+  unsigned Imm = MI->getOperand(OpNum).getImm();
+  if (Imm == 0)
+    return;
+  assert(Imm > 0 && Imm < 32 && "Invalid PKH shift immediate value!");
+  O << ", lsl #" << Imm;
+}
+
+void ARMInstPrinter::printPKHASRShiftImm(const MCInst *MI, unsigned OpNum,
+                                         raw_ostream &O) {
+  unsigned Imm = MI->getOperand(OpNum).getImm();
+  // A shift amount of 32 is encoded as 0.
+  if (Imm == 0)
+    Imm = 32;
+  assert(Imm > 0 && Imm <= 32 && "Invalid PKH shift immediate value!");
+  O << ", asr #" << Imm;
+}
+
 void ARMInstPrinter::printRegisterList(const MCInst *MI, unsigned OpNum,
                                        raw_ostream &O) {
   O << "{";
index d5f238bb8a61bac2e57e667f74be2426bfa15892..8f3172922cce3697b152187954b3c84d380c3785 100644 (file)
@@ -65,6 +65,8 @@ public:
                                       raw_ostream &O);
   void printMemBOption(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printShiftImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+  void printPKHLSLShiftImm(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+  void printPKHASRShiftImm(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);
index 7cfca93e7a89aaa31703e6a489e83f2a2287fc67..a1ad83c11b1a182279f0e5f5d76edbf3a118daa2 100644 (file)
@@ -594,6 +594,8 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
   IMM("imm0_4095");
   IMM("imm0_65535");
   IMM("imm0_65535_expr");
+  IMM("pkh_lsl_amt");
+  IMM("pkh_asr_amt");
   IMM("jt2block_operand");
   IMM("t_imm_s4");
   IMM("pclabel");