forked from OSchip/llvm-project
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
This commit is contained in:
parent
31a01ee3cb
commit
8b6a9c1574
|
@ -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)
|
||||
|
|
|
@ -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]>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue