Pattern match vmrg* instructions, which are now lowered by the CFE into shuffles.
authorChris Lattner <sabre@nondot.org>
Thu, 6 Apr 2006 21:11:54 +0000 (21:11 +0000)
committerChris Lattner <sabre@nondot.org>
Thu, 6 Apr 2006 21:11:54 +0000 (21:11 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@27457 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/PowerPC/PPCISelLowering.cpp
lib/Target/PowerPC/PPCISelLowering.h
lib/Target/PowerPC/PPCInstrAltivec.td
lib/Target/PowerPC/README_ALTIVEC.txt

index c954f8ced8d8ce7500bd09de17b8c1232414c5e2..53c3cee5628f9e04fe92d5dedb464bc523aff44d 100644 (file)
@@ -293,10 +293,50 @@ bool PPC::isVPKUWUMShuffleMask(SDNode *N) {
   return true;
 }
 
+/// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for
+/// a VRGL* instruction with the specified unit size (1,2 or 4 bytes).
+bool PPC::isVMRGLShuffleMask(SDNode *N, unsigned UnitSize) {
+  assert(N->getOpcode() == ISD::BUILD_VECTOR &&
+         N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!");
+  assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
+         "Unsupported merge size!");
+  
+  for (unsigned i = 0; i != 8/UnitSize; ++i)     // Step over units
+    for (unsigned j = 0; j != UnitSize; ++j) {   // Step over bytes within unit
+      if (!isConstantOrUndef(N->getOperand(i*UnitSize*2+j),
+                             8+j+i*UnitSize) ||
+          !isConstantOrUndef(N->getOperand(i*UnitSize*2+UnitSize+j),
+                             24+j+i*UnitSize))
+        return false;
+    }
+  return true;
+}
+
+/// isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for
+/// a VRGH* instruction with the specified unit size (1,2 or 4 bytes).
+bool PPC::isVMRGHShuffleMask(SDNode *N, unsigned UnitSize) {
+  assert(N->getOpcode() == ISD::BUILD_VECTOR &&
+         N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!");
+  assert((UnitSize == 1 || UnitSize == 2 || UnitSize == 4) &&
+         "Unsupported merge size!");
+
+  for (unsigned i = 0; i != 8/UnitSize; ++i)     // Step over units
+    for (unsigned j = 0; j != UnitSize; ++j) {   // Step over bytes within unit
+      if (!isConstantOrUndef(N->getOperand(i*UnitSize*2+j),
+                             0+j+i*UnitSize) ||
+          !isConstantOrUndef(N->getOperand(i*UnitSize*2+UnitSize+j),
+                             16+j+i*UnitSize))
+        return false;
+    }
+  return true;
+}
+
+
 /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift
 /// amount, otherwise return -1.
 int PPC::isVSLDOIShuffleMask(SDNode *N) {
-  assert(N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!");
+  assert(N->getOpcode() == ISD::BUILD_VECTOR &&
+         N->getNumOperands() == 16 && "PPC only supports shuffles by bytes!");
   // Find the first non-undef value in the shuffle mask.
   unsigned i;
   for (i = 0; i != 16 && N->getOperand(i).getOpcode() == ISD::UNDEF; ++i)
@@ -833,13 +873,19 @@ SDOperand PPCTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     if (V2.getOpcode() == ISD::UNDEF && 
         (PPC::isSplatShuffleMask(PermMask.Val, 1) ||
          PPC::isSplatShuffleMask(PermMask.Val, 2) ||
-         PPC::isSplatShuffleMask(PermMask.Val, 4)))
+         PPC::isSplatShuffleMask(PermMask.Val, 4) ||
+         PPC::isVSLDOIRotateShuffleMask(PermMask.Val) != -1))
       return Op;
     
     if (PPC::isVPKUWUMShuffleMask(PermMask.Val) ||
         PPC::isVPKUHUMShuffleMask(PermMask.Val) ||
         PPC::isVSLDOIShuffleMask(PermMask.Val) != -1 ||
-        PPC::isVSLDOIRotateShuffleMask(PermMask.Val) != -1)
+        PPC::isVMRGLShuffleMask(PermMask.Val, 1) ||
+        PPC::isVMRGLShuffleMask(PermMask.Val, 2) ||
+        PPC::isVMRGLShuffleMask(PermMask.Val, 4) ||
+        PPC::isVMRGHShuffleMask(PermMask.Val, 1) ||
+        PPC::isVMRGHShuffleMask(PermMask.Val, 2) ||
+        PPC::isVMRGHShuffleMask(PermMask.Val, 4))
       return Op;
     
     // TODO: Handle more cases, and also handle cases that are cheaper to do as
index 77d85c2559f97e9b43fac1507654bcee6e7faea1..c2666ed7af92a1147976bfc4a720cb44150ccdf7 100644 (file)
@@ -109,6 +109,14 @@ namespace llvm {
     /// isVPKUWUMShuffleMask - Return true if this is the shuffle mask for a
     /// VPKUWUM instruction.
     bool isVPKUWUMShuffleMask(SDNode *N);
+
+    /// isVMRGLShuffleMask - Return true if this is a shuffle mask suitable for
+    /// a VRGL* instruction with the specified unit size (1,2 or 4 bytes).
+    bool isVMRGLShuffleMask(SDNode *N, unsigned UnitSize);
+
+    /// isVMRGHShuffleMask - Return true if this is a shuffle mask suitable for
+    /// a VRGH* instruction with the specified unit size (1,2 or 4 bytes).
+    bool isVMRGHShuffleMask(SDNode *N, unsigned UnitSize);
     
     /// isVSLDOIShuffleMask - If this is a vsldoi shuffle mask, return the shift
     /// amount, otherwise return -1.
index 216cbbddfef8ff6d77885d88658a8ff524b7e2ce..b295641e335d52f68163c4207259a8bc3de3be4e 100644 (file)
@@ -24,6 +24,26 @@ def VPKUWUM_shuffle_mask : PatLeaf<(build_vector), [{
   return PPC::isVPKUWUMShuffleMask(N);
 }]>;
 
+def VMRGLB_shuffle_mask : PatLeaf<(build_vector), [{
+  return PPC::isVMRGLShuffleMask(N, 1);
+}]>;
+def VMRGLH_shuffle_mask : PatLeaf<(build_vector), [{
+  return PPC::isVMRGLShuffleMask(N, 2);
+}]>;
+def VMRGLW_shuffle_mask : PatLeaf<(build_vector), [{
+  return PPC::isVMRGLShuffleMask(N, 4);
+}]>;
+def VMRGHB_shuffle_mask : PatLeaf<(build_vector), [{
+  return PPC::isVMRGHShuffleMask(N, 1);
+}]>;
+def VMRGHH_shuffle_mask : PatLeaf<(build_vector), [{
+  return PPC::isVMRGHShuffleMask(N, 2);
+}]>;
+def VMRGHW_shuffle_mask : PatLeaf<(build_vector), [{
+  return PPC::isVMRGHShuffleMask(N, 4);
+}]>;
+
+
 def VSLDOI_get_imm : SDNodeXForm<build_vector, [{
   return getI32Imm(PPC::isVSLDOIShuffleMask(N));
 }]>;
@@ -278,12 +298,30 @@ def VMINUB : VX1_Int< 514, "vminub", int_ppc_altivec_vminub>;
 def VMINUH : VX1_Int< 578, "vminuh", int_ppc_altivec_vminuh>;
 def VMINUW : VX1_Int< 642, "vminuw", int_ppc_altivec_vminuw>;
 
-def VMRGHB : VX1_Int<12 , "vmrghb", int_ppc_altivec_vmrghb>;
-def VMRGHH : VX1_Int<76 , "vmrghh", int_ppc_altivec_vmrghh>;
-def VMRGHW : VX1_Int<140, "vmrghw", int_ppc_altivec_vmrghw>;
-def VMRGLB : VX1_Int<268, "vmrglb", int_ppc_altivec_vmrglb>;
-def VMRGLH : VX1_Int<332, "vmrglh", int_ppc_altivec_vmrglh>;
-def VMRGLW : VX1_Int<396, "vmrglw", int_ppc_altivec_vmrglw>;
+def VMRGHB : VXForm_1< 12, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
+                      "vmrghb $vD, $vA, $vB", VecFP,
+                      [(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
+                                             VRRC:$vB, VMRGHB_shuffle_mask))]>;
+def VMRGHH : VXForm_1< 76, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
+                      "vmrghh $vD, $vA, $vB", VecFP,
+                      [(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
+                                             VRRC:$vB, VMRGHH_shuffle_mask))]>;
+def VMRGHW : VXForm_1<140, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
+                      "vmrghw $vD, $vA, $vB", VecFP,
+                      [(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
+                                             VRRC:$vB, VMRGHW_shuffle_mask))]>;
+def VMRGLB : VXForm_1<268, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
+                      "vmrglb $vD, $vA, $vB", VecFP,
+                      [(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
+                                             VRRC:$vB, VMRGLB_shuffle_mask))]>;
+def VMRGLH : VXForm_1<332, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
+                      "vmrglh $vD, $vA, $vB", VecFP,
+                      [(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
+                                             VRRC:$vB, VMRGLH_shuffle_mask))]>;
+def VMRGLW : VXForm_1<396, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
+                      "vmrglw $vD, $vA, $vB", VecFP,
+                      [(set VRRC:$vD, (vector_shuffle (v16i8 VRRC:$vA),
+                                             VRRC:$vB, VMRGLW_shuffle_mask))]>;
 
 def VMSUMMBM : VA1a_Int<37, "vmsummbm", int_ppc_altivec_vmsummbm>;
 def VMSUMSHM : VA1a_Int<40, "vmsumshm", int_ppc_altivec_vmsumshm>;
index 711f7c3ba7140b0e900042b4e398d54dcb621f34..b9456082fb4ea62ecd752572aec03960690a9930 100644 (file)
@@ -129,6 +129,3 @@ void test(vector int *X, vector int *Y) {
 
 //===----------------------------------------------------------------------===//
 
-Lower "merges" in the front-end to shuffles, reconstruct in the backend.
-
-//===----------------------------------------------------------------------===//