Write patterns for the various shl and srl patterns that don't involve
authorNate Begeman <natebegeman@mac.com>
Wed, 19 Oct 2005 18:42:01 +0000 (18:42 +0000)
committerNate Begeman <natebegeman@mac.com>
Wed, 19 Oct 2005 18:42:01 +0000 (18:42 +0000)
doing something clever.

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

lib/Target/PowerPC/PPCISelDAGToDAG.cpp
lib/Target/PowerPC/PPCInstrFormats.td
lib/Target/PowerPC/PPCInstrInfo.td

index 7cc92694cb32f82bab9303e0bac82eb51eb3e49e..430efd8275668f4ad5257e5877073b4afcd90118 100644 (file)
@@ -1214,51 +1214,28 @@ SDOperand PPCDAGToDAGISel::Select(SDOperand Op) {
   case ISD::SHL: {
     unsigned Imm, SH, MB, ME;
     if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
-        isRotateAndMask(N, Imm, true, SH, MB, ME))
+        isRotateAndMask(N, Imm, true, SH, MB, ME)) {
       CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, 
                            Select(N->getOperand(0).getOperand(0)),
                            getI32Imm(SH), getI32Imm(MB), getI32Imm(ME));
-    else if (isIntImmediate(N->getOperand(1), Imm)) {
-      if (N->getValueType(0) == MVT::i64)
-        CurDAG->SelectNodeTo(N, PPC::RLDICR, MVT::i64, Select(N->getOperand(0)),
-                             getI32Imm(Imm), getI32Imm(63-Imm));
-      else
-        CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)),
-                             getI32Imm(Imm), getI32Imm(0), getI32Imm(31-Imm));
-    } else {
-      if (N->getValueType(0) == MVT::i64)
-        CurDAG->SelectNodeTo(N, PPC::SLD, MVT::i64, Select(N->getOperand(0)),
-                             Select(N->getOperand(1)));
-      else
-        CurDAG->SelectNodeTo(N, PPC::SLW, MVT::i32, Select(N->getOperand(0)),
-                             Select(N->getOperand(1)));
+      return SDOperand(N, 0);
     }
-    return SDOperand(N, 0);
+    
+    // Other cases are autogenerated.
+    break;
   }
   case ISD::SRL: {
     unsigned Imm, SH, MB, ME;
     if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) &&
-        isRotateAndMask(N, Imm, true, SH, MB, ME))
+        isRotateAndMask(N, Imm, true, SH, MB, ME)) { 
       CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, 
                            Select(N->getOperand(0).getOperand(0)),
                            getI32Imm(SH & 0x1F), getI32Imm(MB), getI32Imm(ME));
-    else if (isIntImmediate(N->getOperand(1), Imm)) {
-      if (N->getValueType(0) == MVT::i64)
-        CurDAG->SelectNodeTo(N, PPC::RLDICL, MVT::i64, Select(N->getOperand(0)),
-                             getI32Imm(64-Imm), getI32Imm(Imm));
-      else
-        CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)),
-                             getI32Imm((32-Imm) & 0x1F), getI32Imm(Imm),
-                             getI32Imm(31));
-    } else {
-      if (N->getValueType(0) == MVT::i64)
-        CurDAG->SelectNodeTo(N, PPC::SRD, MVT::i64, Select(N->getOperand(0)),
-                             Select(N->getOperand(1)));
-      else
-        CurDAG->SelectNodeTo(N, PPC::SRW, MVT::i32, Select(N->getOperand(0)),
-                             Select(N->getOperand(1)));
+      return SDOperand(N, 0);
     }
-    return SDOperand(N, 0);
+    
+    // Other cases are autogenerated.
+    break;
   }
   case ISD::FNEG: {
     SDOperand Val = Select(N->getOperand(0));
index 880a66a99e296008abdade40c52efa67b89011c0..061311feaf28fd6290bec5f55eb8535312e8cfa8 100644 (file)
@@ -468,13 +468,16 @@ class AForm_3<bits<6> opcode, bits<5> xo, dag OL, string asmstr, list<dag> pat>
 }
 
 // 1.7.13 M-Form
