It used to be that t_addrmode_s4 was used for both:
authorJohnny Chen <johnny.chen@apple.com>
Thu, 17 Mar 2011 22:04:05 +0000 (22:04 +0000)
committerJohnny Chen <johnny.chen@apple.com>
Thu, 17 Mar 2011 22:04:05 +0000 (22:04 +0000)
o A8.6.195 STR (register) -- Encoding T1
o A8.6.193 STR (immediate, Thumb) -- Encoding T1

It has been changed so that now they use different addressing modes
and thus different MC representation (Operand Infos).  Modify the
disassembler to reflect the change, and add relevant tests.

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

lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
test/MC/Disassembler/ARM/thumb-tests.txt

index 33889da77d6c5304a66550c66c3996c946fbc7ee..fcfe1de17a4ee4aea9e7f0bc3b7ffd3de8ddbd03 100644 (file)
@@ -598,7 +598,7 @@ static bool DisassembleThumb2Ldpci(MCInst &MI, unsigned Opcode,
 
 // A6.2.4 Load/store single data item
 //
-// Load/Store Register (reg|imm):      tRd tRn imm5 tRm
+// Load/Store Register (reg|imm):      tRd tRn imm5|tRm
 // Load Register Signed Byte|Halfword: tRd tRn tRm
 static bool DisassembleThumb1LdSt(unsigned opA, MCInst &MI, unsigned Opcode,
     uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
@@ -624,28 +624,25 @@ static bool DisassembleThumb1LdSt(unsigned opA, MCInst &MI, unsigned Opcode,
                                                      getT1tRn(insn))));
   OpIdx = 2;
 
-  // We have either { imm5, tRm } or { tRm } remaining.
-  // Process the imm5 first.  Note that STR/LDR (register) should skip the imm5
-  // offset operand for t_addrmode_s[1|2|4].
+  // We have either { imm5 } or { tRm } remaining.
+  // Note that STR/LDR (register) should skip the imm5 offset operand for
+  // t_addrmode_s[1|2|4].
 
   assert(OpIdx < NumOps && "More operands expected");
 
   if (OpInfo[OpIdx].RegClass < 0 && !OpInfo[OpIdx].isPredicate() &&
       !OpInfo[OpIdx].isOptionalDef()) {
-
-    MI.addOperand(MCOperand::CreateImm(Imm5 ? getT1Imm5(insn) : 0));
+    assert(Imm5 && "Immediate operand expected for this opcode");
+    MI.addOperand(MCOperand::CreateImm(getT1Imm5(insn)));
+    ++OpIdx;
+  } else {
+    // The next reg operand is tRm, the offset.
+    assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
+           && "Thumb reg operand expected");
+    MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
+                                                       getT1tRm(insn))));
     ++OpIdx;
   }
-
-  // The next reg operand is tRm, the offset.
-  assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
-         && "Thumb reg operand expected");
-  MI.addOperand(MCOperand::CreateReg(
-                  Imm5 ? 0
-                       : getRegisterEnum(B, ARM::tGPRRegClassID,
-                                         getT1tRm(insn))));
-  ++OpIdx;
-
   return true;
 }
 
index 36f74381a5e66fe98e2c392ce0460ff9b04cf1cf..26a6af8404a3c778085eb447e29d34afaffc29a8 100644 (file)
 # CHECK:       ldmia   r0!, {r1}
 0x02 0xc8
 
+# CHECK:       str     r0, [r3]
+0x18 0x60
+
+# CHECK:       str     r0, [r3, #4]
+0x58 0x60
+
+# CHECK:       str     r2, [r5, r3]
+0xea 0x50
+
 # CHECK:       ldrb.w  r8, #-24
 0x1f 0xf8 0x18 0x80