Pseudo-ize Thumb2 jump tables with explicit MC lowering to the raw

instructions. This simplifies instruction printing and disassembly.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120333 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach
2010-11-29 22:37:40 +00:00
parent 8ad87ab166
commit 5ca66696e7
8 changed files with 74 additions and 162 deletions

View File

@@ -789,7 +789,6 @@ static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
}
// Misc. Branch Instructions.
// BR_JTadd, BR_JTr, BR_JTm
// BLXr9, BXr9
// BRIND, BX_RET
static bool DisassembleBrMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
@@ -816,72 +815,6 @@ static bool DisassembleBrMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
return true;
}
// BR_JTadd is an ADD with Rd = PC, (Rn, Rm) as the target and index regs.
if (Opcode == ARM::BR_JTadd) {
// InOperandList with GPR:$target and GPR:$idx regs.
assert(NumOps == 4 && "Expect 4 operands");
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
// Fill in the two remaining imm operands to signify build completion.
MI.addOperand(MCOperand::CreateImm(0));
MI.addOperand(MCOperand::CreateImm(0));
OpIdx = 4;
return true;
}
// BR_JTr is a MOV with Rd = PC, and Rm as the source register.
if (Opcode == ARM::BR_JTr) {
// InOperandList with GPR::$target reg.
assert(NumOps == 3 && "Expect 3 operands");
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
// Fill in the two remaining imm operands to signify build completion.
MI.addOperand(MCOperand::CreateImm(0));
MI.addOperand(MCOperand::CreateImm(0));
OpIdx = 3;
return true;
}
// BR_JTm is an LDR with Rt = PC.
if (Opcode == ARM::BR_JTm) {
// This is the reg/reg form, with base reg followed by +/- reg shop imm.
// See also ARMAddressingModes.h (Addressing Mode #2).
assert(NumOps == 5 && getIBit(insn) == 1 && "Expect 5 operands && I-bit=1");
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
// Disassemble the offset reg (Rm), shift type, and immediate shift length.
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
// Inst{6-5} encodes the shift opcode.
ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 6, 5));
// Inst{11-7} encodes the imm5 shift amount.
unsigned ShImm = slice(insn, 11, 7);
// A8.4.1. Possible rrx or shift amount of 32...
getImmShiftSE(ShOp, ShImm);
MI.addOperand(MCOperand::CreateImm(
ARM_AM::getAM2Opc(AddrOpcode, ShImm, ShOp)));
// Fill in the two remaining imm operands to signify build completion.
MI.addOperand(MCOperand::CreateImm(0));
MI.addOperand(MCOperand::CreateImm(0));
OpIdx = 5;
return true;
}
return false;
}

View File

@@ -1248,13 +1248,7 @@ static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned Opcode,
return true;
}
// PC-based defined for Codegen, which do not get decoded by design:
//
// t2TBB, t2TBH: Rm immDontCare immDontCare
//
// Generic version defined for disassembly:
//
// t2TBBgen, t2TBHgen: Rn Rm Pred-Imm Pred-CCR
// t2TBB, t2TBH: Rn Rm Pred-Imm Pred-CCR
static bool DisassembleThumb2TB(MCInst &MI, unsigned Opcode,
uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
@@ -2125,7 +2119,7 @@ static bool DisassembleThumb2(uint16_t op1, uint16_t op2, uint16_t op,
return DisassembleThumb2LdStDual(MI, Opcode, insn, NumOps, NumOpsAdded,
B);
}
if (Opcode == ARM::t2TBBgen || Opcode == ARM::t2TBHgen) {
if (Opcode == ARM::t2TBB || Opcode == ARM::t2TBH) {
// Table branch.
return DisassembleThumb2TB(MI, Opcode, insn, NumOps, NumOpsAdded, B);
}