mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 04:33:05 +00:00
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:
parent
27debd60a1
commit
863d2af947
@ -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)>;
|
||||
|
@ -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:
|
||||
|
@ -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]
|
||||
|
||||
|
||||
@------------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user