From 923f3dac014c876e91bf1d797fa3e7e3d8a5e10b Mon Sep 17 00:00:00 2001 From: Johnny Chen Date: Sat, 26 Mar 2011 01:32:48 +0000 Subject: [PATCH] Fixed the t2PLD and friends disassembly and add two test cases. llvm-svn: 128322 --- .../ARM/Disassembler/ARMDisassembler.cpp | 37 ++++++++++++++++++- .../ARM/Disassembler/ThumbDisassemblerCore.h | 12 ++---- llvm/test/MC/Disassembler/ARM/thumb-tests.txt | 6 +++ 3 files changed, 45 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp index 42c267b45ee0..74f8b53b48cf 100644 --- a/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp +++ b/llvm/lib/Target/ARM/Disassembler/ARMDisassembler.cpp @@ -284,6 +284,24 @@ static unsigned T2Morph2LoadLiteral(unsigned Opcode) { } } +// Helper function for special case handling of PLD (literal) and friends. +// See A8.6.117 T1 & T2 and friends for why we morphed the opcode +// before returning it. +static unsigned T2Morph2PLDLiteral(unsigned Opcode) { + switch (Opcode) { + default: + return Opcode; // Return unmorphed opcode. + + case ARM::t2PLDi8: case ARM::t2PLDs: + case ARM::t2PLDWi12: case ARM::t2PLDWi8: + case ARM::t2PLDWs: + return ARM::t2PLDi12; + + case ARM::t2PLIi8: case ARM::t2PLIs: + return ARM::t2PLIi12; + } +} + /// decodeThumbSideEffect is a decorator function which can potentially twiddle /// the instruction or morph the returned opcode under Thumb2. /// @@ -334,12 +352,27 @@ static unsigned decodeThumbSideEffect(bool IsThumb2, unsigned &insn) { } // --------- Transform End Marker --------- + unsigned unmorphed = decodeThumbInstruction(insn); + // See, for example, A6.3.7 Load word: Table A6-18 Load word. // See A8.6.57 T3, T4 & A8.6.60 T2 and friends for why we morphed the opcode // before returning it to our caller. if (op1 == 3 && slice(op2, 6, 5) == 0 && slice(op2, 0, 0) == 1 - && slice(insn, 19, 16) == 15) - return T2Morph2LoadLiteral(decodeThumbInstruction(insn)); + && slice(insn, 19, 16) == 15) { + unsigned morphed = T2Morph2LoadLiteral(unmorphed); + if (morphed != unmorphed) + return morphed; + } + + // See, for example, A8.6.117 PLD,PLDW (immediate) T1 & T2, and friends for + // why we morphed the opcode before returning it to our caller. + if (slice(insn, 31, 25) == 0x7C && slice(insn, 15, 12) == 0xF + && slice(insn, 22, 22) == 0 && slice(insn, 20, 20) == 1 + && slice(insn, 19, 16) == 15) { + unsigned morphed = T2Morph2PLDLiteral(unmorphed); + if (morphed != unmorphed) + return morphed; + } // One last check for NEON/VFP instructions. if ((op1 == 1 || op1 == 3) && slice(op2, 6, 6) == 1) diff --git a/llvm/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h b/llvm/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h index d08e98f511e8..ac6eb67579d0 100644 --- a/llvm/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h +++ b/llvm/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h @@ -1786,7 +1786,7 @@ static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned Opcode, uint32_t insn, decodeRn(insn)))); ++OpIdx; - if (OpInfo[OpIdx].RegClass == ARM::GPRRegClassID) { + if (OpInfo[OpIdx].RegClass == ARM::rGPRRegClassID) { MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID, decodeRm(insn)))); } else { @@ -1794,15 +1794,11 @@ static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned Opcode, uint32_t insn, && !OpInfo[OpIdx].isOptionalDef() && "Pure imm operand expected"); int Offset = 0; - if (slice(insn, 19, 16) == 0xFF) { - bool Negative = slice(insn, 23, 23) == 0; - unsigned Imm12 = getImm12(insn); - Offset = Negative ? -1 - Imm12 : 1 * Imm12; - } else if (Opcode == ARM::t2PLDi8 || Opcode == ARM::t2PLDWi8 || - Opcode == ARM::t2PLIi8) { + if (Opcode == ARM::t2PLDi8 || Opcode == ARM::t2PLDWi8 || + Opcode == ARM::t2PLIi8) { // A8.6.117 Encoding T2: add = FALSE unsigned Imm8 = getImm8(insn); - Offset = -1 - Imm8; + Offset = -1 * Imm8; } else // The i12 forms. See, for example, A8.6.117 Encoding T1. Offset = decodeImm12(insn); MI.addOperand(MCOperand::CreateImm(Offset)); diff --git a/llvm/test/MC/Disassembler/ARM/thumb-tests.txt b/llvm/test/MC/Disassembler/ARM/thumb-tests.txt index b167ad1153b7..2ab75405e0cb 100644 --- a/llvm/test/MC/Disassembler/ARM/thumb-tests.txt +++ b/llvm/test/MC/Disassembler/ARM/thumb-tests.txt @@ -190,3 +190,9 @@ # CHECK: umull r1, r2, r3, r4 0xa3 0xfb 0x04 0x12 + +# CHECK: pld [r5, r0, lsl #1] +0x15 0xf8 0x10 0xf0 + +# CHECK: pld [pc, #-16] +0x1f 0xf8 0x10 0xf0