From 2cc5cda464e7c936215281934193658cb799c603 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Wed, 21 Dec 2011 20:54:00 +0000 Subject: [PATCH] Thumb2 assembly parsing of 'mov(register shifted register)' aliases. These map to the ASR, LSR, LSL, ROR instruction definitions. rdar://10615373 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@147094 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/ARM/ARMInstrThumb2.td | 5 ++++ lib/Target/ARM/AsmParser/ARMAsmParser.cpp | 36 +++++++++++++++++++++++ test/MC/ARM/basic-thumb2-instructions.s | 25 ++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index b300ea518e0..10422ee111d 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -4141,6 +4141,11 @@ def t2MOVsi: t2AsmPseudo<"mov${p} $Rd, $shift", def t2MOVSsi: t2AsmPseudo<"movs${p} $Rd, $shift", (ins rGPR:$Rd, t2_so_reg:$shift, pred:$p)>; +def t2MOVsr: t2AsmPseudo<"mov${p} $Rd, $shift", + (ins rGPR:$Rd, so_reg_reg:$shift, pred:$p)>; +def t2MOVSsr: t2AsmPseudo<"movs${p} $Rd, $shift", + (ins rGPR:$Rd, so_reg_reg:$shift, pred:$p)>; + // ADR w/o the .w suffix def : t2InstAlias<"adr${p} $Rd, $addr", (t2ADR rGPR:$Rd, t2adrlabel:$addr, pred:$p)>; diff --git a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp index b6e0d1b35c5..ab954bea258 100644 --- a/lib/Target/ARM/AsmParser/ARMAsmParser.cpp +++ b/lib/Target/ARM/AsmParser/ARMAsmParser.cpp @@ -5748,6 +5748,42 @@ processInstruction(MCInst &Inst, return true; } // Handle the Thumb2 mode MOV complex aliases. + case ARM::t2MOVsr: + case ARM::t2MOVSsr: { + // 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()) && + isARMLowRegister(Inst.getOperand(2).getReg()) && + Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg() && + inITBlock() == (Inst.getOpcode() == ARM::t2MOVsr)) + isNarrow = true; + MCInst TmpInst; + unsigned newOpc; + switch(ARM_AM::getSORegShOp(Inst.getOperand(3).getImm())) { + default: llvm_unreachable("unexpected opcode!"); + case ARM_AM::asr: newOpc = isNarrow ? ARM::tASRrr : ARM::t2ASRrr; break; + case ARM_AM::lsr: newOpc = isNarrow ? ARM::tLSRrr : ARM::t2LSRrr; break; + case ARM_AM::lsl: newOpc = isNarrow ? ARM::tLSLrr : ARM::t2LSLrr; break; + case ARM_AM::ror: newOpc = isNarrow ? ARM::tROR : ARM::t2RORrr; break; + } + TmpInst.setOpcode(newOpc); + TmpInst.addOperand(Inst.getOperand(0)); // Rd + if (isNarrow) + TmpInst.addOperand(MCOperand::CreateReg( + Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0)); + TmpInst.addOperand(Inst.getOperand(1)); // Rn + TmpInst.addOperand(Inst.getOperand(2)); // Rm + TmpInst.addOperand(Inst.getOperand(4)); // CondCode + TmpInst.addOperand(Inst.getOperand(5)); + if (!isNarrow) + TmpInst.addOperand(MCOperand::CreateReg( + Inst.getOpcode() == ARM::t2MOVSsr ? ARM::CPSR : 0)); + Inst = TmpInst; + return true; + } case ARM::t2MOVsi: case ARM::t2MOVSsi: { // Which instruction to expand to depends on the CCOut operand and diff --git a/test/MC/ARM/basic-thumb2-instructions.s b/test/MC/ARM/basic-thumb2-instructions.s index be640f00692..9e5c4be89d5 100644 --- a/test/MC/ARM/basic-thumb2-instructions.s +++ b/test/MC/ARM/basic-thumb2-instructions.s @@ -1155,11 +1155,36 @@ _func: mov r6, r2, lsr #16 movs r6, r2, asr #32 movs r6, r2, ror #5 + movs r4, r4, lsl r5 + movs r4, r4, lsr r5 + movs r4, r4, asr r5 + movs r4, r4, ror r5 + mov r4, r4, lsl r5 + movs r4, r4, ror r8 + movs r4, r5, lsr r6 + itttt eq + moveq r4, r4, lsl r5 + moveq r4, r4, lsr r5 + moveq r4, r4, asr r5 + moveq r4, r4, ror r5 @ 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] +@ CHECK: lsls r4, r5 @ encoding: [0xac,0x40] +@ CHECK: lsrs r4, r5 @ encoding: [0xec,0x40] +@ CHECK: asrs r4, r5 @ encoding: [0x2c,0x41] +@ CHECK: rors r4, r5 @ encoding: [0xec,0x41] +@ CHECK: lsl.w r4, r4, r5 @ encoding: [0x04,0xfa,0x05,0xf4] +@ CHECK: rors.w r4, r4, r8 @ encoding: [0x74,0xfa,0x08,0xf4] +@ CHECK: lsrs.w r4, r5, r6 @ encoding: [0x35,0xfa,0x06,0xf4] +@ CHECK: itttt eq @ encoding: [0x01,0xbf] +@ CHECK: lsleq r4, r5 @ encoding: [0xac,0x40] +@ CHECK: lsreq r4, r5 @ encoding: [0xec,0x40] +@ CHECK: asreq r4, r5 @ encoding: [0x2c,0x41] +@ CHECK: roreq r4, r5 @ encoding: [0xec,0x41] + @------------------------------------------------------------------------------ -- 2.34.1