Thumb2 parsing for push/pop w/ hi registers in the reglist.

rdar://10130228.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@144331 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2011-11-10 23:17:11 +00:00
parent fae02597bb
commit 5402637ff2
2 changed files with 47 additions and 2 deletions

View File

@ -4526,16 +4526,21 @@ validateInstruction(MCInst &Inst,
"in register list"); "in register list");
break; break;
} }
// Like for ldm/stm, push and pop have hi-reg handling version in Thumb2,
// so only issue a diagnostic for thumb1. The instructions will be
// switched to the t2 encodings in processInstruction() if necessary.
case ARM::tPOP: { case ARM::tPOP: {
bool listContainsBase; bool listContainsBase;
if (checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase)) if (checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase) &&
!isThumbTwo())
return Error(Operands[2]->getStartLoc(), return Error(Operands[2]->getStartLoc(),
"registers must be in range r0-r7 or pc"); "registers must be in range r0-r7 or pc");
break; break;
} }
case ARM::tPUSH: { case ARM::tPUSH: {
bool listContainsBase; bool listContainsBase;
if (checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase)) if (checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase) &&
!isThumbTwo())
return Error(Operands[2]->getStartLoc(), return Error(Operands[2]->getStartLoc(),
"registers must be in range r0-r7 or lr"); "registers must be in range r0-r7 or lr");
break; break;
@ -4691,6 +4696,31 @@ processInstruction(MCInst &Inst,
} }
break; break;
} }
case ARM::tPOP: {
bool listContainsBase;
// If the register list contains any high registers, we need to use
// the 32-bit encoding instead if we're in Thumb2. Otherwise, this
// should have generated an error in validateInstruction().
if (!checkLowRegisterList(Inst, 2, 0, ARM::PC, listContainsBase))
return;
assert (isThumbTwo());
Inst.setOpcode(ARM::t2LDMIA_UPD);
// Add the base register and writeback operands.
Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
break;
}
case ARM::tPUSH: {
bool listContainsBase;
if (!checkLowRegisterList(Inst, 2, 0, ARM::LR, listContainsBase))
return;
assert (isThumbTwo());
Inst.setOpcode(ARM::t2STMDB_UPD);
// Add the base register and writeback operands.
Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
Inst.insert(Inst.begin(), MCOperand::CreateReg(ARM::SP));
break;
}
case ARM::t2MOVi: { case ARM::t2MOVi: {
// If we can use the 16-bit encoding and the user didn't explicitly // If we can use the 16-bit encoding and the user didn't explicitly
// request the 32-bit variant, transform it here. // request the 32-bit variant, transform it here.

View File

@ -1436,6 +1436,21 @@ _func:
@ CHECK: pli [sp, r2, lsl #1] @ encoding: [0x1d,0xf9,0x12,0xf0] @ CHECK: pli [sp, r2, lsl #1] @ encoding: [0x1d,0xf9,0x12,0xf0]
@ CHECK: pli [sp, r2] @ encoding: [0x1d,0xf9,0x02,0xf0] @ CHECK: pli [sp, r2] @ encoding: [0x1d,0xf9,0x02,0xf0]
@------------------------------------------------------------------------------
@ POP (alias)
@------------------------------------------------------------------------------
pop {r2, r9}
@ CHECK: pop.w {r2, r9} @ encoding: [0xbd,0xe8,0x04,0x02]
@------------------------------------------------------------------------------
@ PUSH (alias)
@------------------------------------------------------------------------------
push {r2, r9}
@ CHECK: push.w {r2, r9} @ encoding: [0x2d,0xe9,0x04,0x02]
@------------------------------------------------------------------------------ @------------------------------------------------------------------------------
@ QADD/QADD16/QADD8 @ QADD/QADD16/QADD8