Thumb2 assembler aliases for "mov(shifted register)"

rdar://10549767


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@146520 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jim Grosbach 2011-12-13 22:45:11 +00:00
parent 27debd60a1
commit 863d2af947
3 changed files with 57 additions and 1 deletions

View File

@ -4126,3 +4126,10 @@ def : t2InstAlias<"mul${p} $Rn, $Rm",
// "neg" is and alias for "rsb rd, rn, #0"
def : t2InstAlias<"neg${s}${p} $Rd, $Rm",
(t2RSBri rGPR:$Rd, rGPR:$Rm, 0, pred:$p, cc_out:$s)>;
// MOV so_reg assembler pseudos. InstAlias isn't expressive enough for
// these, unfortunately.
def t2MOVsi: t2AsmPseudo<"mov${p} $Rd, $shift",
(ins rGPR:$Rd, t2_so_reg:$shift, pred:$p)>;
def t2MOVSsi: t2AsmPseudo<"movs${p} $Rd, $shift",
(ins rGPR:$Rd, t2_so_reg:$shift, pred:$p)>;

View File

@ -5248,7 +5248,44 @@ processInstruction(MCInst &Inst,
Inst = TmpInst;
return true;
}
// Handle the MOV complex aliases.
// Handle the Thumb2 mode MOV complex aliases.
case ARM::t2MOVsi:
case ARM::t2MOVSsi: {
// Which instruction to expand to depends on the CCOut operand and
// whether we're in an IT block if the register operands are low
// registers.
bool isNarrow = false;
if (isARMLowRegister(Inst.getOperand(0).getReg()) &&
isARMLowRegister(Inst.getOperand(1).getReg()) &&
inITBlock() == (Inst.getOpcode() == ARM::t2MOVsi))
isNarrow = true;
MCInst TmpInst;
unsigned newOpc;
switch(ARM_AM::getSORegShOp(Inst.getOperand(2).getImm())) {
default: llvm_unreachable("unexpected opcode!");
case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRri : ARM::t2ASRri; break;
case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRri : ARM::t2LSRri; break;
case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLri : ARM::t2LSLri; break;
case ARM_AM::ror: newOpc = ARM::t2RORri; isNarrow = false; break;
}
unsigned Ammount = ARM_AM::getSORegOffset(Inst.getOperand(2).getImm());
if (Ammount == 32) Ammount = 0;
TmpInst.setOpcode(newOpc);
TmpInst.addOperand(Inst.getOperand(0)); // Rd
if (isNarrow)
TmpInst.addOperand(MCOperand::CreateReg(
Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
TmpInst.addOperand(Inst.getOperand(1)); // Rn
TmpInst.addOperand(MCOperand::CreateImm(Ammount));
TmpInst.addOperand(Inst.getOperand(3)); // CondCode
TmpInst.addOperand(Inst.getOperand(4));
if (!isNarrow)
TmpInst.addOperand(MCOperand::CreateReg(
Inst.getOpcode() == ARM::t2MOVSsi ? ARM::CPSR : 0));
Inst = TmpInst;
return true;
}
// Handle the ARM mode MOV complex aliases.
case ARM::ASRr:
case ARM::LSRr:
case ARM::LSLr:

View File

@ -1147,6 +1147,18 @@ _func:
@ CHECK: mvn r3, #2 @ encoding: [0x6f,0xf0,0x02,0x03]
@------------------------------------------------------------------------------
@ MOV(shifted register)
@------------------------------------------------------------------------------
mov r6, r2, lsl #16
mov r6, r2, lsr #16
movs r6, r2, asr #32
movs r6, r2, ror #5
@ CHECK: lsl.w r6, r2, #16 @ encoding: [0x4f,0xea,0x02,0x46]
@ CHECK: lsr.w r6, r2, #16 @ encoding: [0x4f,0xea,0x12,0x46]
@ CHECK: asrs r6, r2, #32 @ encoding: [0x16,0x10]
@ CHECK: rors.w r6, r2, #5 @ encoding: [0x5f,0xea,0x72,0x16]
@------------------------------------------------------------------------------