From 846dd95f87f62e2faa6092f99b521ecd9790121a Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Thu, 18 Aug 2011 22:31:17 +0000 Subject: [PATCH] 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 --- .../ARM/Disassembler/ARMDisassembler.cpp | 50 ++++++++++++++++--- 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 c5464ceb361..40a7936cfe2 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 349ad101559..cf258759379 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