From 8b6a9c157453b220a9988d3d78653f0fe36e9e55 Mon Sep 17 00:00:00 2001 From: Jim Grosbach Date: Thu, 14 Oct 2010 22:57:13 +0000 Subject: [PATCH] Refactor the MOVsr[al]_flag and RRX pseudo-instructions to really be pseudos and let the ARMExpandPseudoInsts pass fix them up into the real (MOVs) instruction form. llvm-svn: 116534 --- llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp | 29 ++++++++++++++++++++ llvm/lib/Target/ARM/ARMInstrInfo.td | 18 ++++++------ llvm/test/CodeGen/ARM/long_shift.ll | 2 +- 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp index 6755487b4413..5dceeb1967f8 100644 --- a/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp +++ b/llvm/lib/Target/ARM/ARMExpandPseudoInsts.cpp @@ -16,6 +16,7 @@ #define DEBUG_TYPE "arm-pseudo" #include "ARM.h" +#include "ARMAddressingModes.h" #include "ARMBaseInstrInfo.h" #include "ARMRegisterInfo.h" #include "llvm/CodeGen/MachineFunctionPass.h" @@ -575,6 +576,34 @@ bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) { ModifiedOp = false; break; + case ARM::MOVsrl_flag: + case ARM::MOVsra_flag: { + // These are just fancy MOVs insructions. + MachineInstrBuilder MIB = + AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVs), + MI.getOperand(0).getReg()) + .addOperand(MI.getOperand(1)) + .addReg(0) + .addImm(ARM_AM::getSORegOpc((Opcode == ARM::MOVsrl_flag ? ARM_AM::lsr + : ARM_AM::asr), 1))) + .addReg(ARM::CPSR); + TransferImpOps(MI, MIB, MIB); + MI.eraseFromParent(); + break; + } + case ARM::RRX: { + // This encodes as "MOVs Rd, Rm, rrx + MachineInstrBuilder MIB = + AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVs), + MI.getOperand(0).getReg()) + .addOperand(MI.getOperand(1)) + .addOperand(MI.getOperand(1)) + .addImm(ARM_AM::getSORegOpc(ARM_AM::rrx, 0))) + .addReg(0); + TransferImpOps(MI, MIB, MIB); + MI.eraseFromParent(); + break; + } case ARM::tLDRpci_pic: case ARM::t2LDRpci_pic: { unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic) diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.td b/llvm/lib/Target/ARM/ARMInstrInfo.td index 5a2070d8c89e..1b6d3e0f8069 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.td +++ b/llvm/lib/Target/ARM/ARMInstrInfo.td @@ -1686,20 +1686,20 @@ def : ARMPat<(or GPR:$src, 0xffff0000), (MOVTi16 GPR:$src, 0xffff)>, Requires<[IsARM, HasV6T2]>; let Uses = [CPSR] in -def RRX: AsI1<0b1101, (outs GPR:$Rd), (ins GPR:$Rm), Pseudo, IIC_iMOVsi, - "rrx", "\t$Rd, $Rm", - [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP; +def RRX: PseudoInst<(outs GPR:$Rd), (ins GPR:$Rm), IIC_iMOVsi, "", + [(set GPR:$Rd, (ARMrrx GPR:$Rm))]>, UnaryDP, + Requires<[IsARM]>; // These aren't really mov instructions, but we have to define them this way // due to flag operands. let Defs = [CPSR] in { -def MOVsrl_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, - IIC_iMOVsi, "movs", "\t$dst, $src, lsr #1", - [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP; -def MOVsra_flag : AI1<0b1101, (outs GPR:$dst), (ins GPR:$src), Pseudo, - IIC_iMOVsi, "movs", "\t$dst, $src, asr #1", - [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP; +def MOVsrl_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "", + [(set GPR:$dst, (ARMsrl_flag GPR:$src))]>, UnaryDP, + Requires<[IsARM]>; +def MOVsra_flag : PseudoInst<(outs GPR:$dst), (ins GPR:$src), IIC_iMOVsi, "", + [(set GPR:$dst, (ARMsra_flag GPR:$src))]>, UnaryDP, + Requires<[IsARM]>; } //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/ARM/long_shift.ll b/llvm/test/CodeGen/ARM/long_shift.ll index 4d2243a2aa33..5e4f5730f8d2 100644 --- a/llvm/test/CodeGen/ARM/long_shift.ll +++ b/llvm/test/CodeGen/ARM/long_shift.ll @@ -2,7 +2,7 @@ define i64 @f0(i64 %A, i64 %B) { ; CHECK: f0 -; CHECK: movs r3, r3, lsr #1 +; CHECK: lsrs r3, r3, #1 ; CHECK-NEXT: rrx r2, r2 ; CHECK-NEXT: subs r0, r0, r2 ; CHECK-NEXT: sbc r1, r1, r3