Refactor the code for disassembling Thumb2 saturate instructions along the

same lines as the change I made for ARM saturate instructions.

llvm-svn: 111029
This commit is contained in:
Bob Wilson 2010-08-13 19:04:21 +00:00
parent 8d3c89e765
commit d3a828ce68
1 changed files with 39 additions and 56 deletions

View File

@ -1470,22 +1470,36 @@ static inline bool Thumb2SaturateOpcode(unsigned Opcode) {
}
}
static inline unsigned decodeThumb2SaturatePos(unsigned Opcode, uint32_t insn) {
switch (Opcode) {
case ARM::t2SSATlsl:
case ARM::t2SSATasr:
return slice(insn, 4, 0) + 1;
case ARM::t2SSAT16:
return slice(insn, 3, 0) + 1;
case ARM::t2USATlsl:
case ARM::t2USATasr:
return slice(insn, 4, 0);
case ARM::t2USAT16:
return slice(insn, 3, 0);
default:
assert(0 && "Unexpected opcode");
return 0;
/// DisassembleThumb2Sat - Disassemble Thumb2 saturate instructions:
/// o t2SSAT[lsl|asr], t2USAT[lsl|asr]: Rs sat_pos Rn shamt
/// o t2SSAT16, t2USAT16: Rs sat_pos Rn
static bool DisassembleThumb2Sat(MCInst &MI, unsigned Opcode, uint32_t insn,
unsigned &NumOpsAdded, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
NumOpsAdded = TID.getNumOperands() - 2; // ignore predicate operands
// Disassemble the register def.
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
decodeRs(insn))));
unsigned Pos = slice(insn, 4, 0);
if (Opcode == ARM::t2SSATlsl ||
Opcode == ARM::t2SSATasr ||
Opcode == ARM::t2SSAT16)
Pos += 1;
MI.addOperand(MCOperand::CreateImm(Pos));
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::rGPRRegClassID,
decodeRn(insn))));
if (NumOpsAdded == 4) {
// Inst{14-12:7-6} encodes the imm5 shift amount.
unsigned ShAmt = slice(insn, 14, 12) << 2 | slice(insn, 7, 6);
if ((Opcode == ARM::t2SSATasr || Opcode == ARM::t2USATasr) && ShAmt == 0)
ShAmt = 32;
MI.addOperand(MCOperand::CreateImm(ShAmt));
}
return true;
}
// A6.3.3 Data-processing (plain binary immediate)
@ -1499,11 +1513,6 @@ static inline unsigned decodeThumb2SaturatePos(unsigned Opcode, uint32_t insn) {
// o t2SBFX (SBFX): Rs Rn lsb width
// o t2UBFX (UBFX): Rs Rn lsb width
// o t2BFI (BFI): Rs Rn lsb width
//
// [Signed|Unsigned] Saturate [16]
//
// o t2SSAT[lsl|asr], t2USAT[lsl|asr]: Rs sat_pos Rn shamt
// o t2SSAT16, t2USAT16: Rs sat_pos Rn
static bool DisassembleThumb2DPBinImm(MCInst &MI, unsigned Opcode,
uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
@ -1528,30 +1537,6 @@ static bool DisassembleThumb2DPBinImm(MCInst &MI, unsigned Opcode,
decodeRs(insn))));
++OpIdx;
// t2SSAT/t2SSAT16/t2USAT/t2USAT16 has imm operand after Rd.
if (Thumb2SaturateOpcode(Opcode)) {
MI.addOperand(MCOperand::CreateImm(decodeThumb2SaturatePos(Opcode, insn)));
MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RnRegClassID,
decodeRn(insn))));
if (Opcode == ARM::t2SSAT16 || Opcode == ARM::t2USAT16) {
OpIdx += 2;
return true;
}
// For SSAT operand reg (Rn) has been disassembled above.
// Now disassemble the shift amount.
// Inst{14-12:7-6} encodes the imm5 shift amount.
unsigned ShAmt = slice(insn, 14, 12) << 2 | slice(insn, 7, 6);
MI.addOperand(MCOperand::CreateImm(ShAmt));
OpIdx += 3;
return true;
}
if (TwoReg) {
assert(NumOps >= 3 && "Expect >= 3 operands");
int Idx;
@ -2163,22 +2148,20 @@ static bool DisassembleThumb2(uint16_t op1, uint16_t op2, uint16_t op,
break;
case 2:
if (op == 0) {
if (slice(op2, 5, 5) == 0) {
if (slice(op2, 5, 5) == 0)
// Data-processing (modified immediate)
return DisassembleThumb2DPModImm(MI, Opcode, insn, NumOps, NumOpsAdded,
B);
} else {
// Data-processing (plain binary immediate)
return DisassembleThumb2DPBinImm(MI, Opcode, insn, NumOps, NumOpsAdded,
B);
}
} else {
// Branches and miscellaneous control on page A6-20.
return DisassembleThumb2BrMiscCtrl(MI, Opcode, insn, NumOps, NumOpsAdded,
B);
}
if (Thumb2SaturateOpcode(Opcode))
return DisassembleThumb2Sat(MI, Opcode, insn, NumOpsAdded, B);
break;
// Data-processing (plain binary immediate)
return DisassembleThumb2DPBinImm(MI, Opcode, insn, NumOps, NumOpsAdded,
B);
}
// Branches and miscellaneous control on page A6-20.
return DisassembleThumb2BrMiscCtrl(MI, Opcode, insn, NumOps, NumOpsAdded,
B);
case 3:
switch (slice(op2, 6, 5)) {
case 0: