Thumb2 assembly parsing and encoding for LDR(register).
authorJim Grosbach <grosbach@apple.com>
Wed, 7 Sep 2011 23:10:15 +0000 (23:10 +0000)
committerJim Grosbach <grosbach@apple.com>
Wed, 7 Sep 2011 23:10:15 +0000 (23:10 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139264 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMInstrThumb2.td
lib/Target/ARM/AsmParser/ARMAsmParser.cpp
test/MC/ARM/basic-thumb2-instructions.s

index e2b16d853476adbc8ac6ae32b05e8bf249fe6c73..bb9debd7696449c85e92cd27891bd7a805f86836 100644 (file)
@@ -167,11 +167,13 @@ def t2am_imm8s4_offset : Operand<i32> {
 }
 
 // t2addrmode_so_reg  := reg + (reg << imm2)
+def t2addrmode_so_reg_asmoperand : AsmOperandClass {let Name="T2MemRegOffset";}
 def t2addrmode_so_reg : Operand<i32>,
                         ComplexPattern<i32, 3, "SelectT2AddrModeSoReg", []> {
   let PrintMethod = "printT2AddrModeSoRegOperand";
   let EncoderMethod = "getT2AddrModeSORegOpValue";
   let DecoderMethod = "DecodeT2AddrModeSOReg";
+  let ParserMatchClass = t2addrmode_so_reg_asmoperand;
   let MIOperandInfo = (ops GPR:$base, rGPR:$offsreg, i32imm:$offsimm);
 }
 
@@ -3709,3 +3711,9 @@ def : t2InstAlias<"ldrb${p} $Rt, $addr",
                   (t2LDRBi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>;
 def : t2InstAlias<"ldrh${p} $Rt, $addr",
                   (t2LDRHi12 rGPR:$Rt, t2addrmode_imm12:$addr, pred:$p)>;
+def : t2InstAlias<"ldr${p} $Rt, $addr",
+                  (t2LDRs GPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>;
+def : t2InstAlias<"ldrb${p} $Rt, $addr",
+                  (t2LDRBs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>;
+def : t2InstAlias<"ldrh${p} $Rt, $addr",
+                  (t2LDRHs rGPR:$Rt, t2addrmode_so_reg:$addr, pred:$p)>;
index 9efdd421f0ca6718bd3e632eba72d88c39713760..6df2d56ff2cf2010cc379d69bb972f04319903af 100644 (file)
@@ -680,6 +680,16 @@ public:
       return false;
     return true;
   }
+  bool isT2MemRegOffset() const {
+    if (Kind != Memory || !Mem.OffsetRegNum || Mem.isNegative)
+      return false;
+    // Only lsl #{0, 1, 2, 3} allowed.
+    if (Mem.ShiftType == ARM_AM::no_shift)
+      return true;
+    if (Mem.ShiftType != ARM_AM::lsl || Mem.ShiftImm > 3)
+      return false;
+    return true;
+  }
   bool isMemThumbRR() const {
     // Thumb reg+reg addressing is simple. Just two registers, a base and
     // an offset. No shifts, negations or any other complicating factors.
@@ -844,7 +854,6 @@ public:
       ARM_AM::getSORegOpc(RegShiftedImm.ShiftTy, RegShiftedImm.ShiftImm)));
   }
 
-
   void addShifterImmOperands(MCInst &Inst, unsigned N) const {
     assert(N == 1 && "Invalid number of operands!");
     Inst.addOperand(MCOperand::CreateImm((ShifterImm.isASR << 5) |
@@ -1145,6 +1154,13 @@ public:
     Inst.addOperand(MCOperand::CreateImm(Val));
   }
 
+  void addT2MemRegOffsetOperands(MCInst &Inst, unsigned N) const {
+    assert(N == 3 && "Invalid number of operands!");
+    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
+    Inst.addOperand(MCOperand::CreateReg(Mem.OffsetRegNum));
+    Inst.addOperand(MCOperand::CreateImm(Mem.ShiftImm));
+  }
+
   void addMemThumbRROperands(MCInst &Inst, unsigned N) const {
     assert(N == 2 && "Invalid number of operands!");
     Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
index d23b565540e4f660356035bdc25667167f13f331..25141dbcb2e8861c6f8e82451491edccb075c619 100644 (file)
@@ -539,6 +539,24 @@ _func:
             @   fixup A - offset: 0, value: _foo, kind: fixup_t2_ldst_pcrel_12
 
 
+@------------------------------------------------------------------------------
+@ LDR(register)
+@------------------------------------------------------------------------------
+        ldr r1, [r8, r1]
+        ldr.w r4, [r5, r2]
+        ldr r6, [r0, r2, lsl #3]
+        ldr r8, [r8, r2, lsl #2]
+        ldr r7, [sp, r2, lsl #1]
+        ldr r7, [sp, r2, lsl #0]
+
+@ CHECK: ldr.w r1, [r8, r1]            @ encoding: [0x58,0xf8,0x01,0x10]
+@ CHECK: ldr.w r4, [r5, r2]            @ encoding: [0x55,0xf8,0x02,0x40]
+@ CHECK: ldr.w r6, [r0, r2, lsl #3]    @ encoding: [0x50,0xf8,0x32,0x60]
+@ CHECK: ldr.w r8, [r8, r2, lsl #2]    @ encoding: [0x58,0xf8,0x22,0x80]
+@ CHECK: ldr.w r7, [sp, r2, lsl #1]    @ encoding: [0x5d,0xf8,0x12,0x70]
+@ CHECK: ldr.w r7, [sp, r2]            @ encoding: [0x5d,0xf8,0x02,0x70]
+
+
 @------------------------------------------------------------------------------
 @ LDRB(immediate)
 @------------------------------------------------------------------------------