Rename getAddrModeImm12OpValue to getAddrModeImmOpValue and expand it to work
authorBill Wendling <isanbard@gmail.com>
Tue, 2 Nov 2010 22:31:46 +0000 (22:31 +0000)
committerBill Wendling <isanbard@gmail.com>
Tue, 2 Nov 2010 22:31:46 +0000 (22:31 +0000)
with immediates up to 16-bits in size. The same logic is applied to other LDR
encodings, e.g. VLDR, but which use a different immediate bit width (8-bits in
VLDR's case). Removing the "12" allows it to be more generic.

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

lib/Target/ARM/ARMCodeEmitter.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMInstrVFP.td
lib/Target/ARM/ARMMCCodeEmitter.cpp
test/MC/ARM/arm_instructions.s
test/MC/ARM/simple-fp-encoding.s

index 0ef65bb23ce213eb93e683385ee225a236d70972..0584dec51466e5661468ca75ceed70d0e6363bf4 100644 (file)
@@ -177,26 +177,27 @@ namespace {
       const { return 0; }
     unsigned getBitfieldInvertedMaskOpValue(const MachineInstr &MI,
                                             unsigned Op) const { return 0; }
-    unsigned getAddrModeImm12OpValue(const MachineInstr &MI, unsigned Op)
-      const {
-        // {17-13} = reg
-        // {12}    = (U)nsigned (add == '1', sub == '0')
-        // {11-0}  = imm12
-        const MachineOperand &MO  = MI.getOperand(Op);
-        const MachineOperand &MO1 = MI.getOperand(Op + 1);
-        if (!MO.isReg()) {
-          emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_cp_entry);
-          return 0;
-        }
-        unsigned Reg = getARMRegisterNumbering(MO.getReg());
-        int32_t Imm12 = MO1.getImm();
-        uint32_t Binary;
-        Binary = Imm12 & 0xfff;
-        if (Imm12 >= 0)
-          Binary |= (1 << 12);
-        Binary |= (Reg << 13);
-        return Binary;
+    uint32_t getAddrModeImmOpValue(const MachineInstr &MI, unsigned Op) const {
+      // {20-17} = reg
+      // {16}    = (U)nsigned (add == '1', sub == '0')
+      // {15-0}  = imm
+      const MachineOperand &MO  = MI.getOperand(Op);
+      const MachineOperand &MO1 = MI.getOperand(Op + 1);
+      if (!MO.isReg()) {
+        emitConstPoolAddress(MO.getIndex(), ARM::reloc_arm_cp_entry);
+        return 0;
       }
+
+      unsigned Reg = getARMRegisterNumbering(MO.getReg());
+      int32_t Imm = MO1.getImm();
+      uint32_t Binary;
+      Binary = Imm & 0xffff;
+      if (Imm >= 0)
+        Binary |= (1 << 16);
+
+      Binary |= (Reg << 17);
+      return Binary;
+    }
     unsigned getNEONVcvtImm32OpValue(const MachineInstr &MI, unsigned Op)
       const { return 0; }
 
index 3c1da1efb6523646d0dfc4ad5f5031ebf0c691fe..95ab0f1d8d6c5b669265a5522465bebf244caf48 100644 (file)
@@ -398,7 +398,7 @@ def addrmode_imm12 : Operand<i32>,
   // #0 and #-0 differently. We flag #-0 as the magic value INT32_MIN. All other
   // immediate values are as normal.
 
-  string EncoderMethod = "getAddrModeImm12OpValue";
+  string EncoderMethod = "getAddrModeImmOpValue";
   let PrintMethod = "printAddrModeImm12Operand";
   let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
 }
@@ -464,6 +464,7 @@ def addrmode5 : Operand<i32>,
   let PrintMethod = "printAddrMode5Operand";
   let MIOperandInfo = (ops GPR:$base, i32imm);
   let ParserMatchClass = ARMMemMode5AsmOperand;
+  string EncoderMethod = "getAddrModeImmOpValue";
 }
 
 // addrmode6 := reg with optional writeback
@@ -830,9 +831,9 @@ multiclass AI_ldr1<bit opc22, string opc, InstrItinClass iii,
                    AddrMode_i12, LdFrm, iii, opc, "\t$Rt, $addr",
                   [(set GPR:$Rt, (opnode addrmode_imm12:$addr))]> {
     bits<4> Rt;
-    bits<17> addr;
-    let Inst{23}    = addr{12};     // U (add = ('U' == 1))
-    let Inst{19-16} = addr{16-13};  // Rn
+    bits<32> addr;
+    let Inst{23}    = addr{16};     // U (add = ('U' == 1))
+    let Inst{19-16} = addr{20-17};  // Rn
     let Inst{15-12} = Rt;
     let Inst{11-0}  = addr{11-0};   // imm12
   }
@@ -840,9 +841,9 @@ multiclass AI_ldr1<bit opc22, string opc, InstrItinClass iii,
                   AddrModeNone, LdFrm, iir, opc, "\t$Rt, $shift",
                  [(set GPR:$Rt, (opnode ldst_so_reg:$shift))]> {
     bits<4> Rt;
-    bits<17> shift;
-    let Inst{23}    = shift{12};    // U (add = ('U' == 1))
-    let Inst{19-16} = shift{16-13}; // Rn
+    bits<32> shift;
+    let Inst{23}    = shift{16};    // U (add = ('U' == 1))
+    let Inst{19-16} = shift{20-17}; // Rn
     let Inst{11-0}  = shift{11-0};
   }
 }
index fd0e84b1178a24a1d13837cf1b44ef4acd90dae1..337028d88df9e9d20d970a7688ca4ef2ca74d698 100644 (file)
@@ -53,18 +53,29 @@ def vfp_f64imm : Operand<f64>,
 let canFoldAsLoad = 1, isReMaterializable = 1 in {
 def VLDRD : ADI5<0b1101, 0b01, (outs DPR:$Dd), (ins addrmode5:$addr),
                  IIC_fpLoad64, "vldr", ".64\t$Dd, $addr",
-                 [(set DPR:$Dd, (f64 (load addrmode5:$addr)))]>;
+                 [(set DPR:$Dd, (f64 (load addrmode5:$addr)))]> {
+  // Instruction operands.
+  bits<5> Dd;
+  bits<32> addr;
+
+  // Encode instruction operands.
+  let Inst{23}    = addr{16};     // U (add = (U == '1'))
+  let Inst{22}    = Dd{4};
+  let Inst{19-16} = addr{20-17};  // Rn
+  let Inst{15-12} = Dd{3-0};
+  let Inst{7-0}   = addr{7-0};    // imm8
+}
 
 def VLDRS : ASI5<0b1101, 0b01, (outs SPR:$dst), (ins addrmode5:$addr),
                  IIC_fpLoad32, "vldr", ".32\t$dst, $addr",
                  [(set SPR:$dst, (load addrmode5:$addr))]>;
 } // canFoldAsLoad
 
-def VSTRD  : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr),
+def VSTRD : ADI5<0b1101, 0b00, (outs), (ins DPR:$src, addrmode5:$addr),
                  IIC_fpStore64, "vstr", ".64\t$src, $addr",
                  [(store (f64 DPR:$src), addrmode5:$addr)]>;
 
-def VSTRS  : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr),
+def VSTRS : ASI5<0b1101, 0b00, (outs), (ins SPR:$src, addrmode5:$addr),
                  IIC_fpStore32, "vstr", ".32\t$src, $addr",
                  [(store SPR:$src, addrmode5:$addr)]>;
 
index 6935974455af673c6b0c9138cc5029be85ffa517..bc16fe04c389876b0931257430f13b7ab19184ea 100644 (file)
@@ -49,9 +49,8 @@ public:
   /// operand requires relocation, record the relocation and return zero.
   unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO) const;
 
