// Return the register enum Based on RegClass and the raw register number.
// For DRegPair, see comments below.
// FIXME: Auto-gened?
-static unsigned getRegisterEnum(unsigned RegClassID, unsigned RawRegister,
+static unsigned getRegisterEnum(BO B, unsigned RegClassID, unsigned RawRegister,
bool DRegPair = false) {
if (DRegPair && RegClassID == ARM::QPRRegClassID) {
}
break;
}
- assert(0 && "Invalid (RegClassID, RawRegister) combination");
+ errs() << "Invalid (RegClassID, RawRegister) combination\n";
+ // Encoding error. Mark the builder with error code != 0.
+ B->SetErr(-1);
return 0;
}
// Inst{3-0} => Rm
// Inst{11-8} => Rs
static bool DisassembleMulFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
unsigned short NumDefs = TID.getNumDefs();
if (NumDefs == 2) {
assert(NumOps >= 4 && OpInfo[3].RegClass == ARM::GPRRegClassID &&
"Expect 4th register operand");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
++OpIdx;
}
// The destination register: RdHi{19-16} or Rd{19-16}.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
// The two src regsiters: Rn{3-0}, then Rm{11-8}.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRs(insn))));
OpIdx += 3;
// Many multiply instructions (e.g., MLA) have three src registers.
// The third register operand is Ra{15-12}.
if (OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::GPRRegClassID) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
++OpIdx;
}
// and friends
//
static bool DisassembleCoprocessor(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(NumOps >= 5 && "Num of operands >= 5 for coprocessor instr");
MI.addOperand(MCOperand::CreateImm(decodeRd(insn)));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
if (PW) {
MI.addOperand(NoGPR ? MCOperand::CreateImm(decodeRd(insn))
: MCOperand::CreateReg(
- getRegisterEnum(ARM::GPRRegClassID,
+ getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
MI.addOperand(OneCopOpc ? MCOperand::CreateReg(
- getRegisterEnum(ARM::GPRRegClassID,
+ getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn)))
: MCOperand::CreateImm(decodeRn(insn)));
// SRSW/SRS: addrmode4:$addr mode_imm
// RFEW/RFE: addrmode4:$addr Rn
static bool DisassembleBrFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
if (CoprocessorOpcode(Opcode))
- return DisassembleCoprocessor(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleCoprocessor(MI, Opcode, insn, NumOps, NumOpsAdded, B);
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
if (!OpInfo) return false;
if (Opcode == ARM::MRS || Opcode == ARM::MRSsys) {
assert(NumOps >= 1 && OpInfo[0].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
NumOpsAdded = 1;
return true;
if (Opcode == ARM::BXJ) {
assert(NumOps >= 1 && OpInfo[0].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
NumOpsAdded = 1;
return true;
if (Opcode == ARM::MSR || Opcode == ARM::MSRsys) {
assert(NumOps >= 1 && OpInfo[0].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
MI.addOperand(MCOperand::CreateImm(slice(insn, 19, 16)));
NumOpsAdded = 2;
if (Opcode == ARM::SRSW || Opcode == ARM::SRS)
MI.addOperand(MCOperand::CreateImm(slice(insn, 4, 0)));
else
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
NumOpsAdded = 3;
return true;
// BLXr9, BXr9
// BRIND, BX_RET
static bool DisassembleBrMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
if (!OpInfo) return false;
if (Opcode == ARM::BLXr9 || Opcode == ARM::BRIND) {
assert(NumOps >= 1 && OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
OpIdx = 1;
return true;
// InOperandList with GPR:$target and GPR:$idx regs.
assert(NumOps == 4 && "Expect 4 operands");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
// Fill in the two remaining imm operands to signify build completion.
// InOperandList with GPR::$target reg.
assert(NumOps == 3 && "Expect 3 operands");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
// Fill in the two remaining imm operands to signify build completion.
// See also ARMAddressingModes.h (Addressing Mode #2).
assert(NumOps == 5 && getIBit(insn) == 1 && "Expect 5 operands && I-bit=1");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ 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(ARM::GPRRegClassID,
+ 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));
// operations have Rd Rm Rn, instead of the "normal" Rd Rn Rm.
// They are QADD, QDADD, QDSUB, and QSUB.
static bool DisassembleDPFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
unsigned short NumDefs = TID.getNumDefs();
// Disassemble register def if there is one.
if (NumDefs && (OpInfo[OpIdx].RegClass == ARM::GPRRegClassID)) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
++OpIdx;
}
if (SaturateOpcode(Opcode)) {
MI.addOperand(MCOperand::CreateImm(decodeSaturatePos(Opcode, insn)));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
if (Opcode == ARM::SSAT16 || Opcode == ARM::USAT16) {
if (Opcode == ARM::BFC || Opcode == ARM::BFI) {
// TIED_TO operand skipped for BFC and Inst{3-0} (Reg) for BFI.
MI.addOperand(MCOperand::CreateReg(Opcode == ARM::BFC ? 0
- : getRegisterEnum(ARM::GPRRegClassID,
+ : getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
uint32_t mask = 0;
if (!getBFCInvMask(insn, mask))
return true;
}
if (Opcode == ARM::SBFX || Opcode == ARM::UBFX) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
MI.addOperand(MCOperand::CreateImm(slice(insn, 11, 7)));
MI.addOperand(MCOperand::CreateImm(slice(insn, 20, 16) + 1));
assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(ARM::GPRRegClassID,
+ getRegisterEnum(B, ARM::GPRRegClassID,
RmRn ? decodeRm(insn) : decodeRn(insn))));
++OpIdx;
}
// routed here as well.
// assert(getIBit(insn) == 0 && "I_Bit != '0' reg/reg form");
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(ARM::GPRRegClassID,
+ getRegisterEnum(B, ARM::GPRRegClassID,
RmRn? decodeRn(insn) : decodeRm(insn))));
++OpIdx;
} else if (Opcode == ARM::MOVi16 || Opcode == ARM::MOVTi16) {
}
static bool DisassembleDPSoRegFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
unsigned short NumDefs = TID.getNumDefs();
// Disassemble register def if there is one.
if (NumDefs && (OpInfo[OpIdx].RegClass == ARM::GPRRegClassID)) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
++OpIdx;
}
if (!isUnary) {
assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
}
// Register-controlled shifts have Inst{7} = 0 and Inst{4} = 1.
unsigned Rs = slice(insn, 4, 4);
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
if (Rs) {
// Register-controlled shifts: [Rm, Rs, shift].
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRs(insn))));
// Inst{6-5} encodes the shift opcode.
ARM_AM::ShiftOpc ShOp = getShiftOpcForBits(slice(insn, 6, 5));
}
static bool DisassembleLdStFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, bool isStore) {
+ unsigned short NumOps, unsigned &NumOpsAdded, bool isStore, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
bool isPrePost = isPrePostLdSt(TID.TSFlags);
if (isPrePost && isStore) {
assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
}
assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
++OpIdx;
if (isPrePost && !isStore) {
assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
}
"Reg operand expected");
assert((!isPrePost || (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1))
&& "Index mode or tied_to operand expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
MI.addOperand(MCOperand::CreateImm(Offset));
} else {
// Disassemble the offset reg (Rm), shift type, and immediate shift length.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ 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));
}
static bool DisassembleLdFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
- return DisassembleLdStFrm(MI, Opcode, insn, NumOps, NumOpsAdded, false);
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
+ return DisassembleLdStFrm(MI, Opcode, insn, NumOps, NumOpsAdded, false, B);
}
static bool DisassembleStFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
- return DisassembleLdStFrm(MI, Opcode, insn, NumOps, NumOpsAdded, true);
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
+ return DisassembleLdStFrm(MI, Opcode, insn, NumOps, NumOpsAdded, true, B);
}
static bool HasDualReg(unsigned Opcode) {
}
static bool DisassembleLdStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, bool isStore) {
+ unsigned short NumOps, unsigned &NumOpsAdded, bool isStore, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
bool isPrePost = isPrePostLdSt(TID.TSFlags);
if (isPrePost && isStore) {
assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
}
assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
++OpIdx;
// Fill in LDRD and STRD's second operand.
if (DualReg) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn) + 1)));
++OpIdx;
}
if (isPrePost && !isStore) {
assert(OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
"Reg operand expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
}
"Reg operand expected");
assert((!isPrePost || (TID.getOperandConstraint(OpIdx, TOI::TIED_TO) != -1))
&& "Index mode or tied_to operand expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
MI.addOperand(MCOperand::CreateImm(Offset));
} else {
// Disassemble the offset reg (Rm).
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
unsigned Offset = ARM_AM::getAM3Opc(AddrOpcode, 0);
MI.addOperand(MCOperand::CreateImm(Offset));
}
static bool DisassembleLdMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
- return DisassembleLdStMiscFrm(MI, Opcode, insn, NumOps, NumOpsAdded, false);
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
+ return DisassembleLdStMiscFrm(MI, Opcode, insn, NumOps, NumOpsAdded, false,
+ B);
}
static bool DisassembleStMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
- return DisassembleLdStMiscFrm(MI, Opcode, insn, NumOps, NumOpsAdded, true);
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
+ return DisassembleLdStMiscFrm(MI, Opcode, insn, NumOps, NumOpsAdded, true, B);
}
// The algorithm for disassembly of LdStMulFrm is different from others because
// and operand 1 (the AM4 mode imm). After operand 3, we need to populate the
// reglist with each affected register encoded as an MCOperand.
static bool DisassembleLdStMulFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(NumOps >= 5 && "LdStMulFrm expects NumOps >= 5");
OpIdx = 0;
- unsigned Base = getRegisterEnum(ARM::GPRRegClassID, decodeRn(insn));
+ unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
// Writeback to base, if necessary.
if (Opcode == ARM::LDM_UPD || Opcode == ARM::STM_UPD) {
unsigned RegListBits = insn & ((1 << 16) - 1);
for (unsigned i = 0; i < 16; ++i) {
if ((RegListBits >> i) & 1) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
i)));
++OpIdx;
}
//
// SWP, SWPB: Rd Rm Rn
static bool DisassembleLdStExFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
if (!OpInfo) return false;
bool isDW = (Opcode == ARM::LDREXD || Opcode == ARM::STREXD);
// Add the destination operand.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
++OpIdx;
// Store register Exclusive needs a source operand.
if (isStore) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
++OpIdx;
if (isDW) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn)+1)));
++OpIdx;
}
} else if (isDW) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn)+1)));
++OpIdx;
}
// Finally add the pointer operand.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
// PKHBT, PKHTB: Rd Rn Rm , LSL/ASR #imm5
// RBIT, REV, REV16, REVSH: Rd Rm
static bool DisassembleArithMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
unsigned &OpIdx = NumOpsAdded;
bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass == ARM::GPRRegClassID;
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
++OpIdx;
if (ThreeReg) {
assert(NumOps >= 4 && "Expect >= 4 operands");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
}
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
++OpIdx;
// The 2nd operand register is Rn and the 3rd operand regsiter is Rm for the
// three register operand form. Otherwise, Rn=0b1111 and only Rm is used.
static bool DisassembleExtFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
unsigned &OpIdx = NumOpsAdded;
bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass == ARM::GPRRegClassID;
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
++OpIdx;
if (ThreeReg) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
}
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
++OpIdx;
// VCVTDS, VCVTSD: converts between double-precision and single-precision
// The rest of the instructions have homogeneous [VFP]Rd and [VFP]Rm registers.
static bool DisassembleVFPUnaryFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(NumOps >= 1 && "VFPUnaryFrm expects NumOps >= 1");
bool isSP = (RegClass == ARM::SPRRegClassID);
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(RegClass, decodeVFPRd(insn, isSP))));
+ getRegisterEnum(B, RegClass, decodeVFPRd(insn, isSP))));
++OpIdx;
// Early return for compare with zero instructions.
isSP = (RegClass == ARM::SPRRegClassID);
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(RegClass, decodeVFPRm(insn, isSP))));
+ getRegisterEnum(B, RegClass, decodeVFPRm(insn, isSP))));
++OpIdx;
return true;
// InOperandList to that of the dst. As far as asm printing is concerned, this
// tied_to operand is simply skipped.
static bool DisassembleVFPBinaryFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(NumOps >= 3 && "VFPBinaryFrm expects NumOps >= 3");
bool isSP = (RegClass == ARM::SPRRegClassID);
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(RegClass, decodeVFPRd(insn, isSP))));
+ getRegisterEnum(B, RegClass, decodeVFPRd(insn, isSP))));
++OpIdx;
// Skip tied_to operand constraint.
}
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(RegClass, decodeVFPRn(insn, isSP))));
+ getRegisterEnum(B, RegClass, decodeVFPRn(insn, isSP))));
++OpIdx;
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(RegClass, decodeVFPRm(insn, isSP))));
+ getRegisterEnum(B, RegClass, decodeVFPRm(insn, isSP))));
++OpIdx;
return true;
// A8.6.297 vcvt (floating-point and fixed-point)
// Dd|Sd Dd|Sd(TIED_TO) #fbits(= 16|32 - UInt(imm4:i))
static bool DisassembleVFPConv1Frm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(NumOps >= 2 && "VFPConv1Frm expects NumOps >= 2");
int size = slice(insn, 7, 7) == 0 ? 16 : 32;
int fbits = size - (slice(insn,3,0) << 1 | slice(insn,5,5));
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(RegClassID,
+ getRegisterEnum(B, RegClassID,
decodeVFPRd(insn, SP))));
assert(TID.getOperandConstraint(1, TOI::TIED_TO) != -1 &&
if (slice(insn, 18, 18) == 1) { // to_integer operation
d = decodeVFPRd(insn, true /* Is Single Precision */);
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(ARM::SPRRegClassID, d)));
+ getRegisterEnum(B, ARM::SPRRegClassID, d)));
m = decodeVFPRm(insn, SP);
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(RegClassID, m)));
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassID, m)));
} else {
d = decodeVFPRd(insn, SP);
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(RegClassID, d)));
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassID, d)));
m = decodeVFPRm(insn, true /* Is Single Precision */);
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(ARM::SPRRegClassID, m)));
+ getRegisterEnum(B, ARM::SPRRegClassID, m)));
}
NumOpsAdded = 2;
}
// VMOVRS - A8.6.330
// Rt => Rd; Sn => UInt(Vn:N)
static bool DisassembleVFPConv2Frm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(NumOps >= 2 && "VFPConv2Frm expects NumOps >= 2");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::SPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::SPRRegClassID,
decodeVFPRn(insn, true))));
NumOpsAdded = 2;
return true;
// VMOVRRS - A8.6.331
// Rt => Rd; Rt2 => Rn; Sm => UInt(Vm:M); Sm1 = Sm+1
static bool DisassembleVFPConv3Frm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(NumOps >= 3 && "VFPConv3Frm expects NumOps >= 3");
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
unsigned &OpIdx = NumOpsAdded;
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
OpIdx = 2;
if (OpInfo[OpIdx].RegClass == ARM::SPRRegClassID) {
unsigned Sm = decodeVFPRm(insn, true);
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::SPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::SPRRegClassID,
Sm)));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::SPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::SPRRegClassID,
Sm+1)));
OpIdx += 2;
} else {
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(ARM::DPRRegClassID,
+ getRegisterEnum(B, ARM::DPRRegClassID,
decodeVFPRm(insn, false))));
++OpIdx;
}
// VMOVSR - A8.6.330
// Rt => Rd; Sn => UInt(Vn:N)
static bool DisassembleVFPConv4Frm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(NumOps >= 2 && "VFPConv4Frm expects NumOps >= 2");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::SPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::SPRRegClassID,
decodeVFPRn(insn, true))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
NumOpsAdded = 2;
return true;
// VMOVRRS - A8.6.331
// Rt => Rd; Rt2 => Rn; Sm => UInt(Vm:M); Sm1 = Sm+1
static bool DisassembleVFPConv5Frm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(NumOps >= 3 && "VFPConv5Frm expects NumOps >= 3");
if (OpInfo[OpIdx].RegClass == ARM::SPRRegClassID) {
unsigned Sm = decodeVFPRm(insn, true);
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::SPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::SPRRegClassID,
Sm)));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::SPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::SPRRegClassID,
Sm+1)));
OpIdx += 2;
} else {
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(ARM::DPRRegClassID,
+ getRegisterEnum(B, ARM::DPRRegClassID,
decodeVFPRm(insn, false))));
++OpIdx;
}
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
OpIdx += 2;
return true;
// VFP Load/Store Instructions.
// VLDRD, VLDRS, VSTRD, VSTRS
static bool DisassembleVFPLdStFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(NumOps >= 3 && "VFPLdStFrm expects NumOps >= 3");
// Extract Dd/Sd for operand 0.
unsigned RegD = decodeVFPRd(insn, isSPVFP);
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(RegClassID, RegD)));
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassID, RegD)));
- unsigned Base = getRegisterEnum(ARM::GPRRegClassID, decodeRn(insn));
+ unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
MI.addOperand(MCOperand::CreateReg(Base));
// Next comes the AM5 Opcode.
//
// VLDMD[_UPD], VLDMS[_UPD], VSTMD[_UPD], VSTMS[_UPD]
static bool DisassembleVFPLdStMulFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(NumOps >= 5 && "VFPLdStMulFrm expects NumOps >= 5");
OpIdx = 0;
- unsigned Base = getRegisterEnum(ARM::GPRRegClassID, decodeRn(insn));
+ unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
// Writeback to base, if necessary.
if (Opcode == ARM::VLDMD_UPD || Opcode == ARM::VLDMS_UPD ||
// Fill the variadic part of reglist.
unsigned Regs = isSPVFP ? Imm8 : Imm8/2;
for (unsigned i = 0; i < Regs; ++i) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(RegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClassID,
RegD + i)));
++OpIdx;
}
// FCONSTS (SPR and a VFPf32Imm operand)
// VMRS/VMSR (GPR operand)
static bool DisassembleVFPMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
unsigned &OpIdx = NumOpsAdded;
unsigned RegEnum = 0;
switch (OpInfo[0].RegClass) {
case ARM::DPRRegClassID:
- RegEnum = getRegisterEnum(ARM::DPRRegClassID, decodeVFPRd(insn, false));
+ RegEnum = getRegisterEnum(B, ARM::DPRRegClassID, decodeVFPRd(insn, false));
break;
case ARM::SPRRegClassID:
- RegEnum = getRegisterEnum(ARM::SPRRegClassID, decodeVFPRd(insn, true));
+ RegEnum = getRegisterEnum(B, ARM::SPRRegClassID, decodeVFPRd(insn, true));
break;
case ARM::GPRRegClassID:
- RegEnum = getRegisterEnum(ARM::GPRRegClassID, decodeRd(insn));
+ RegEnum = getRegisterEnum(B, ARM::GPRRegClassID, decodeRd(insn));
break;
default:
assert(0 && "Invalid reg class id");
//
// Correctly set VLD*/VST*'s TIED_TO GPR, as the asm printer needs it.
static bool DisassembleNLdSt0(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, bool Store, bool DblSpaced) {
+ unsigned short NumOps, unsigned &NumOpsAdded, bool Store, bool DblSpaced,
+ BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
const TargetOperandInfo *OpInfo = TID.OpInfo;
// LLVM Addressing Mode #6.
unsigned RmEnum = 0;
if (WB && Rm != 13)
- RmEnum = getRegisterEnum(ARM::GPRRegClassID, Rm);
+ RmEnum = getRegisterEnum(B, ARM::GPRRegClassID, Rm);
if (Store) {
// Consume possible WB, AddrMode6, possible increment reg, the DPR/QPR's,
"Reg operand expected");
if (WB) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
Rn)));
++OpIdx;
}
assert((OpIdx+1) < NumOps && OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
OpInfo[OpIdx + 1].RegClass == 0 && "Addrmode #6 Operands expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
Rn)));
MI.addOperand(MCOperand::CreateImm(0)); // Alignment ignored?
OpIdx += 2;
RegClass = OpInfo[OpIdx].RegClass;
while (OpIdx < NumOps && OpInfo[OpIdx].RegClass == RegClass) {
if (Opcode >= ARM::VST1q16 && Opcode <= ARM::VST1q8)
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(RegClass,Rd,true)));
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClass, Rd,
+ true)));
else
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(RegClass,Rd)));
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClass,Rd)));
Rd += Inc;
++OpIdx;
}
while (OpIdx < NumOps && OpInfo[OpIdx].RegClass == RegClass) {
if (Opcode >= ARM::VLD1q16 && Opcode <= ARM::VLD1q8)
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(RegClass,Rd,true)));
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClass, Rd,
+ true)));
else
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(RegClass,Rd)));
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClass, Rd)));
Rd += Inc;
++OpIdx;
}
if (WB) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
Rn)));
++OpIdx;
}
assert((OpIdx+1) < NumOps && OpInfo[OpIdx].RegClass == ARM::GPRRegClassID &&
OpInfo[OpIdx + 1].RegClass == 0 && "Addrmode #6 Operands expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
Rn)));
MI.addOperand(MCOperand::CreateImm(0)); // Alignment ignored?
OpIdx += 2;
// Find out about double-spaced-ness of the Opcode and pass it on to
// DisassembleNLdSt0().
static bool DisassembleNLdSt(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const StringRef Name = ARMInsts[Opcode].Name;
bool DblSpaced = false;
}
return DisassembleNLdSt0(MI, Opcode, insn, NumOps, NumOpsAdded,
- slice(insn, 21, 21) == 0, DblSpaced);
+ slice(insn, 21, 21) == 0, DblSpaced, B);
}
// VMOV (immediate)
// Qd/Dd imm
static bool DisassembleN1RegModImmFrm(MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
const TargetOperandInfo *OpInfo = TID.OpInfo;
"Expect 1 reg operand followed by 1 imm operand");
// Qd/Dd = Inst{22:15-12} => NEON Rd
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(OpInfo[0].RegClass,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[0].RegClass,
decodeNEONRd(insn))));
ElemSize esize = ESizeNA;
//
// Others
static bool DisassembleNVdVmOptImm(MCInst &MI, unsigned Opc, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, N2VFlag Flag = N2V_None) {
+ unsigned short NumOps, unsigned &NumOpsAdded, N2VFlag Flag, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opc];
const TargetOperandInfo *OpInfo = TID.OpInfo;
}
// Qd/Dd = Inst{22:15-12} => NEON Rd
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(OpInfo[OpIdx].RegClass,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
decodeNEONRd(insn))));
++OpIdx;
}
// Dm = Inst{5:3-0} => NEON Rm
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(OpInfo[OpIdx].RegClass,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
decodeNEONRm(insn))));
++OpIdx;
}
static bool DisassembleN2RegFrm(MCInst &MI, unsigned Opc, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
- return DisassembleNVdVmOptImm(MI, Opc, insn, NumOps, NumOpsAdded);
+ return DisassembleNVdVmOptImm(MI, Opc, insn, NumOps, NumOpsAdded,
+ N2V_None, B);
}
static bool DisassembleNVCVTFrm(MCInst &MI, unsigned Opc, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
return DisassembleNVdVmOptImm(MI, Opc, insn, NumOps, NumOpsAdded,
- N2V_VectorConvert_Between_Float_Fixed);
+ N2V_VectorConvert_Between_Float_Fixed, B);
}
static bool DisassembleNVecDupLnFrm(MCInst &MI, unsigned Opc, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
return DisassembleNVdVmOptImm(MI, Opc, insn, NumOps, NumOpsAdded,
- N2V_VectorDupLane);
+ N2V_VectorDupLane, B);
}
// Vector Shift [Accumulate] Instructions.
// VSHLLi16, VSHLLi32, VSHLLi8: Qd Dm imm (== size)
//
static bool DisassembleNVectorShift(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, bool LeftShift) {
+ unsigned short NumOps, unsigned &NumOpsAdded, bool LeftShift, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
const TargetOperandInfo *OpInfo = TID.OpInfo;
OpIdx = 0;
// Qd/Dd = Inst{22:15-12} => NEON Rd
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(OpInfo[OpIdx].RegClass,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
decodeNEONRd(insn))));
++OpIdx;
"Reg operand expected");
// Qm/Dm = Inst{5:3-0} => NEON Rm
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(OpInfo[OpIdx].RegClass,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
decodeNEONRm(insn))));
++OpIdx;
// Left shift instructions.
static bool DisassembleN2RegVecShLFrm(MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
- return DisassembleNVectorShift(MI, Opcode, insn, NumOps, NumOpsAdded, true);
+ return DisassembleNVectorShift(MI, Opcode, insn, NumOps, NumOpsAdded, true,
+ B);
}
// Right shift instructions have different shift amount interpretation.
static bool DisassembleN2RegVecShRFrm(MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
- return DisassembleNVectorShift(MI, Opcode, insn, NumOps, NumOpsAdded, false);
+ return DisassembleNVectorShift(MI, Opcode, insn, NumOps, NumOpsAdded, false,
+ B);
}
namespace {
//
// Others
static bool DisassembleNVdVnVmOptImm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, N3VFlag Flag = N3V_None) {
+ unsigned short NumOps, unsigned &NumOpsAdded, N3VFlag Flag, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
const TargetOperandInfo *OpInfo = TID.OpInfo;
}
// Qd/Dd = Inst{22:15-12} => NEON Rd
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(OpInfo[OpIdx].RegClass,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, OpInfo[OpIdx].RegClass,
decodeNEONRd(insn))));
++OpIdx;
// or
// Dm = Inst{5:3-0} => NEON Rm
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(OpInfo[OpIdx].RegClass,
+ getRegisterEnum(B, OpInfo[OpIdx].RegClass,
VdVnVm ? decodeNEONRn(insn)
: decodeNEONRm(insn))));
++OpIdx;
: decodeNEONRn(insn);
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(OpInfo[OpIdx].RegClass, m)));
+ getRegisterEnum(B, OpInfo[OpIdx].RegClass, m)));
++OpIdx;
if (OpIdx < NumOps && OpInfo[OpIdx].RegClass == 0
}
static bool DisassembleN3RegFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
- return DisassembleNVdVnVmOptImm(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleNVdVnVmOptImm(MI, Opcode, insn, NumOps, NumOpsAdded,
+ N3V_None, B);
}
static bool DisassembleN3RegVecShFrm(MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
return DisassembleNVdVnVmOptImm(MI, Opcode, insn, NumOps, NumOpsAdded,
- N3V_VectorShift);
+ N3V_VectorShift, B);
}
static bool DisassembleNVecExtractFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
return DisassembleNVdVnVmOptImm(MI, Opcode, insn, NumOps, NumOpsAdded,
- N3V_VectorExtract);
+ N3V_VectorExtract, B);
}
static bool DisassembleNVecMulScalarFrm(MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
return DisassembleNVdVnVmOptImm(MI, Opcode, insn, NumOps, NumOpsAdded,
- N3V_Multiply_By_Scalar);
+ N3V_Multiply_By_Scalar, B);
}
// Vector Table Lookup
// VTBL3, VTBX3: Dd [Dd(TIED_TO)] Dn Dn+1 Dn+2 Dm
// VTBL4, VTBX4: Dd [Dd(TIED_TO)] Dn Dn+1 Dn+2 Dn+3 Dm
static bool DisassembleNVTBLFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
const TargetOperandInfo *OpInfo = TID.OpInfo;
unsigned Len = slice(insn, 9, 8) + 1;
// Dd (the destination vector)
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::DPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::DPRRegClassID,
decodeNEONRd(insn))));
++OpIdx;
for (unsigned i = 0; i < Len; ++i) {
assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::DPRRegClassID &&
"Reg operand expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::DPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::DPRRegClassID,
Rn + i)));
++OpIdx;
}
// Dm (the index vector)
assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::DPRRegClassID &&
"Reg operand (index vector) expected");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::DPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::DPRRegClassID,
decodeNEONRm(insn))));
++OpIdx;
// Vector Get Lane (move scalar to ARM core register) Instructions.
// VGETLNi32, VGETLNs16, VGETLNs8, VGETLNu16, VGETLNu8: Rt Dn index
static bool DisassembleNEONGetLnFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
const TargetOperandInfo *OpInfo = TID.OpInfo;
: ESize32);
// Rt = Inst{15-12} => ARM Rd
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
// Dn = Inst{7:19-16} => NEON Rn
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::DPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::DPRRegClassID,
decodeNEONRn(insn))));
MI.addOperand(MCOperand::CreateImm(decodeNVLaneOpIndex(insn, esize)));
// Vector Set Lane (move ARM core register to scalar) Instructions.
// VSETLNi16, VSETLNi32, VSETLNi8: Dd Dd (TIED_TO) Rt index
static bool DisassembleNEONSetLnFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
const TargetOperandInfo *OpInfo = TID.OpInfo;
: ESize32);
// Dd = Inst{7:19-16} => NEON Rn
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::DPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::DPRRegClassID,
decodeNEONRn(insn))));
// TIED_TO operand.
MI.addOperand(MCOperand::CreateReg(0));
// Rt = Inst{15-12} => ARM Rd
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
MI.addOperand(MCOperand::CreateImm(decodeNVLaneOpIndex(insn, esize)));
// Vector Duplicate Instructions (from ARM core register to all elements).
// VDUP8d, VDUP16d, VDUP32d, VDUP8q, VDUP16q, VDUP32q: Qd/Dd Rt
static bool DisassembleNEONDupFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
unsigned RegClass = OpInfo[0].RegClass;
// Qd/Dd = Inst{7:19-16} => NEON Rn
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(RegClass,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, RegClass,
decodeNEONRn(insn))));
// Rt = Inst{15-12} => ARM Rd
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
NumOpsAdded = 2;
}
static bool DisassemblePreLoadFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
// Preload Data/Instruction requires either 2 or 4 operands.
// PLDi, PLDWi, PLIi: Rn [+/-]imm12 add = (U == '1')
// PLDr[a|m], PLDWr[a|m], PLIr[a|m]: Rn Rm addrmode2_opc
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
if (Opcode == ARM::PLDi || Opcode == ARM::PLDWi || Opcode == ARM::PLIi) {
MI.addOperand(MCOperand::CreateImm(Offset));
NumOpsAdded = 2;
} else {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
ARM_AM::AddrOpc AddrOpcode = getUBit(insn) ? ARM_AM::add : ARM_AM::sub;
}
static bool DisassembleMiscFrm(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
if (MemBarrierInstr(insn))
return true;
}
if (PreLoadOpcode(Opcode))
- return DisassemblePreLoadFrm(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassemblePreLoadFrm(MI, Opcode, insn, NumOps, NumOpsAdded, B);
assert(0 && "Unexpected misc instruction!");
return false;
unsigned NumOpsAdded = 0;
bool OK = (*Disasm)(MI, Opcode, insn, NumOps, NumOpsAdded, this);
- if (!OK) return false;
+ if (!OK || this->Err != 0) return false;
if (NumOpsAdded >= NumOps)
return true;
/// Opcode, Format, and NumOperands make up an ARM Basic MCBuilder.
ARMBasicMCBuilder::ARMBasicMCBuilder(unsigned opc, ARMFormat format,
unsigned short num)
- : Opcode(opc), Format(format), NumOps(num), SP(0) {
+ : Opcode(opc), Format(format), NumOps(num), SP(0), Err(0) {
unsigned Idx = (unsigned)format;
assert(Idx < (array_lengthof(FuncPtrs) - 1) && "Unknown format");
Disasm = FuncPtrs[Idx];
// Special case:
// tMOVSr: tRd tRn
static bool DisassembleThumb1General(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO Builder) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
unsigned &OpIdx = NumOpsAdded;
// Add the destination operand.
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(ARM::tGPRRegClassID,
+ getRegisterEnum(B, ARM::tGPRRegClassID,
UseRt ? getT1tRt(insn) : getT1tRd(insn))));
++OpIdx;
// Check whether the next operand to be added is a CCR Register.
if (OpInfo[OpIdx].RegClass == ARM::CCRRegClassID) {
assert(OpInfo[OpIdx].isOptionalDef() && "Optional def operand expected");
- MI.addOperand(MCOperand::CreateReg(Builder->InITBlock() ? 0 : ARM::CPSR));
+ MI.addOperand(MCOperand::CreateReg(B->InITBlock() ? 0 : ARM::CPSR));
++OpIdx;
}
if (OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
// For UseRt, the reg operand is tied to the first reg operand.
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(ARM::tGPRRegClassID,
+ getRegisterEnum(B, ARM::tGPRRegClassID,
UseRt ? getT1tRt(insn) : getT1tRn(insn))));
++OpIdx;
}
// The next available operand is either a reg operand or an imm operand.
if (OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
// Three register operand instructions.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::tGPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
getT1tRm(insn))));
} else {
assert(OpInfo[OpIdx].RegClass == 0 &&
// tMVN, tRSB: tRd CPSR tRn
// Others: tRd CPSR tRd(TIED_TO) tRn
static bool DisassembleThumb1DP(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO Builder) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
const TargetOperandInfo *OpInfo = TID.OpInfo;
&& "Invalid arguments");
// Add the destination operand.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::tGPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
getT1tRd(insn))));
++OpIdx;
// Check whether the next operand to be added is a CCR Register.
if (OpInfo[OpIdx].RegClass == ARM::CCRRegClassID) {
assert(OpInfo[OpIdx].isOptionalDef() && "Optional def operand expected");
- MI.addOperand(MCOperand::CreateReg(Builder->InITBlock() ? 0 : ARM::CPSR));
+ MI.addOperand(MCOperand::CreateReg(B->InITBlock() ? 0 : ARM::CPSR));
++OpIdx;
}
// Process possible next reg operand.
if (OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID) {
// Add tRn operand.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::tGPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
getT1tRn(insn))));
++OpIdx;
}
// tBX_RET_vararg: Rm
// tBLXr_r9: Rm
static bool DisassembleThumb1Special(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
// tBX_RET has 0 operand.
if (NumOps == 0)
// BX/BLX has 1 reg operand: Rm.
if (NumOps == 1) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
getT1Rm(insn))));
NumOpsAdded = 1;
return true;
// Add the destination operand.
unsigned RegClass = OpInfo[OpIdx].RegClass;
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(RegClass,
+ getRegisterEnum(B, RegClass,
IsGPR(RegClass) ? getT1Rd(insn)
: getT1tRd(insn))));
++OpIdx;
assert(OpIdx < NumOps && "More operands expected");
RegClass = OpInfo[OpIdx].RegClass;
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(RegClass,
+ getRegisterEnum(B, RegClass,
IsGPR(RegClass) ? getT1Rm(insn)
: getT1tRn(insn))));
++OpIdx;
//
// tLDRpci: tRt imm8*4
static bool DisassembleThumb1LdPC(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
if (!OpInfo) return false;
&& "Invalid arguments");
// Add the destination operand.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::tGPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
getT1tRt(insn))));
// And the (imm8 << 2) operand.
// Load/Store Register (reg|imm): tRd tRn imm5 tRm
// Load Register Signed Byte|Halfword: tRd tRn tRm
static bool DisassembleThumb1LdSt(unsigned opA, MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded) {
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
const TargetOperandInfo *OpInfo = TID.OpInfo;
&& "Expect >= 2 operands and first two as thumb reg operands");
// Add the destination reg and the base reg.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::tGPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
getT1tRd(insn))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::tGPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
getT1tRn(insn))));
OpIdx = 2;
// The next reg operand is tRm, the offset.
assert(OpIdx < NumOps && OpInfo[OpIdx].RegClass == ARM::tGPRRegClassID
&& "Thumb reg operand expected");
- MI.addOperand(MCOperand::CreateReg(Imm5 ? 0
- : getRegisterEnum(ARM::tGPRRegClassID,
- getT1tRm(insn))));
+ MI.addOperand(MCOperand::CreateReg(
+ Imm5 ? 0
+ : getRegisterEnum(B, ARM::tGPRRegClassID,
+ getT1tRm(insn))));
++OpIdx;
return true;
//
// Load/Store Register SP relative: tRt ARM::SP imm8
static bool DisassembleThumb1LdStSP(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert((Opcode == ARM::tLDRspi || Opcode == ARM::tSTRspi)
&& "Invalid opcode");
!OpInfo[2].isOptionalDef())
&& "Invalid arguments");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::tGPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
getT1tRt(insn))));
MI.addOperand(MCOperand::CreateReg(ARM::SP));
MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
//
// tADDrPCi: tRt imm8
static bool DisassembleThumb1AddPCi(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(Opcode == ARM::tADDrPCi && "Invalid opcode");
!OpInfo[1].isOptionalDef())
&& "Invalid arguments");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::tGPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
getT1tRt(insn))));
MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
NumOpsAdded = 2;
//
// tADDrSPi: tRt ARM::SP imm8
static bool DisassembleThumb1AddSPi(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(Opcode == ARM::tADDrSPi && "Invalid opcode");
!OpInfo[2].isOptionalDef())
&& "Invalid arguments");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::tGPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
getT1tRt(insn))));
MI.addOperand(MCOperand::CreateReg(ARM::SP));
MI.addOperand(MCOperand::CreateImm(getT1Imm8(insn)));
// "low registers" is specified by Inst{7-0}
// lr|pc is specified by Inst{8}
static bool DisassembleThumb1PushPop(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert((Opcode == ARM::tPUSH || Opcode == ARM::tPOP) && "Invalid opcode");
| slice(insn, 7, 0);
for (unsigned i = 0; i < 16; ++i) {
if ((RegListBits >> i) & 1) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
i)));
++OpIdx;
}
// no operand
// Others: tRd tRn
static bool DisassembleThumb1Misc(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
if (NumOps == 0)
return true;
if (Opcode == ARM::tPUSH || Opcode == ARM::tPOP)
- return DisassembleThumb1PushPop(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb1PushPop(MI, Opcode, insn, NumOps, NumOpsAdded, B);
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
&& "Expect >=2 operands");
// Add the destination operand.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::tGPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
getT1tRd(insn))));
if (OpInfo[1].RegClass == ARM::tGPRRegClassID) {
// Two register instructions.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::tGPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
getT1tRn(insn))));
} else {
// CBNZ, CBZ
// tLDM_UPD/tSTM_UPD: tRt tRt AM4ModeImm Pred-Imm Pred-CCR register_list
// tLDM: tRt AM4ModeImm Pred-Imm Pred-CCR register_list
static bool DisassembleThumb1LdStMul(bool Ld, MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded) {
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert((Opcode == ARM::tLDM || Opcode == ARM::tLDM_UPD ||
Opcode == ARM::tSTM_UPD) && "Invalid opcode");
// WB register, if necessary.
if (Opcode == ARM::tLDM_UPD || Opcode == ARM::tSTM_UPD) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
tRt)));
++OpIdx;
}
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
tRt)));
++OpIdx;
// Fill the variadic part of reglist.
for (unsigned i = 0; i < 8; ++i) {
if ((RegListBits >> i) & 1) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::tGPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::tGPRRegClassID,
i)));
++OpIdx;
}
}
static bool DisassembleThumb1LdMul(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
- return DisassembleThumb1LdStMul(true, MI, Opcode, insn, NumOps, NumOpsAdded);
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
+ return DisassembleThumb1LdStMul(true, MI, Opcode, insn, NumOps, NumOpsAdded,
+ B);
}
static bool DisassembleThumb1StMul(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
- return DisassembleThumb1LdStMul(false, MI, Opcode, insn, NumOps, NumOpsAdded);
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
+ return DisassembleThumb1LdStMul(false, MI, Opcode, insn, NumOps, NumOpsAdded,
+ B);
}
// A8.6.16 B Encoding T1
// tSVC: imm8 Pred-Imm Pred-CCR
// tTRAP: 0 operand (early return)
static bool DisassembleThumb1CondBr(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO) {
if (Opcode == ARM::tTRAP)
return true;
//
// tB: offset
static bool DisassembleThumb1Br(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
if (!OpInfo) return false;
// 1101xx Conditional branch, and Supervisor Call on page A6-13
// 11100x Unconditional Branch, see B on page A8-44
//
-static bool DisassembleThumb1(uint16_t op,
- MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded, BO Builder) {
+static bool DisassembleThumb1(uint16_t op, MCInst &MI, unsigned Opcode,
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
unsigned op1 = slice(op, 5, 4);
unsigned op2 = slice(op, 3, 2);
switch (op1) {
case 0:
// A6.2.1 Shift (immediate), add, subtract, move, and compare
- return DisassembleThumb1General(MI, Opcode, insn, NumOps, NumOpsAdded,
- Builder);
+ return DisassembleThumb1General(MI, Opcode, insn, NumOps, NumOpsAdded, B);
case 1:
switch (op2) {
case 0:
switch (op3) {
case 0:
// A6.2.2 Data-processing
- return DisassembleThumb1DP(MI, Opcode, insn, NumOps, NumOpsAdded,
- Builder);
+ return DisassembleThumb1DP(MI, Opcode, insn, NumOps, NumOpsAdded, B);
case 1:
// A6.2.3 Special data instructions and branch and exchange
- return DisassembleThumb1Special(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb1Special(MI, Opcode, insn, NumOps, NumOpsAdded,
+ B);
default:
// A8.6.59 LDR (literal)
- return DisassembleThumb1LdPC(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb1LdPC(MI, Opcode, insn, NumOps, NumOpsAdded, B);
}
break;
default:
// A6.2.4 Load/store single data item
- return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded,
+ B);
break;
}
break;
switch (op2) {
case 0:
// A6.2.4 Load/store single data item
- return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb1LdSt(opA, MI, Opcode, insn, NumOps, NumOpsAdded,
+ B);
case 1:
// A6.2.4 Load/store single data item
- return DisassembleThumb1LdStSP(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb1LdStSP(MI, Opcode, insn, NumOps, NumOpsAdded, B);
case 2:
if (op3 <= 1) {
// A8.6.10 ADR
- return DisassembleThumb1AddPCi(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb1AddPCi(MI, Opcode, insn, NumOps, NumOpsAdded,
+ B);
} else {
// A8.6.8 ADD (SP plus immediate)
- return DisassembleThumb1AddSPi(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb1AddSPi(MI, Opcode, insn, NumOps, NumOpsAdded,
+ B);
}
default:
// A6.2.5 Miscellaneous 16-bit instructions
- return DisassembleThumb1Misc(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb1Misc(MI, Opcode, insn, NumOps, NumOpsAdded, B);
}
break;
case 3:
case 0:
if (op3 <= 1) {
// A8.6.189 STM / STMIA / STMEA
- return DisassembleThumb1StMul(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb1StMul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
} else {
// A8.6.53 LDM / LDMIA / LDMFD
- return DisassembleThumb1LdMul(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb1LdMul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
}
case 1:
// A6.2.6 Conditional branch, and Supervisor Call
- return DisassembleThumb1CondBr(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb1CondBr(MI, Opcode, insn, NumOps, NumOpsAdded, B);
case 2:
// Unconditional Branch, see B on page A8-44
- return DisassembleThumb1Br(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb1Br(MI, Opcode, insn, NumOps, NumOpsAdded, B);
default:
assert(0 && "Unreachable code");
break;
// t2RFE[IA|DB]W/t2RFE[IA|DB]: Rn
static bool DisassembleThumb2RFE(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
NumOpsAdded = 1;
return true;
}
static bool DisassembleThumb2LdStMul(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
if (Thumb2SRSOpcode(Opcode))
return DisassembleThumb2SRS(MI, Opcode, insn, NumOps, NumOpsAdded);
if (Thumb2RFEOpcode(Opcode))
- return DisassembleThumb2RFE(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2RFE(MI, Opcode, insn, NumOps, NumOpsAdded, B);
assert((Opcode == ARM::t2LDM || Opcode == ARM::t2LDM_UPD ||
Opcode == ARM::t2STM || Opcode == ARM::t2STM_UPD)
OpIdx = 0;
- unsigned Base = getRegisterEnum(ARM::GPRRegClassID, decodeRn(insn));
+ unsigned Base = getRegisterEnum(B, ARM::GPRRegClassID, decodeRn(insn));
// Writeback to base.
if (Opcode == ARM::t2LDM_UPD || Opcode == ARM::t2STM_UPD) {
unsigned RegListBits = insn & ((1 << 16) - 1);
for (unsigned i = 0; i < 16; ++i) {
if ((RegListBits >> i) & 1) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
i)));
++OpIdx;
}
// t2STREXD: Rm Rd Rs Rn
// t2STREXB, t2STREXH: Rm Rd Rn
static bool DisassembleThumb2LdStEx(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
if (!OpInfo) return false;
// Add the destination operand for store.
if (isStore) {
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(ARM::GPRRegClassID,
+ getRegisterEnum(B, ARM::GPRRegClassID,
isSW ? decodeRs(insn) : decodeRm(insn))));
++OpIdx;
}
// Source operand for store and destination operand for load.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
++OpIdx;
// Thumb2 doubleword complication: with an extra source/destination operand.
if (isDW) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRs(insn))));
++OpIdx;
}
// Finally add the pointer operand.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
// Ditto for t2LDRD_PRE, t2LDRD_POST, t2STRD_PRE, t2STRD_POST, which are for
// disassembly only and do not have a tied_to writeback base register operand.
static bool DisassembleThumb2LdStDual(MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded) {
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
if (!OpInfo) return false;
&& "Expect >= 4 operands and first 3 as reg operands");
// Add the <Rt> <Rt2> operands.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRs(insn))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
// Finally add (+/-)imm8*4, depending on the U bit.
//
// t2TBBgen, t2TBHgen: Rn Rm Pred-Imm Pred-CCR
static bool DisassembleThumb2TB(MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded) {
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
assert(NumOps >= 2 && "Expect >= 2 operands");
// The generic version of TBB/TBH needs a base register.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
// Add the index register.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
NumOpsAdded = 2;
// nothing else, because the shift amount is already specified.
// Similar case holds for t2MOVrx, t2ADDrr, ..., etc.
static bool DisassembleThumb2DPSoReg(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
const TargetOperandInfo *OpInfo = TID.OpInfo;
&& OpInfo[3].RegClass == 0
&& "Exactlt 4 operands expect and first two as reg operands");
// Only need to populate the src reg operand.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
MI.addOperand(MCOperand::CreateReg(0));
MI.addOperand(MCOperand::CreateImm(0));
// Build the register operands, followed by the constant shift specifier.
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(ARM::GPRRegClassID,
+ getRegisterEnum(B, ARM::GPRRegClassID,
NoDstReg ? decodeRn(insn) : decodeRs(insn))));
++OpIdx;
MI.addOperand(MI.getOperand(Idx));
} else {
assert(!NoDstReg && "Internal error");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
}
++OpIdx;
}
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
++OpIdx;
//
// ModImm = ThumbExpandImm(i:imm3:imm8)
static bool DisassembleThumb2DPModImm(MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded) {
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
unsigned &OpIdx = NumOpsAdded;
// Build the register operands, followed by the modified immediate.
MI.addOperand(MCOperand::CreateReg(
- getRegisterEnum(ARM::GPRRegClassID,
+ getRegisterEnum(B, ARM::GPRRegClassID,
NoDstReg ? decodeRn(insn) : decodeRs(insn))));
++OpIdx;
if (TwoReg) {
assert(!NoDstReg && "Internal error");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
}
// 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) {
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
const TargetOperandInfo *OpInfo = TID.OpInfo;
// Build the register operand(s), followed by the immediate(s).
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRs(insn))));
++OpIdx;
if (Thumb2SaturateOpcode(Opcode)) {
MI.addOperand(MCOperand::CreateImm(decodeThumb2SaturatePos(Opcode, insn)));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
if (Opcode == ARM::t2SSAT16 || Opcode == ARM::t2USAT16) {
MI.addOperand(MI.getOperand(Idx));
} else {
// Add src reg operand.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
}
++OpIdx;
// t2MSR/t2MSRsys -> Rn mask=Inst{11-8}
// t2SMC -> imm4 = Inst{19-16}
static bool DisassembleThumb2BrMiscCtrl(MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded) {
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
if (NumOps == 0)
return true;
// MRS and MRSsys take one GPR reg Rs.
if (Opcode == ARM::t2MRS || Opcode == ARM::t2MRSsys) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRs(insn))));
NumOpsAdded = 1;
return true;
}
// BXJ takes one GPR reg Rn.
if (Opcode == ARM::t2BXJ) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
NumOpsAdded = 1;
return true;
}
// MSR and MSRsys take one GPR reg Rn, followed by the mask.
if (Opcode == ARM::t2MSR || Opcode == ARM::t2MSRsys || Opcode == ARM::t2BXJ) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
MI.addOperand(MCOperand::CreateImm(slice(insn, 11, 8)));
NumOpsAdded = 2;
}
static bool DisassembleThumb2PreLoad(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
// Preload Data/Instruction requires either 2 or 3 operands.
// t2PLDi12, t2PLDi8, t2PLDpci: Rn [+/-]imm12/imm8
OpInfo[0].RegClass == ARM::GPRRegClassID &&
"Expect >= 2 operands and first one as reg operand");
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
if (OpInfo[OpIdx].RegClass == ARM::GPRRegClassID) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
} else {
assert(OpInfo[OpIdx].RegClass == 0 && !OpInfo[OpIdx].isPredicate()
// These instrs calculate an address from the PC value and an immediate offset.
// Rd Rn=PC (+/-)imm12 (+ if Inst{23} == 0b1)
static bool DisassembleThumb2Ldpci(MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded) {
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
if (!OpInfo) return false;
// Build the register operand, followed by the (+/-)imm12 immediate.
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
MI.addOperand(MCOperand::CreateImm(decodeImm12(insn)));
// Delegates to DisassembleThumb2PreLoad() for preload data/instruction.
// Delegates to DisassembleThumb2Ldpci() for load * literal operations.
static bool DisassembleThumb2LdSt(bool Load, MCInst &MI, unsigned Opcode,
- uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded) {
+ uint32_t insn, unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
unsigned Rn = decodeRn(insn);
if (Thumb2PreloadOpcode(Opcode))
- return DisassembleThumb2PreLoad(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2PreLoad(MI, Opcode, insn, NumOps, NumOpsAdded, B);
// See, for example, A6.3.7 Load word: Table A6-18 Load word.
if (Load && Rn == 15)
- return DisassembleThumb2Ldpci(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2Ldpci(MI, Opcode, insn, NumOps, NumOpsAdded, B);
const TargetInstrDesc &TID = ARMInsts[Opcode];
const TargetOperandInfo *OpInfo = TID.OpInfo;
Imm = decodeImm8(insn);
}
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID, R0)));
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+ R0)));
++OpIdx;
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID, R1)));
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+ R1)));
++OpIdx;
if (ThreeReg) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,R2)));
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
+ R2)));
++OpIdx;
}
//
// Miscellaneous operations: Rs [Rn] Rm
static bool DisassembleThumb2DPReg(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetInstrDesc &TID = ARMInsts[Opcode];
const TargetOperandInfo *OpInfo = TID.OpInfo;
bool ThreeReg = NumOps > 2 && OpInfo[2].RegClass == ARM::GPRRegClassID;
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRs(insn))));
++OpIdx;
if (ThreeReg) {
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
++OpIdx;
}
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
++OpIdx;
// Unsigned Sum of Absolute Differences [and Accumulate]
// Rs Rn Rm [Ra=Inst{15-12}]
static bool DisassembleThumb2Mul(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
bool FourReg = NumOps > 3 && OpInfo[3].RegClass == ARM::GPRRegClassID;
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRs(insn))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
if (FourReg)
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
NumOpsAdded = FourReg ? 4 : 3;
//
// Signed/Unsigned divide: t2SDIV, t2UDIV: Rs Rn Rm
static bool DisassembleThumb2LongMul(MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ unsigned short NumOps, unsigned &NumOpsAdded, BO B) {
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
// Build the register operands.
if (FourReg)
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRd(insn))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRs(insn))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRn(insn))));
- MI.addOperand(MCOperand::CreateReg(getRegisterEnum(ARM::GPRRegClassID,
+ MI.addOperand(MCOperand::CreateReg(getRegisterEnum(B, ARM::GPRRegClassID,
decodeRm(insn))));
if (FourReg)
// 1xxxxxx - Coprocessor instructions on page A6-40
//
static bool DisassembleThumb2(uint16_t op1, uint16_t op2, uint16_t op,
- MCInst &MI, unsigned Opcode, uint32_t insn,
- unsigned short NumOps, unsigned &NumOpsAdded) {
+ MCInst &MI, unsigned Opcode, uint32_t insn, unsigned short NumOps,
+ unsigned &NumOpsAdded, BO B) {
switch (op1) {
case 1:
if (slice(op2, 6, 5) == 0) {
if (slice(op2, 2, 2) == 0) {
// Load/store multiple.
- return DisassembleThumb2LdStMul(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2LdStMul(MI, Opcode, insn, NumOps, NumOpsAdded,
+ B);
}
// Load/store dual, load/store exclusive, table branch, otherwise.
if ((ARM::t2LDREX <= Opcode && Opcode <= ARM::t2LDREXH) ||
(ARM::t2STREX <= Opcode && Opcode <= ARM::t2STREXH)) {
// Load/store exclusive.
- return DisassembleThumb2LdStEx(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2LdStEx(MI, Opcode, insn, NumOps, NumOpsAdded,
+ B);
}
if (Opcode == ARM::t2LDRDi8 ||
Opcode == ARM::t2LDRD_PRE || Opcode == ARM::t2LDRD_POST ||
Opcode == ARM::t2STRDi8 ||
Opcode == ARM::t2STRD_PRE || Opcode == ARM::t2STRD_POST) {
// Load/store dual.
- return DisassembleThumb2LdStDual(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2LdStDual(MI, Opcode, insn, NumOps, NumOpsAdded,
+ B);
}
if (Opcode == ARM::t2TBBgen || Opcode == ARM::t2TBHgen) {
// Table branch.
- return DisassembleThumb2TB(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2TB(MI, Opcode, insn, NumOps, NumOpsAdded, B);
}
} else if (slice(op2, 6, 5) == 1) {
// Data-processing (shifted register).
- return DisassembleThumb2DPSoReg(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2DPSoReg(MI, Opcode, insn, NumOps, NumOpsAdded, B);
}
// FIXME: A6.3.18 Coprocessor instructions
if (op == 0) {
if (slice(op2, 5, 5) == 0) {
// Data-processing (modified immediate)
- return DisassembleThumb2DPModImm(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2DPModImm(MI, Opcode, insn, NumOps, NumOpsAdded,
+ B);
} else {
// Data-processing (plain binary immediate)
- return DisassembleThumb2DPBinImm(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2DPBinImm(MI, Opcode, insn, NumOps, NumOpsAdded,
+ B);
}
} else {
// Branches and miscellaneous control on page A6-20.
- return DisassembleThumb2BrMiscCtrl(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2BrMiscCtrl(MI, Opcode, insn, NumOps, NumOpsAdded,
+ B);
}
break;
if (slice(op2, 0, 0) == 0) {
if (slice(op2, 4, 4) == 0) {
// Store single data item on page A6-30
- return DisassembleThumb2LdSt(false, MI,Opcode,insn,NumOps,NumOpsAdded);
+ return DisassembleThumb2LdSt(false, MI,Opcode,insn,NumOps,NumOpsAdded,
+ B);
} else {
// FIXME: Advanced SIMD element or structure load/store instructions.
// But see ThumbDisassembler::getInstruction().
}
} else {
// Table A6-9 32-bit Thumb instruction encoding: Load byte|halfword|word
- return DisassembleThumb2LdSt(true, MI,Opcode,insn,NumOps,NumOpsAdded);
+ return DisassembleThumb2LdSt(true, MI,Opcode,insn,NumOps,NumOpsAdded, B);
}
break;
case 1:
if (slice(op2, 4, 4) == 0) {
// A6.3.12 Data-processing (register)
- return DisassembleThumb2DPReg(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2DPReg(MI, Opcode, insn, NumOps, NumOpsAdded, B);
} else if (slice(op2, 3, 3) == 0) {
// A6.3.16 Multiply, multiply accumulate, and absolute difference
- return DisassembleThumb2Mul(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2Mul(MI, Opcode, insn, NumOps, NumOpsAdded, B);
} else {
// A6.3.17 Long multiply, long multiply accumulate, and divide
- return DisassembleThumb2LongMul(MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2LongMul(MI, Opcode, insn, NumOps, NumOpsAdded,
+ B);
}
break;
default:
uint16_t op2 = slice(HalfWord, 10, 4);
uint16_t op = slice(insn, 15, 15);
- return DisassembleThumb2(op1, op2, op, MI, Opcode, insn, NumOps, NumOpsAdded);
+ return DisassembleThumb2(op1, op2, op, MI, Opcode, insn, NumOps, NumOpsAdded,
+ Builder);
}