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:
Johnny Chen
2010-04-21 01:01:19 +00:00
parent 08e322db8a
commit 52d2b0ed00
4 changed files with 73 additions and 16 deletions

View File

@ -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));