From 3862709058ecfe809c9d4b32e3bff0efe8ebe646 Mon Sep 17 00:00:00 2001 From: Amaury de la Vieuville Date: Tue, 11 Jun 2013 08:03:20 +0000 Subject: 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 --- lib/Target/ARM/Disassembler/ARMDisassembler.cpp | 38 ++++++++++++++++------ test/MC/Disassembler/ARM/arm-LDREXD-reencoding.txt | 14 ++++++++ test/MC/Disassembler/ARM/arm-STREXD-reencoding.txt | 14 ++++++++ 3 files changed, 56 insertions(+), 10 deletions(-) create mode 100644 test/MC/Disassembler/ARM/arm-LDREXD-reencoding.txt create mode 100644 test/MC/Disassembler/ARM/arm-STREXD-reencoding.txt diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 4d25e15fcc..b1a12306f5 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; diff --git a/test/MC/Disassembler/ARM/arm-LDREXD-reencoding.txt b/test/MC/Disassembler/ARM/arm-LDREXD-reencoding.txt new file mode 100644 index 0000000000..e73d4ce88e --- /dev/null +++ b/test/MC/Disassembler/ARM/arm-LDREXD-reencoding.txt @@ -0,0 +1,14 @@ +# RUN: llvm-mc -triple armv7 -show-encoding -disassemble < %s | FileCheck %s + +0x9f 0x0f 0xb0 0xe1 +0x9f 0xcf 0xb1 0xe1 +0x9f 0xcf 0xb3 0xe1 +0x9f 0x8f 0xbd 0xe1 +0x9f 0xcf 0xbe 0xe1 + +# CHECK: ldrexd r0, r1, [r0] @ encoding: [0x9f,0x0f,0xb0,0xe1] +# CHECK: ldrexd r12, sp, [r1] @ encoding: [0x9f,0xcf,0xb1,0xe1] +# CHECK: ldrexd r12, sp, [r3] @ encoding: [0x9f,0xcf,0xb3,0xe1] +# CHECK: ldrexd r8, r9, [sp] @ encoding: [0x9f,0x8f,0xbd,0xe1] +# CHECK: ldrexd r12, sp, [lr] @ encoding: [0x9f,0xcf,0xbe,0xe1] + diff --git a/test/MC/Disassembler/ARM/arm-STREXD-reencoding.txt b/test/MC/Disassembler/ARM/arm-STREXD-reencoding.txt new file mode 100644 index 0000000000..27944ac8bc --- /dev/null +++ b/test/MC/Disassembler/ARM/arm-STREXD-reencoding.txt @@ -0,0 +1,14 @@ +# RUN: llvm-mc -triple armv7 -show-encoding -disassemble < %s | FileCheck %s + +0x92 0x1f 0xa0 0xe1 +0x90 0x4f 0xa3 0xe1 +0x92 0xdf 0xa4 0xe1 +0x90 0xaf 0xa6 0xe1 +0x9c 0x5f 0xa8 0xe1 + +# CHECK: strexd r1, r2, r3, [r0] @ encoding: [0x92,0x1f,0xa0,0xe1] +# CHECK: strexd r4, r0, r1, [r3] @ encoding: [0x90,0x4f,0xa3,0xe1] +# CHECK: strexd sp, r2, r3, [r4] @ encoding: [0x92,0xdf,0xa4,0xe1] +# CHECK: strexd r10, r0, r1, [r6] @ encoding: [0x90,0xaf,0xa6,0xe1] +# CHECK: strexd r5, r12, sp, [r8] @ encoding: [0x9c,0x5f,0xa8,0xe1] + -- cgit v1.2.3