aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohnny Chen <johnny.chen@apple.com>2011-03-15 01:13:17 +0000
committerJohnny Chen <johnny.chen@apple.com>2011-03-15 01:13:17 +0000
commit085ea1b6337ff524edcff3368ee15b5acf9f5e53 (patch)
treef4f72d23e1228cdc02578ee4ff6c4978a307918e
parent28cc1aa3a748068b6490a19fc4af2443bc7f3dbd (diff)
Fixed an ARM disassembler bug where it does not handle STRi12 correctly because an extra
register operand was erroneously added. Remove an incorrect assert which triggers the bug. rdar://problem/9131529 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@127642 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp15
-rw-r--r--test/MC/Disassembler/ARM/arm-tests.txt12
2 files changed, 21 insertions, 6 deletions
diff --git a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
index 32c41fc479..0211581015 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
+++ b/lib/Target/ARM/Disassembler/ARMDisassemblerCore.cpp
@@ -1079,18 +1079,21 @@ static bool DisassembleLdStFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
if (OpIdx + 1 >= NumOps)
return false;
- assert((OpInfo[OpIdx].RegClass == ARM::GPRRegClassID) &&
- (OpInfo[OpIdx+1].RegClass < 0) &&
- "Expect 1 reg operand followed by 1 imm operand");
-
ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
if (getIBit(insn) == 0) {
- MI.addOperand(MCOperand::CreateReg(0));
+ // For pre- and post-indexed case, add a reg0 operand (Addressing Mode #2).
+ // Otherwise, skip the reg operand since for addrmode_imm12, Rn has already
+ // been populated.
+ if (isPrePost) {
+ MI.addOperand(MCOperand::CreateReg(0));
+ OpIdx += 1;
+ }
// Disassemble the 12-bit immediate offset.
unsigned Imm12 = slice(insn, 11, 0);
unsigned Offset = ARM_AM::getAM2Opc(AddrOpcode, Imm12, ARM_AM::no_shift);
MI.addOperand(MCOperand::CreateImm(Offset));
+ OpIdx += 1;
} else {
// Disassemble the offset reg (Rm), shift type, and immediate shift length.
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
@@ -1104,8 +1107,8 @@ static bool DisassembleLdStFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
getImmShiftSE(ShOp, ShImm);
MI.addOperand(MCOperand::CreateImm(
ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp)));
+ OpIdx += 2;
}
- OpIdx += 2;
return true;
}
diff --git a/test/MC/Disassembler/ARM/arm-tests.txt b/test/MC/Disassembler/ARM/arm-tests.txt
index 5d80474541..22a73f2cda 100644
--- a/test/MC/Disassembler/ARM/arm-tests.txt
+++ b/test/MC/Disassembler/ARM/arm-tests.txt
@@ -142,3 +142,15 @@
# CHECK: uqadd16mi r6, r11, r8
0x18 0x60 0x6b 0x46
+
+# CHECK: str r0, [sp, #4]
+0x04 0x00 0x8d 0xe5
+
+# CHECK: str r1, [sp]
+0x00 0x10 0x8d 0xe5
+
+# CHECK: ldr r3, [pc, #144]
+0x90 0x30 0x9f 0xe5
+
+# CHECK: strdeq r2, r3, [r0], -r8
+0xf8 0x24 0x00 0x00