Thumb2 parsing and encoding of B instruction.

Tweak handling of IT blocks a bit to enable this. The differentiation between
B and Bcc needs special sauce.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@139049 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2011-09-02 23:22:08 +00:00
parent 7a15a9ad97
commit a110988b39
2 changed files with 32 additions and 9 deletions

View File

@ -64,6 +64,14 @@ class ARMAsmParser : public MCTargetAsmParser {
// ~0U if no active IT block.
} ITState;
bool inITBlock() { return ITState.CurPosition != ~0U;}
void forwardITPosition() {
if (!inITBlock()) return;
// Move to the next instruction in the IT block, if there is one. If not,
// mark the block as done.
unsigned TZ = CountTrailingZeros_32(ITState.Mask);
if (++ITState.CurPosition == 5 - TZ)
ITState.CurPosition = ~0U; // Done with the IT block after this.
}
MCAsmParser &getParser() const { return Parser; }
@ -3351,12 +3359,7 @@ validateInstruction(MCInst &Inst,
if (ITState.FirstCond)
ITState.FirstCond = false;
else
bit = (ITState.Mask >> (4 - ITState.CurPosition)) & 1;
// Increment our position in the IT block first thing, as we want to
// move forward even if we find an error in the IT block.
unsigned TZ = CountTrailingZeros_32(ITState.Mask);
if (++ITState.CurPosition == 4 - TZ)
ITState.CurPosition = ~0U; // Done with the IT block after this.
bit = (ITState.Mask >> (5 - ITState.CurPosition)) & 1;
// The instruction must be predicable.
if (!MCID.isPredicable())
return Error(Loc, "instructions in IT block must be predicable");
@ -3519,8 +3522,8 @@ processInstruction(MCInst &Inst,
Inst.setOpcode(ARM::tADDi3);
break;
case ARM::t2Bcc:
// If the conditional is AL, we really want t2B.
if (Inst.getOperand(1).getImm() == ARMCC::AL)
// If the conditional is AL or we're in an IT block, we really want t2B.
if (Inst.getOperand(1).getImm() == ARMCC::AL || inITBlock())
Inst.setOpcode(ARM::t2B);
break;
case ARM::tBcc:
@ -3614,13 +3617,22 @@ MatchAndEmitInstruction(SMLoc IDLoc,
case Match_Success:
// Context sensitive operand constraints aren't handled by the matcher,
// so check them here.
if (validateInstruction(Inst, Operands))
if (validateInstruction(Inst, Operands)) {
// Still progress the IT block, otherwise one wrong condition causes
// nasty cascading errors.
forwardITPosition();
return true;
}
// Some instructions need post-processing to, for example, tweak which
// encoding is selected.
processInstruction(Inst, Operands);
// Only move forward at the very end so that everything in validate
// and process gets a consistent answer about whether we're in an IT
// block.
forwardITPosition();
Out.EmitInstruction(Inst);
return false;
case Match_MissingFeature:

View File

@ -177,8 +177,19 @@ _func:
@------------------------------------------------------------------------------
@ B
@------------------------------------------------------------------------------
b.w _bar
beq.w _bar
it eq
beq.w _bar
bmi.w #-183396
@ CHECK: b.w _bar @ encoding: [A,0xf0'A',A,0x90'A']
@ fixup A - offset: 0, value: _bar, kind: fixup_t2_uncondbranch
@ CHECK: beq.w _bar @ encoding: [A,0xf0'A',A,0x80'A']
@ fixup A - offset: 0, value: _bar, kind: fixup_t2_condbranch
@ CHECK: it eq @ encoding: [0x08,0xbf]
@ CHECK: b.w _bar @ encoding: [A,0xf0'A',A,0x90'A']
@ fixup A - offset: 0, value: _bar, kind: fixup_t2_uncondbranch
@ CHECK: bmi.w #-183396 @ encoding: [0x13,0xf5,0xce,0xa9]
@------------------------------------------------------------------------------