aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohnny Chen <johnny.chen@apple.com>2011-03-26 01:32:48 +0000
committerJohnny Chen <johnny.chen@apple.com>2011-03-26 01:32:48 +0000
commiteca915fb5242442756a80bad7f285cb54d7b8ea4 (patch)
tree0b53af21c434667a4ce383bd0c5ffa6574928175
parent29aeed1bf8c70eec381d5cbf7de2710b5157d526 (diff)
Fixed the t2PLD and friends disassembly and add two test cases.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@128322 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Target/ARM/Disassembler/ARMDisassembler.cpp37
-rw-r--r--lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h12
-rw-r--r--test/MC/Disassembler/ARM/thumb-tests.txt6
3 files changed, 45 insertions, 10 deletions
diff --git a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp b/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
index 42c267b45e..74f8b53b48 100644
--- a/lib/Target/ARM/Disassembler/ARMDisassembler.cpp
+++ b/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/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h b/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
index d08e98f511..ac6eb67579 100644
--- a/lib/Target/ARM/Disassembler/ThumbDisassemblerCore.h
+++ b/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/test/MC/Disassembler/ARM/thumb-tests.txt b/test/MC/Disassembler/ARM/thumb-tests.txt
index b167ad1153..2ab75405e0 100644
--- a/test/MC/Disassembler/ARM/thumb-tests.txt
+++ b/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