Fixed the t2PLD and friends disassembly and add two test cases.
llvm-svn: 128322
This commit is contained in:
parent
785cbdb6da
commit
923f3dac01
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue