Refactor the MOVsr[al]_flag and RRX pseudo-instructions to really be pseudos
authorJim Grosbach <grosbach@apple.com>
Thu, 14 Oct 2010 22:57:13 +0000 (22:57 +0000)
committerJim Grosbach <grosbach@apple.com>
Thu, 14 Oct 2010 22:57:13 +0000 (22:57 +0000)
and let the ARMExpandPseudoInsts pass fix them up into the real (MOVs)
instruction form.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@116534 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/ARM/ARMExpandPseudoInsts.cpp
lib/Target/ARM/ARMInstrInfo.td
test/CodeGen/ARM/long_shift.ll

index 6755487b441348feb92c393cc1a73f8068df7c33..5dceeb1967f88064c8ed0935a029d9ac0369c52f 100644 (file)
@@ -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)
index 5a2070d8c89ea6c5b0255a8347e120d8819a0890..1b6d3e0f806923b6a30bbddcca761980aeb2db42 100644 (file)
@@ -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]>;
 }
 
 //===----------------------------------------------------------------------===//
index 4d2243a2aa334ad3f2c633f1b2cbbff5070a64c4..5e4f5730f8d21ae38b44db3bc1324cf0fd8df3f5 100644 (file)
@@ -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