From 863d2af9477e331955a9bee8be1969ce658b59b5 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Tue, 13 Dec 2011 22:45:11 +0000 Subject: [PATCH] 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 --- lib/Target/ARM/ARMInstrThumb2.td | 7 ++++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 39 ++++++++++++++++++++++- test/MC/ARM/basic-thumb2-instructions.s | 12 +++++++ 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 6f9201c0e7f..c8ab59fc6f1 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -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)>; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index 745fa897725..b7db86acf07 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -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: diff --git a/test/MC/ARM/basic-thumb2-instructions.s b/test/MC/ARM/basic-thumb2-instructions.s index 9577ea6b05f..028e17bdc9a 100644 --- a/test/MC/ARM/basic-thumb2-instructions.s +++ b/test/MC/ARM/basic-thumb2-instructions.s @@ -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] @------------------------------------------------------------------------------ -- 2.34.1