ARM cleanup of rot_imm encoding.
authorJim Grosbach <grosbach@apple.com>
Tue, 26 Jul 2011 21:28:43 +0000 (21:28 +0000)
committerJim Grosbach <grosbach@apple.com>
Tue, 26 Jul 2011 21:28:43 +0000 (21:28 +0000)
Start of cleaning this up a bit. First step is to remove the encoder hook by
storing the operand as the bits it'll actually encode to so it can just be
directly used. Map it to the assembly source values 8/16/24 when we print it.

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

lib/Target/ARM/ARMCodeEmitter.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrThumb2.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
lib/Target/ARM/MCTargetDesc/ARMMCCodeEmitter.cpp

index 61a49a8a095fc1ea5388e0ef6cc2867a85261430..6c10a431d9b6599e3fe0eeb87fbaff5f8b1aa624 100644 (file)
@@ -215,8 +215,6 @@ namespace {
       const { return 0; }
     unsigned getT2SORegOpValue(const MachineInstr &MI, unsigned Op)
       const { return 0; }
-    unsigned getRotImmOpValue(const MachineInstr &MI, unsigned Op)
-      const { return 0; }
     unsigned getImmMinusOneOpValue(const MachineInstr &MI, unsigned Op)
       const { return 0; }
     unsigned getT2AdrLabelOpValue(const MachineInstr &MI, unsigned Op)
index 55735802a341ae71611e96ea9f2fa5b3ddac4787..3b755933b3a7e4f27aecc621eb8b8d9309bba6fe 100644 (file)
@@ -388,10 +388,20 @@ def neon_vcvt_imm32 : Operand<i32> {
 }
 
 // rot_imm: An integer that encodes a rotate amount. Must be 8, 16, or 24.
-def rot_imm : Operand<i32>, ImmLeaf<i32, [{
-    int32_t v = (int32_t)Imm;
-    return v == 8 || v == 16 || v == 24; }]> {
-  let EncoderMethod = "getRotImmOpValue";
+def rot_imm_XFORM: SDNodeXForm<imm, [{
+  switch (N->getZExtValue()){
+  default: assert(0);
+  case 0:  return CurDAG->getTargetConstant(0, MVT::i32);
+  case 8:  return CurDAG->getTargetConstant(1, MVT::i32);
+  case 16: return CurDAG->getTargetConstant(2, MVT::i32);
+  case 24: return CurDAG->getTargetConstant(3, MVT::i32);
+  }
+}]>;
+def rot_imm : Operand<i32>, PatLeaf<(i32 imm), [{
+    int32_t v = N->getZExtValue();
+    return v == 8 || v == 16 || v == 24; }],
+    rot_imm_XFORM> {
+  let PrintMethod = "printRotImmOperand";
 }
 
 // shift_imm: An integer that encodes a shift amount and the type of shift
@@ -989,7 +999,7 @@ multiclass AI_ext_rrot<bits<8> opcod, string opc, PatFrag opnode> {
     let Inst{3-0}   = Rm;
   }
   def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
-                 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
+                 IIC_iEXTr, opc, "\t$Rd, $Rm, $rot",
                  [(set GPR:$Rd, (opnode (rotr GPR:$Rm, rot_imm:$rot)))]>,
               Requires<[IsARM, HasV6]> {
     bits<4> Rd;
@@ -1011,7 +1021,7 @@ multiclass AI_ext_rrot_np<bits<8> opcod, string opc> {
     let Inst{11-10} = 0b00;
   }
   def r_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rm, rot_imm:$rot),
-                 IIC_iEXTr, opc, "\t$Rd, $Rm, ror $rot",
+                 IIC_iEXTr, opc, "\t$Rd, $Rm, $rot",
                  [/* For disassembly only; pattern left blank */]>,
               Requires<[IsARM, HasV6]> {
     bits<2> rot;
@@ -1038,7 +1048,7 @@ multiclass AI_exta_rrot<bits<8> opcod, string opc, PatFrag opnode> {
   }
   def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
                                              rot_imm:$rot),
-                  IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
+                  IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, $rot",
                   [(set GPR:$Rd, (opnode GPR:$Rn,
                                           (rotr GPR:$Rm, rot_imm:$rot)))]>,
                   Requires<[IsARM, HasV6]> {
@@ -1064,7 +1074,7 @@ multiclass AI_exta_rrot_np<bits<8> opcod, string opc> {
   }
   def rr_rot : AExtI<opcod, (outs GPR:$Rd), (ins GPR:$Rn, GPR:$Rm,
                                              rot_imm:$rot),
-                  IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
+                  IIC_iEXTAr, opc, "\t$Rd, $Rn, $Rm, $rot",
                   [/* For disassembly only; pattern left blank */]>,
                   Requires<[IsARM, HasV6]> {
     bits<4> Rn;
@@ -2414,9 +2424,9 @@ defm UXTB16 : AI_ext_rrot<0b01101100,
 //        instead so we can include a check for masking back in the upper
 //        eight bits of the source into the lower eight bits of the result.
 //def : ARMV6Pat<(and (shl GPR:$Src, (i32 8)), 0xFF00FF),
-//               (UXTB16r_rot GPR:$Src, 24)>;
+//               (UXTB16r_rot GPR:$Src, 3)>;
 def : ARMV6Pat<(and (srl GPR:$Src, (i32 8)), 0xFF00FF),
-               (UXTB16r_rot GPR:$Src, 8)>;
+               (UXTB16r_rot GPR:$Src, 1)>;
 
 defm UXTAB : AI_exta_rrot<0b01101110, "uxtab",
                         BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
index 1a9ab1c8763a0a53c3033082202fbb87fb66d405..bc9d878399f4f9ae185134b8ef387e1741f8050a 100644 (file)
@@ -990,7 +990,7 @@ multiclass T2I_ext_rrot<bits<3> opcod, string opc, PatFrag opnode> {
      let Inst{5-4} = 0b00; // rotate
    }
   def r_rot : T2TwoReg<(outs rGPR:$Rd), (ins rGPR:$Rm, rot_imm:$rot), IIC_iEXTr,
-                  opc, ".w\t$Rd, $Rm, ror $rot",
+                  opc, ".w\t$Rd, $Rm, $rot",
                  [(set rGPR:$Rd, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]> {
      let Inst{31-27} = 0b11111;
      let Inst{26-23} = 0b0100;
@@ -1019,7 +1019,7 @@ multiclass T2I_ext_rrot_uxtb16<bits<3> opcod, string opc, PatFrag opnode> {
      let Inst{5-4} = 0b00; // rotate
    }
   def r_rot : T2TwoReg<(outs rGPR:$dst), (ins rGPR:$Rm, rot_imm:$rot),
-                  IIC_iEXTr, opc, "\t$dst, $Rm, ror $rot",
+                  IIC_iEXTr, opc, "\t$dst, $Rm, $rot",
                  [(set rGPR:$dst, (opnode (rotr rGPR:$Rm, rot_imm:$rot)))]>,
                  Requires<[HasT2ExtractPack, IsThumb2]> {
      let Inst{31-27} = 0b11111;
@@ -1079,7 +1079,7 @@ multiclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> {
    }
   def rr_rot : T2ThreeReg<(outs rGPR:$Rd),
                   (ins rGPR:$Rn, rGPR:$Rm, rot_imm:$rot),
-                  IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot",
+                  IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, $rot",
                   [(set rGPR:$Rd, (opnode rGPR:$Rn,
                                           (rotr rGPR:$Rm, rot_imm:$rot)))]>,
                   Requires<[HasT2ExtractPack, IsThumb2]> {
@@ -1094,9 +1094,7 @@ multiclass T2I_exta_rrot<bits<3> opcod, string opc, PatFrag opnode> {
    }
 }
 
-// DO variant - disassembly only, no pattern
-
-multiclass T2I_exta_rrot_DO<bits<3> opcod, string opc> {
+multiclass T2I_exta_rrot_np<bits<3> opcod, string opc> {
   def rr     : T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm), IIC_iEXTAr,
                   opc, "\t$Rd, $Rn, $Rm", []> {
      let Inst{31-27} = 0b11111;
@@ -1106,8 +1104,8 @@ multiclass T2I_exta_rrot_DO<bits<3> opcod, string opc> {
      let Inst{7} = 1;
      let Inst{5-4} = 0b00; // rotate
    }
-  def rr_rot :T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm, i32imm:$rot),
-                  IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, ror $rot", []> {
+  def rr_rot :T2ThreeReg<(outs rGPR:$Rd), (ins rGPR:$Rn, rGPR:$Rm,rot_imm:$rot),
+                  IIC_iEXTAsr, opc, "\t$Rd, $Rn, $Rm, $rot", []> {
      let Inst{31-27} = 0b11111;
      let Inst{26-23} = 0b0100;
      let Inst{22-20} = opcod;
@@ -1681,7 +1679,7 @@ defm t2SXTAB : T2I_exta_rrot<0b100, "sxtab",
                         BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS, i8))>>;
 defm t2SXTAH : T2I_exta_rrot<0b000, "sxtah",
                         BinOpFrag<(add node:$LHS, (sext_inreg node:$RHS,i16))>>;
-defm t2SXTAB16 : T2I_exta_rrot_DO<0b010, "sxtab16">;
+defm t2SXTAB16 : T2I_exta_rrot_np<0b010, "sxtab16">;
 
 // TODO: SXT(A){B|H}16 - done for disassembly only
 
@@ -1700,17 +1698,17 @@ defm t2UXTB16 : T2I_ext_rrot_uxtb16<0b011, "uxtb16",
 //        instead so we can include a check for masking back in the upper
 //        eight bits of the source into the lower eight bits of the result.
 //def : T2Pat<(and (shl rGPR:$Src, (i32 8)), 0xFF00FF),
-//            (t2UXTB16r_rot rGPR:$Src, 24)>,
+//            (t2UXTB16r_rot rGPR:$Src, 3)>,
 //          Requires<[HasT2ExtractPack, IsThumb2]>;
 def : T2Pat<(and (srl rGPR:$Src, (i32 8)), 0xFF00FF),
-            (t2UXTB16r_rot rGPR:$Src, 8)>,
+            (t2UXTB16r_rot rGPR:$Src, 1)>,
         Requires<[HasT2ExtractPack, IsThumb2]>;
 
 defm t2UXTAB : T2I_exta_rrot<0b101, "uxtab",
                            BinOpFrag<(add node:$LHS, (and node:$RHS, 0x00FF))>>;
 defm t2UXTAH : T2I_exta_rrot<0b001, "uxtah",
                            BinOpFrag<(add node:$LHS, (and node:$RHS, 0xFFFF))>>;
-defm t2UXTAB16 : T2I_exta_rrot_DO<0b011, "uxtab16">;
+defm t2UXTAB16 : T2I_exta_rrot_np<0b011, "uxtab16">;
 }
 
 //===----------------------------------------------------------------------===//
index 07d9f8ebc77695581395081553b5cbd9fd01c130..f16870054e142afa4eb0b994c6f15c5ac269b238 100644 (file)
@@ -1785,8 +1785,7 @@ static bool DisassembleExtFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
       && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
     // Extract the 2-bit rotate field Inst{11-10}.
     unsigned rot = (insn >> ARMII::ExtRotImmShift) & 3;
-    // Rotation by 8, 16, or 24 bits.
-    MI.addOperand(MCOperand::CreateImm(rot << 3));
+    MI.addOperand(MCOperand::CreateImm(rot));
     ++OpIdx;
   }
 
index 694ffe6e99199ceff354b72d7a797cef8cf934ff..e534e21375aea442f2c37a6c6cbbb32ea7c40dd5 100644 (file)
@@ -323,12 +323,6 @@ static inline int decodeImm32_BLX(uint32_t insn) {
   return SignExtend32<25>(Imm25);
 }
 
-// See, for example, A8.6.221 SXTAB16.
-static inline unsigned decodeRotate(uint32_t insn) {
-  unsigned rotate = slice(insn, 5, 4);
-  return rotate << 3;
-}
-
 ///////////////////////////////////////////////
 //                                           //
 // Thumb1 instruction disassembly functions. //
@@ -2195,7 +2189,7 @@ static bool DisassembleThumb2DPReg(MCInst &MI, unsigned Opcode, uint32_t insn,
   if (OpIdx < NumOps && OpInfo[OpIdx].RegClass < 0
       && !OpInfo[OpIdx].isPredicate() && !OpInfo[OpIdx].isOptionalDef()) {
     // Add the rotation amount immediate.
-    MI.addOperand(MCOperand::CreateImm(decodeRotate(insn)));
+    MI.addOperand(MCOperand::CreateImm(slice(insn, 5, 4)));
     ++OpIdx;
   }
 
index 3e58631c6ceebb53f1129a5d2ac58c1bb6baf894..30ec4981b7412483db7afebfa63cbb675c83bf16 100644 (file)
@@ -835,3 +835,17 @@ void ARMInstPrinter::printImmPlusOneOperand(const MCInst *MI, unsigned OpNum,
   unsigned Imm = MI->getOperand(OpNum).getImm();
   O << "#" << Imm + 1;
 }
+
+void ARMInstPrinter::printRotImmOperand(const MCInst *MI, unsigned OpNum,
+                                        raw_ostream &O) {
+  unsigned Imm = MI->getOperand(OpNum).getImm();
+  if (Imm == 0)
+    return;
+  O << "ror #";
+  switch (Imm) {
+  default: assert (0 && "illegal ror immediate!");
+  case 1: O << "8\n"; break;
+  case 2: O << "16\n"; break;
+  case 3: O << "24\n"; break;
+  }
+}
index c254ace6bc61a45fbd33bfd709adcfe19008e5ab..8b5ccad1818a397dc53b8f304be11c7690d912fb 100644 (file)
@@ -115,6 +115,7 @@ public:
   void printVFPf64ImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printNEONModImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
   void printImmPlusOneOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
+  void printRotImmOperand(const MCInst *MI, unsigned OpNum, raw_ostream &O);
 
   void printPCLabel(const MCInst *MI, unsigned OpNum, raw_ostream &O);
 };
index 57439df15305f1764e2bdcee9fd8796c42f74a2d..9482a6db1aef65be6be9d04dba34b55d79be4a71 100644 (file)
@@ -259,17 +259,6 @@ public:
   unsigned getT2SORegOpValue(const MCInst &MI, unsigned Op,
                              SmallVectorImpl<MCFixup> &Fixups) const;
 
-  unsigned getRotImmOpValue(const MCInst &MI, unsigned Op,
-                            SmallVectorImpl<MCFixup> &Fixups) const {
-    switch (MI.getOperand(Op).getImm()) {
-    default: assert (0 && "Not a valid rot_imm value!");
-    case 0:  return 0;
-    case 8:  return 1;
-    case 16: return 2;
-    case 24: return 3;
-    }
-  }
-
   unsigned getImmMinusOneOpValue(const MCInst &MI, unsigned Op,
                                  SmallVectorImpl<MCFixup> &Fixups) const {
     return MI.getOperand(Op).getImm() - 1;