diff options
author | Owen Anderson <resistor@mac.com> | 2011-08-18 22:31:17 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2011-08-18 22:31:17 +0000 |
commit | 846dd95f87f62e2faa6092f99b521ecd9790121a (patch) | |
tree | 5d96522551b398dc1c310fa1a7b5bd25d1105344 | |
parent | 49e2f03849064d9dc26db3865ae419f17daadca6 (diff) |
Fix the decoding of RFE instruction. RFEs have the load bit set, while SRSs have it unset.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138000 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 50 | ||||
-rw-r--r-- | test/MC/Disassembler/ARM/arm-tests.txt | 3 |
2 files changed, 45 insertions, 8 deletions
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index c5464ceb36..40a7936cfe 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -1274,31 +1274,65 @@ static DecodeStatus DecodeMemMultipleWritebackInstruction(llvm::MCInst &Inst, if (pred == 0xF) { switch (Inst.getOpcode()) { - case ARM::STMDA: + case ARM::LDMDA: Inst.setOpcode(ARM::RFEDA); break; - case ARM::STMDA_UPD: + case ARM::LDMDA_UPD: Inst.setOpcode(ARM::RFEDA_UPD); break; - case ARM::STMDB: + case ARM::LDMDB: Inst.setOpcode(ARM::RFEDB); break; - case ARM::STMDB_UPD: + case ARM::LDMDB_UPD: Inst.setOpcode(ARM::RFEDB_UPD); break; - case ARM::STMIA: + case ARM::LDMIA: Inst.setOpcode(ARM::RFEIA); break; - case ARM::STMIA_UPD: + case ARM::LDMIA_UPD: Inst.setOpcode(ARM::RFEIA_UPD); break; - case ARM::STMIB: + case ARM::LDMIB: Inst.setOpcode(ARM::RFEIB); break; - case ARM::STMIB_UPD: + case ARM::LDMIB_UPD: Inst.setOpcode(ARM::RFEIB_UPD); break; + case ARM::STMDA: + Inst.setOpcode(ARM::SRSDA); + break; + case ARM::STMDA_UPD: + Inst.setOpcode(ARM::SRSDA_UPD); + break; + case ARM::STMDB: + Inst.setOpcode(ARM::SRSDB); + break; + case ARM::STMDB_UPD: + Inst.setOpcode(ARM::SRSDB_UPD); + break; + case ARM::STMIA: + Inst.setOpcode(ARM::SRSIA); + break; + case ARM::STMIA_UPD: + Inst.setOpcode(ARM::SRSIA_UPD); + break; + case ARM::STMIB: + Inst.setOpcode(ARM::SRSIB); + break; + case ARM::STMIB_UPD: + Inst.setOpcode(ARM::SRSIB_UPD); + break; + default: + CHECK(S, Fail); } + + // For stores (which become SRS's, the only operand is the mode. + if (fieldFromInstruction32(Insn, 20, 1) == 0) { + Inst.addOperand( + MCOperand::CreateImm(fieldFromInstruction32(Insn, 0, 4))); + return S; + } + return DecodeRFEInstruction(Inst, Insn, Address, Decoder); } diff --git a/test/MC/Disassembler/ARM/arm-tests.txt b/test/MC/Disassembler/ARM/arm-tests.txt index 349ad10155..cf25875937 100644 --- a/test/MC/Disassembler/ARM/arm-tests.txt +++ b/test/MC/Disassembler/ARM/arm-tests.txt @@ -311,3 +311,6 @@ # CHECK: strheq r0, [r0, -r0] 0xb0 0x00 0x00 0x01 + +# CHECK: rfedb #4! +0x14 0x0 0x32 0xf9 |