diff options
author | Amaury de la Vieuville <amaury.dlv@gmail.com> | 2013-06-11 08:03:20 +0000 |
---|---|---|
committer | Amaury de la Vieuville <amaury.dlv@gmail.com> | 2013-06-11 08:03:20 +0000 |
commit | 3862709058ecfe809c9d4b32e3bff0efe8ebe646 (patch) | |
tree | b6f5a061634fb2d37619210168d617f6fb48e46d /lib | |
parent | c139672407b6ad8d2929fd0c52591216fd32b4b6 (diff) | |
download | external_llvm-3862709058ecfe809c9d4b32e3bff0efe8ebe646.zip external_llvm-3862709058ecfe809c9d4b32e3bff0efe8ebe646.tar.gz external_llvm-3862709058ecfe809c9d4b32e3bff0efe8ebe646.tar.bz2 |
ARM: Fix STREX/LDREX reecoding
The decoded MCInst wasn't reencoded as the same instruction
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@183729 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 4d25e15..b1a1230 100644 --- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -165,6 +165,8 @@ static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); static DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); +static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, const void *Decoder); static DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder); static DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo, @@ -854,6 +856,26 @@ static DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo, return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder); } +static const uint16_t GPRPairDecoderTable[] = { + ARM::R0_R1, ARM::R2_R3, ARM::R4_R5, ARM::R6_R7, + ARM::R8_R9, ARM::R10_R11, ARM::R12_SP +}; + +static DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo, + uint64_t Address, const void *Decoder) { + DecodeStatus S = MCDisassembler::Success; + + if (RegNo > 13) + return MCDisassembler::Fail; + + if ((RegNo & 1) || RegNo == 0xe) + S = MCDisassembler::SoftFail; + + unsigned RegisterPair = GPRPairDecoderTable[RegNo/2]; + Inst.addOperand(MCOperand::CreateReg(RegisterPair)); + return S; +} + static DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const void *Decoder) { unsigned Register = 0; @@ -3579,11 +3601,10 @@ static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn, unsigned Rn = fieldFromInstruction(Insn, 16, 4); unsigned pred = fieldFromInstruction(Insn, 28, 4); - if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return MCDisassembler::Fail; + if (Rn == 0xF) + S = MCDisassembler::SoftFail; - if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) - return MCDisassembler::Fail; - if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder))) + if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder))) return MCDisassembler::Fail; if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) return MCDisassembler::Fail; @@ -3593,7 +3614,6 @@ static DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn, return S; } - static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn, uint64_t Address, const void *Decoder){ DecodeStatus S = MCDisassembler::Success; @@ -3606,12 +3626,10 @@ static DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn, if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder))) return MCDisassembler::Fail; - if ((Rt & 1) || Rt == 0xE || Rn == 0xF) return MCDisassembler::Fail; - if (Rd == Rn || Rd == Rt || Rd == Rt+1) return MCDisassembler::Fail; + if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt+1) + S = MCDisassembler::SoftFail; - if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder))) - return MCDisassembler::Fail; - if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder))) + if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder))) return MCDisassembler::Fail; if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder))) return MCDisassembler::Fail; |