Add specializations of addrmode2 that allow differentiating those forms
authorJim Grosbach <grosbach@apple.com>
Wed, 29 Sep 2010 19:03:54 +0000 (19:03 +0000)
committerJim Grosbach <grosbach@apple.com>
Wed, 29 Sep 2010 19:03:54 +0000 (19:03 +0000)
which require the use of the shifter-operand. This will be used to split
the ldr/str instructions such that those versions needing the shifter operand
can get a different scheduling itenerary, as in some cases, the use of the
shifter can cause different scheduling than the simpler forms.

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

lib/Target/ARM/ARMISelDAGToDAG.cpp
lib/Target/ARM/ARMInstrInfo.td

index 7bc7b4ae01bd4255814eba1158590a3d293408c8..d619564a4f2eb11b1ac0795a12f055db0c3d9840 100644 (file)
@@ -46,6 +46,12 @@ DisableShifterOp("disable-shifter-op", cl::Hidden,
 /// instructions for SelectionDAG operations.
 ///
 namespace {
+
+enum AddrMode2Type {
+  AM2_BASE, // Simple AM2 (+-imm12)
+  AM2_SHOP  // Shifter-op AM2
+};
+
 class ARMDAGToDAGISel : public SelectionDAGISel {
   ARMBaseTargetMachine &TM;
 
@@ -74,8 +80,25 @@ public:
 
   bool SelectShifterOperandReg(SDValue N, SDValue &A,
                                SDValue &B, SDValue &C);
-  bool SelectAddrMode2(SDValue N, SDValue &Base,
-                       SDValue &Offset, SDValue &Opc);
+  AddrMode2Type SelectAddrMode2Worker(SDValue N, SDValue &Base,
+                                      SDValue &Offset, SDValue &Opc);
+  bool SelectAddrMode2Base(SDValue N, SDValue &Base, SDValue &Offset,
+                           SDValue &Opc) {
+    return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_BASE;
+  }
+
+  bool SelectAddrMode2ShOp(SDValue N, SDValue &Base, SDValue &Offset,
+                           SDValue &Opc) {
+    return SelectAddrMode2Worker(N, Base, Offset, Opc) == AM2_SHOP;
+  }
+
+  bool SelectAddrMode2(SDValue N, SDValue &Base, SDValue &Offset,
+                       SDValue &Opc) {
+    SelectAddrMode2Worker(N, Base, Offset, Opc);
+    // This always matches one way or another.
+    return true;
+  }
+
   bool SelectAddrMode2Offset(SDNode *Op, SDValue N,
                              SDValue &Offset, SDValue &Opc);
   bool SelectAddrMode3(SDValue N, SDValue &Base,
@@ -245,9 +268,10 @@ bool ARMDAGToDAGISel::SelectShifterOperandReg(SDValue N,
   return true;
 }
 
-bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
-                                      SDValue &Base, SDValue &Offset,
-                                      SDValue &Opc) {
+AddrMode2Type ARMDAGToDAGISel::SelectAddrMode2Worker(SDValue N,
+                                                     SDValue &Base,
+                                                     SDValue &Offset,
+                                                     SDValue &Opc) {
   if (N.getOpcode() == ISD::MUL) {
     if (ConstantSDNode *RHS = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
       // X * [3,5,9] -> X + X * [2,4,8] etc.
@@ -265,7 +289,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
           Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt,
                                                             ARM_AM::lsl),
                                           MVT::i32);
-          return true;
+          return AM2_SHOP;
         }
       }
     }
@@ -285,7 +309,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
     Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(ARM_AM::add, 0,
                                                       ARM_AM::no_shift),
                                     MVT::i32);
-    return true;
+    return AM2_BASE;
   }
 
   // Match simple R +/- imm12 operands.
@@ -309,7 +333,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
         Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, RHSC,
                                                           ARM_AM::no_shift),
                                         MVT::i32);
-        return true;
+        return AM2_BASE;
       }
     }
   }
@@ -353,7 +377,7 @@ bool ARMDAGToDAGISel::SelectAddrMode2(SDValue N,
 
   Opc = CurDAG->getTargetConstant(ARM_AM::getAM2Opc(AddSub, ShAmt, ShOpcVal),
                                   MVT::i32);
-  return true;
+  return AM2_SHOP;
 }
 
 bool ARMDAGToDAGISel::SelectAddrMode2Offset(SDNode *Op, SDValue N,
index 4980d8b602cb554df3ed786f817f06c876f9b986..97ac233fe6cfcd9c53db9e3fb464f686f41c3ed9 100644 (file)
@@ -369,8 +369,22 @@ def imm0_31 : Operand<i32>, PatLeaf<(imm), [{
 
 // Define ARM specific addressing modes.
 
-// addrmode2 := reg +/- reg shop imm
-// addrmode2 := reg +/- imm12
+// addrmode2base := reg +/- imm12
+//
+def addrmode2base : Operand<i32>,
+                ComplexPattern<i32, 3, "SelectAddrMode2Base", []> {
+  let PrintMethod = "printAddrMode2Operand";
+  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
+}
+// addrmode2shop := reg +/- reg shop imm
+//
+def addrmode2shop : Operand<i32>,
+                ComplexPattern<i32, 3, "SelectAddrMode2ShOp", []> {
+  let PrintMethod = "printAddrMode2Operand";
+  let MIOperandInfo = (ops GPR:$base, GPR:$offsreg, i32imm:$offsimm);
+}
+
+// addrmode2 := (addrmode2base || addrmode2shop)
 //
 def addrmode2 : Operand<i32>,
                 ComplexPattern<i32, 3, "SelectAddrMode2", []> {