mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-19 03:24:09 +00:00
Thumb instructions which have reglist operands at the end and predicate operands
before reglist were not properly handled with respect to IT Block. Fix that by creating a new method ARMBasicMCBuilder::DoPredicateOperands() used by those instructions for disassembly. Add a test case. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101974 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -3218,6 +3218,40 @@ static uint32_t CondCode(uint32_t CondField) {
|
||||
return CondField;
|
||||
}
|
||||
|
||||
/// DoPredicateOperands - DoPredicateOperands process the predicate operands
|
||||
/// of some Thumb instructions which come before the reglist operands. It
|
||||
/// returns true if the two predicate operands have been processed.
|
||||
bool ARMBasicMCBuilder::DoPredicateOperands(MCInst& MI, unsigned Opcode,
|
||||
uint32_t /* insn */, unsigned short NumOpsRemaining) {
|
||||
|
||||
assert(NumOpsRemaining > 0 && "Invalid argument");
|
||||
|
||||
const TargetOperandInfo *OpInfo = ARMInsts[Opcode].OpInfo;
|
||||
unsigned Idx = MI.getNumOperands();
|
||||
|
||||
// First, we check whether this instr specifies the PredicateOperand through
|
||||
// a pair of TargetOperandInfos with isPredicate() property.
|
||||
if (NumOpsRemaining >= 2 &&
|
||||
OpInfo[Idx].isPredicate() && OpInfo[Idx+1].isPredicate() &&
|
||||
OpInfo[Idx].RegClass == 0 && OpInfo[Idx+1].RegClass == ARM::CCRRegClassID)
|
||||
{
|
||||
// If we are inside an IT block, get the IT condition bits maintained via
|
||||
// ARMBasicMCBuilder::ITState[7:0], through ARMBasicMCBuilder::GetITCond().
|
||||
// See also A2.5.2.
|
||||
if (InITBlock())
|
||||
MI.addOperand(MCOperand::CreateImm(GetITCond()));
|
||||
else
|
||||
MI.addOperand(MCOperand::CreateImm(ARMCC::AL));
|
||||
MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// TryPredicateAndSBitModifier - TryPredicateAndSBitModifier tries to process
|
||||
/// the possible Predicate and SBitModifier, to build the remaining MCOperand
|
||||
/// constituents.
|
||||
bool ARMBasicMCBuilder::TryPredicateAndSBitModifier(MCInst& MI, unsigned Opcode,
|
||||
uint32_t insn, unsigned short NumOpsRemaining) {
|
||||
|
||||
@ -3258,10 +3292,11 @@ bool ARMBasicMCBuilder::TryPredicateAndSBitModifier(MCInst& MI, unsigned Opcode,
|
||||
MI.addOperand(MCOperand::CreateReg(ARM::CPSR));
|
||||
Idx += 2;
|
||||
NumOpsRemaining -= 2;
|
||||
if (NumOpsRemaining == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (NumOpsRemaining == 0)
|
||||
return true;
|
||||
|
||||
// Next, if OptionalDefOperand exists, we check whether the 'S' bit is set.
|
||||
if (OpInfo[Idx].isOptionalDef() && OpInfo[Idx].RegClass==ARM::CCRRegClassID) {
|
||||
MI.addOperand(MCOperand::CreateReg(getSBit(insn) == 1 ? ARM::CPSR : 0));
|
||||
|
Reference in New Issue
Block a user