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

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

index bb9debd7696449c85e92cd27891bd7a805f86836..2857b2d208e7b2e1e2771040a261b14fba4ddfea 100644 (file)
@@ -123,6 +123,16 @@ def t2adrlabel : Operand<i32> {
 }
 
 
+// t2addrmode_posimm8  := reg + imm8
+def MemPosImm8OffsetAsmOperand : AsmOperandClass {let Name="MemPosImm8Offset";}
+def t2addrmode_posimm8 : Operand<i32> {
+  let PrintMethod = "printT2AddrModeImm8Operand";
+  let EncoderMethod = "getT2AddrModeImm8OpValue";
+  let DecoderMethod = "DecodeT2AddrModeImm8";
+  let ParserMatchClass = MemPosImm8OffsetAsmOperand;
+  let MIOperandInfo = (ops GPR:$base, i32imm:$offsimm);
+}
+
 // t2addrmode_negimm8  := reg - imm8
 def MemNegImm8OffsetAsmOperand : AsmOperandClass {let Name="MemNegImm8Offset";}
 def t2addrmode_negimm8 : Operand<i32>,
@@ -1291,26 +1301,24 @@ def t2LDRSH_POST : T2Iidxldst<1, 0b01, 1, 0, (outs GPR:$Rt, GPR:$Rn),
                             []>;
 } // mayLoad = 1, neverHasSideEffects = 1
 
-// LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110) and are
-// for disassembly only.
+// LDRT, LDRBT, LDRHT, LDRSBT, LDRSHT all have offset mode (PUW=0b110).
 // Ref: A8.6.57 LDR (immediate, Thumb) Encoding T4
 class T2IldT<bit signed, bits<2> type, string opc, InstrItinClass ii>
-  : T2Ii8<(outs rGPR:$Rt), (ins t2addrmode_imm8:$addr), ii, opc,
+  : T2Ii8<(outs rGPR:$Rt), (ins t2addrmode_posimm8:$addr), ii, opc,
           "\t$Rt, $addr", []> {
+  bits<4> Rt;
+  bits<13> addr;
   let Inst{31-27} = 0b11111;
   let Inst{26-25} = 0b00;
   let Inst{24} = signed;
   let Inst{23} = 0;
   let Inst{22-21} = type;
   let Inst{20} = 1; // load
+  let Inst{19-16} = addr{12-9};
+  let Inst{15-12} = Rt;
   let Inst{11} = 1;
   let Inst{10-8} = 0b110; // PUW.
-
-  bits<4> Rt;
-  bits<13> addr;
-  let Inst{15-12} = Rt;
-  let Inst{19-16} = addr{12-9};
-  let Inst{7-0}   = addr{7-0};
+  let Inst{7-0} = addr{7-0};
 }
 
 def t2LDRT   : T2IldT<0, 0b10, "ldrt", IIC_iLoad_i>;
index 6df2d56ff2cf2010cc379d69bb972f04319903af..b66adfc9048e0bc7b04c510167fb56f79b420a57 100644 (file)
@@ -742,6 +742,14 @@ public:
     int64_t Val = Mem.OffsetImm->getValue();
     return Val > -256 && Val < 256;
   }
+  bool isMemPosImm8Offset() const {
+    if (Kind != Memory || Mem.OffsetRegNum != 0)
+      return false;
+    // Immediate offset in range [0, 255].
+    if (!Mem.OffsetImm) return true;
+    int64_t Val = Mem.OffsetImm->getValue();
+    return Val >= 0 && Val < 256;
+  }
   bool isMemNegImm8Offset() const {
     if (Kind != Memory || Mem.OffsetRegNum != 0)
       return false;
@@ -1108,11 +1116,12 @@ public:
     Inst.addOperand(MCOperand::CreateImm(Val));
   }
 
+  void addMemPosImm8OffsetOperands(MCInst &Inst, unsigned N) const {
+    addMemImm8OffsetOperands(Inst, N);
+  }
+
   void addMemNegImm8OffsetOperands(MCInst &Inst, unsigned N) const {
-    assert(N == 2 && "Invalid number of operands!");
-    int64_t Val = Mem.OffsetImm ? Mem.OffsetImm->getValue() : 0;
-    Inst.addOperand(MCOperand::CreateReg(Mem.BaseRegNum));
-    Inst.addOperand(MCOperand::CreateImm(Val));
+    addMemImm8OffsetOperands(Inst, N);
   }
 
   void addMemUImm12OffsetOperands(MCInst &Inst, unsigned N) const {
index 4fc9391f88b44de4d5fa855d67a168d0f557a4ee..1abbd5fa788aa5d9930c0fd9116ab3009eb54c9a 100644 (file)
@@ -591,6 +591,20 @@ _func:
 @ CHECK: ldrb.w        r7, [sp, r2]            @ encoding: [0x1d,0xf8,0x02,0x70]
 
 
+@------------------------------------------------------------------------------
+@ LDRBT
+@------------------------------------------------------------------------------
+        ldrbt r1, [r2]
+        ldrbt r1, [r8, #0]
+        ldrbt r1, [r8, #3]
+        ldrbt r1, [r8, #255]
+
+@ CHECK: ldrbt r1, [r2]                @ encoding: [0x12,0xf8,0x00,0x1e]
+@ CHECK: ldrbt r1, [r8]                @ encoding: [0x18,0xf8,0x00,0x1e]
+@ CHECK: ldrbt r1, [r8, #3]            @ encoding: [0x18,0xf8,0x03,0x1e]
+@ CHECK: ldrbt r1, [r8, #255]          @ encoding: [0x18,0xf8,0xff,0x1e]
+
+
 @------------------------------------------------------------------------------
 @ IT
 @------------------------------------------------------------------------------
index 0a1e4af4180fb867ebab35bc508c9dbabc09b7f7..11de085d9ae0670402d101ef4cc1a264df66be10 100644 (file)
@@ -666,6 +666,7 @@ static int ARMFlagFromOpName(LiteralConstantEmitter *type,
   MISC("spr_reglist", "kOperandTypeARMSPRRegisterList");          // I, R, ...
   MISC("it_mask", "kOperandTypeThumbITMask");                     // I
   MISC("t2addrmode_reg", "kOperandTypeThumb2AddrModeReg");        // R
+  MISC("t2addrmode_posimm8", "kOperandTypeThumb2AddrModeImm8");   // R, I
   MISC("t2addrmode_negimm8", "kOperandTypeThumb2AddrModeImm8");   // R, I
   MISC("t2addrmode_imm8", "kOperandTypeThumb2AddrModeImm8");      // R, I
   MISC("t2am_imm8_offset", "kOperandTypeThumb2AddrModeImm8Offset");//I