-class MForm_1<bits<6> opcode, dag OL, string asmstr> : I<opcode, OL, asmstr> {
+class MForm_1<bits<6> opcode, dag OL, string asmstr, list<dag> pattern> 
+  : I<opcode, OL, asmstr> {
   bits<5> RA;
   bits<5> RS;
   bits<5> RB;
   bits<5> MB;
   bits<5> ME;
 
+  let Pattern = pattern;
+
   bit RC = 0;    // set by isDOT
 
   let Inst{6-10}  = RS;
@@ -485,18 +488,21 @@ class MForm_1<bits<6> opcode, dag OL, string asmstr> : I<opcode, OL, asmstr> {
   let Inst{31}    = RC;
 }
 
-class MForm_2<bits<6> opcode, dag OL, string asmstr>
-  : MForm_1<opcode, OL, asmstr> {
+class MForm_2<bits<6> opcode, dag OL, string asmstr, list<dag> pattern>
+  : MForm_1<opcode, OL, asmstr, pattern> {
 }
 
 // 1.7.14 MD-Form
-class MDForm_1<bits<6> opcode, bits<3> xo, dag OL, string asmstr>
+class MDForm_1<bits<6> opcode, bits<3> xo, dag OL, string asmstr, 
+               list<dag> pattern>
          : I<opcode, OL, asmstr> {
   bits<5> RS;
   bits<5> RA;
   bits<6> SH;
   bits<6> MBE;
 
+  let Pattern = pattern;
+
   bit RC = 0;    // set by isDOT
 
   let Inst{6-10}  = RS;
index e9a55b5be23a8e0e6dce2e906f5009045ed0ada8..6e7408fcb220e274f9907a573a3a3dd33e473b69 100644 (file)
@@ -19,6 +19,26 @@ include "PPCInstrFormats.td"
 // PowerPC specific transformation functions and pattern fragments.
 //
 
+def SHL32 : SDNodeXForm<imm, [{
+  // Transformation function: 31 - imm
+  return getI32Imm(31 - N->getValue());
+}]>;
+
+def SHL64 : SDNodeXForm<imm, [{
+  // Transformation function: 63 - imm
+  return getI32Imm(63 - N->getValue());
+}]>;
+
+def SRL32 : SDNodeXForm<imm, [{
+  // Transformation function: 32 - imm
+  return N->getValue() ? getI32Imm(32 - N->getValue()) : getI32Imm(0);
+}]>;
+
+def SRL64 : SDNodeXForm<imm, [{
+  // Transformation function: 64 - imm
+  return N->getValue() ? getI32Imm(64 - N->getValue()) : getI32Imm(0);
+}]>;
+
 def LO16 : SDNodeXForm<imm, [{
   // Transformation function: get the low 16 bits.
   return getI32Imm((unsigned short)N->getValue());
@@ -354,21 +374,21 @@ def EQV  : XForm_6<31, 284, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
 def XOR  : XForm_6<31, 316, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
                    "xor $rA, $rS, $rB",
                    [(set GPRC:$rA, (xor GPRC:$rS, GPRC:$rB))]>;                   
-def SLD  : XForm_6<31,  27, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
+def SLD  : XForm_6<31,  27, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
                    "sld $rA, $rS, $rB",
-                   []>, isPPC64;
+                   [(set G8RC:$rA, (shl G8RC:$rS, G8RC:$rB))]>, isPPC64;
 def SLW  : XForm_6<31,  24, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
                    "slw $rA, $rS, $rB",
                    [(set GPRC:$rA, (shl GPRC:$rS, GPRC:$rB))]>;
-def SRD  : XForm_6<31, 539, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
+def SRD  : XForm_6<31, 539, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
                    "srd $rA, $rS, $rB",
-                   []>, isPPC64;
+                   [(set G8RC:$rA, (srl G8RC:$rS, G8RC:$rB))]>, isPPC64;
 def SRW  : XForm_6<31, 536, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
                    "srw $rA, $rS, $rB",
                    [(set GPRC:$rA, (srl GPRC:$rS, GPRC:$rB))]>;
-def SRAD : XForm_6<31, 794, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
+def SRAD : XForm_6<31, 794, (ops G8RC:$rA, G8RC:$rS, G8RC:$rB),
                    "srad $rA, $rS, $rB",
-                   []>, isPPC64;
+                   [(set G8RC:$rA, (sra G8RC:$rS, G8RC:$rB))]>, isPPC64;
 def SRAW : XForm_6<31, 792, (ops GPRC:$rA, GPRC:$rS, GPRC:$rB),
                    "sraw $rA, $rS, $rB",
                    [(set GPRC:$rA, (sra GPRC:$rS, GPRC:$rB))]>;
@@ -663,29 +683,36 @@ let isTwoAddress = 1, isCommutable = 1 in {
 // RLWIMI can be commuted if the rotate amount is zero.
 def RLWIMI : MForm_2<20,
                      (ops GPRC:$rA, GPRC:$rSi, GPRC:$rS, u5imm:$SH, u5imm:$MB, 
-                      u5imm:$ME), "rlwimi $rA, $rS, $SH, $MB, $ME">;
+                      u5imm:$ME), "rlwimi $rA, $rS, $SH, $MB, $ME",
+                      []>;
 def RLDIMI : MDForm_1<30, 3,
                       (ops G8RC:$rA, G8RC:$rSi, G8RC:$rS, u6imm:$SH, u6imm:$MB),
-                      "rldimi $rA, $rS, $SH, $MB">, isPPC64;
+                      "rldimi $rA, $rS, $SH, $MB",
+                      []>, isPPC64;
 }
 def RLWINM : MForm_2<21,
                      (ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
-                     "rlwinm $rA, $rS, $SH, $MB, $ME">;
+                     "rlwinm $rA, $rS, $SH, $MB, $ME",
+                     []>;
 def RLWINMo : MForm_2<21,
                      (ops GPRC:$rA, GPRC:$rS, u5imm:$SH, u5imm:$MB, u5imm:$ME),
-                     "rlwinm. $rA, $rS, $SH, $MB, $ME">, isDOT;
+                     "rlwinm. $rA, $rS, $SH, $MB, $ME",
+                     []>, isDOT;
 def RLWNM  : MForm_2<23,
                      (ops GPRC:$rA, GPRC:$rS, GPRC:$rB, u5imm:$MB, u5imm:$ME),
-                     "rlwnm $rA, $rS, $rB, $MB, $ME">;
+                     "rlwnm $rA, $rS, $rB, $MB, $ME",
+                     []>;
 
 // MD-Form instructions.  64 bit rotate instructions.
 //
 def RLDICL : MDForm_1<30, 0,
                       (ops G8RC:$rA, G8RC:$rS, u6imm:$SH, u6imm:$MB),
-                      "rldicl $rA, $rS, $SH, $MB">, isPPC64;
+                      "rldicl $rA, $rS, $SH, $MB",
+                      []>, isPPC64;
 def RLDICR : MDForm_1<30, 1,
                       (ops G8RC:$rA, G8RC:$rS, u6imm:$SH, u6imm:$ME),
-                      "rldicr $rA, $rS, $SH, $ME">, isPPC64;
+                      "rldicr $rA, $rS, $SH, $ME",
+                      []>, isPPC64;
 
 //===----------------------------------------------------------------------===//
 // PowerPC Instruction Patterns
@@ -716,6 +743,17 @@ def : Pat<(anyext GPRC:$in),
 def : Pat<(trunc G8RC:$in),
           (OR8To4 G8RC:$in, G8RC:$in)>;
 
+// SHL
+def : Pat<(shl GPRC:$in, imm:$imm),
+          (RLWINM GPRC:$in, imm:$imm, 0, (SHL32 imm:$imm))>;
+def : Pat<(shl G8RC:$in, imm:$imm),
+          (RLDICR G8RC:$in, imm:$imm, (SHL64 imm:$imm))>;
+// SRL
+def : Pat<(srl GPRC:$in, imm:$imm),
+          (RLWINM GPRC:$in, (SRL32 imm:$imm), imm:$imm, 31)>;
+def : Pat<(srl G8RC:$in, imm:$imm),
+          (RLDICL G8RC:$in, (SRL64 imm:$imm), imm:$imm)>;
+
 // Same as above, but using a temporary. FIXME: implement temporaries :)
 /*
 def : Pattern<(xor GPRC:$in, imm:$imm),