-  /// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
-  /// operand.
-  unsigned getAddrModeImm12OpValue(const MCInst &MI, unsigned Op) const;
+  /// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand.
+  uint32_t getAddrModeImmOpValue(const MCInst &MI, unsigned Op) const;
 
   /// getCCOutOpValue - Return encoding of the 's' bit.
   unsigned getCCOutOpValue(const MCInst &MI, unsigned Op) const {
@@ -170,37 +169,38 @@ unsigned ARMMCCodeEmitter::getMachineOpValue(const MCInst &MI,
   return 0;
 }
 
-/// getAddrModeImm12OpValue - Return encoding info for 'reg +/- imm12'
-/// operand.
-unsigned ARMMCCodeEmitter::getAddrModeImm12OpValue(const MCInst &MI,
-                                                   unsigned OpIdx) const {
-  // {17-13} = reg
-  // {12}    = (U)nsigned (add == '1', sub == '0')
-  // {11-0}  = imm12
+/// getAddrModeImmOpValue - Return encoding info for 'reg +/- imm' operand.
+uint32_t ARMMCCodeEmitter::getAddrModeImmOpValue(const MCInst &MI,
+                                                 unsigned OpIdx) const {
+  // {20-17} = reg
+  // {16}    = (U)nsigned (add == '1', sub == '0')
+  // {15-0}  = imm
   const MCOperand &MO  = MI.getOperand(OpIdx);
   const MCOperand &MO1 = MI.getOperand(OpIdx + 1);
   uint32_t Binary = 0;
 
   // If The first operand isn't a register, we have a label reference.
   if (!MO.isReg()) {
-    Binary |= ARM::PC << 13;     // Rn is PC.
+    Binary |= ARM::PC << 17;     // Rn is PC.
     // FIXME: Add a fixup referencing the label.
     return Binary;
   }
 
   unsigned Reg = getARMRegisterNumbering(MO.getReg());
-  int32_t Imm12 = MO1.getImm();
-  bool isAdd = Imm12 >= 0;
+  int32_t Imm = MO1.getImm();
+  bool isAdd = Imm >= 0;
+
   // Special value for #-0
-  if (Imm12 == INT32_MIN)
-    Imm12 = 0;
+  if (Imm == INT32_MIN)
+    Imm = 0;
+
   // Immediate is always encoded as positive. The 'U' bit controls add vs sub.
-  if (Imm12 < 0)
-    Imm12 = -Imm12;
-  Binary = Imm12 & 0xfff;
+  if (Imm < 0) Imm = -Imm;
+
+  Binary = Imm & 0xffff;
   if (isAdd)
-    Binary |= (1 << 12);
-  Binary |= (Reg << 13);
+    Binary |= (1 << 16);
+  Binary |= (Reg << 17);
   return Binary;
 }
 
@@ -320,7 +320,6 @@ unsigned ARMMCCodeEmitter::getAddrMode6OffsetOpValue(const MCInst &MI,
   return regno.getReg();
 }
 
-
 void ARMMCCodeEmitter::
 EncodeInstruction(const MCInst &MI, raw_ostream &OS,
                   SmallVectorImpl<MCFixup> &Fixups) const {
index b82b36a04399c75d8490798b27037eb14bada893..36636341e1ea1322ec25be544cf71bffa866bc3f 100644 (file)
 
 @ CHECK: bx    lr
 @ CHECK: encoding: [0x1e,0xff,0x2f,0xe1]
-bx lr
+        bx lr
 
 @ CHECK: vqdmull.s32   q8, d17, d16
 @ CHECK: encoding: [0xa0,0x0d,0xe1,0xf2]
-vqdmull.s32     q8, d17, d16
-
-@ CHECK: vldr.64       d17, [r0]
-@ CHECK: encoding: [0x00,0x0b,0x10,0xed]
-vldr.64        d17, [r0]
-
+        vqdmull.s32     q8, d17, d16
index 614a497d53a3eeff005e2775f22185adb4bd5299..cd1ccac0f0a3d465846da0b1f10c07498cc71f76 100644 (file)
 
 @ CHECK: vmov r0, r1, d16            @ encoding: [0x30,0x0b,0x51,0xec]
         vmov    r0, r1, d16
+
+@ CHECK: vldr.64 d17, [r0]           @ encoding: [0x00,0x1b,0xd0,0xed]
+        vldr.64        d17, [r0]
+
+@ CHECK: vldr.64 d1, [r2, #32]       @ encoding: [0x08,0x1b,0x92,0xed]
+        vldr.64        d1, [r2, #32]
+
+        
+@ CHECK: vldr.64 d2, [r3]            @ encoding: [0x00,0x2b,0x93,0xed]
+        vldr.64 d2, [r3]
+
+@ CHECK: vldr.64 d3, [pc]            @ encoding: [0x00,0x3b,0x9f,0xed]
+@ CHECK: vldr.64 d3, [pc]            @ encoding: [0x00,0x3b,0x9f,0xed]
+@ CHECK: vldr.64 d3, [pc]            @ encoding: [0x00,0x3b,0x9f,0xed]
+        vldr.64 d3, [pc]
+        vldr.64 d3, [pc,#0]
+        vldr.64 d3, [pc,#-0]