[llvm-commits] CVS: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp PPCISelLowering.cpp PPCISelLowering.h PPCInstrAltivec.td PPCInstrInfo.td

Chris Lattner lattner at cs.uiuc.edu
Sun Mar 26 02:06:55 PST 2006



Changes in directory llvm/lib/Target/PowerPC:

PPCISelDAGToDAG.cpp updated: 1.177 -> 1.178
PPCISelLowering.cpp updated: 1.113 -> 1.114
PPCISelLowering.h updated: 1.34 -> 1.35
PPCInstrAltivec.td updated: 1.9 -> 1.10
PPCInstrInfo.td updated: 1.211 -> 1.212
---
Log message:

Codegen vector predicate compares.


---
Diffs of the changes:  (+139 -15)

 PPCISelDAGToDAG.cpp |   14 +++++++++
 PPCISelLowering.cpp |   80 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 PPCISelLowering.h   |   11 +++++++
 PPCInstrAltivec.td  |   39 ++++++++++++++++---------
 PPCInstrInfo.td     |   10 +++++-
 5 files changed, 139 insertions(+), 15 deletions(-)


Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.177 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.178
--- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.177	Sat Mar 25 00:47:10 2006
+++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp	Sun Mar 26 04:06:40 2006
@@ -1060,6 +1060,20 @@
                                       getI32Imm(0)), 0);
     return;
   }
+
+  case PPCISD::MFCR: {
+    SDOperand InFlag;
+    Select(InFlag, N->getOperand(1));
+    // Use MFOCRF if supported.
+    if (TLI.getTargetMachine().getSubtarget<PPCSubtarget>().isGigaProcessor())
+      Result = SDOperand(CurDAG->getTargetNode(PPC::MFOCRF, MVT::i32,
+                                               N->getOperand(0), InFlag), 0);
+    else
+      Result = SDOperand(CurDAG->getTargetNode(PPC::MFCR, MVT::i32, InFlag), 0);
+    CodeGenMap[Op] = Result;
+    return;
+  }
+    
   case ISD::SDIV: {
     // FIXME: since this depends on the setting of the carry flag from the srawi
     //        we should really be making notes about that for the scheduler.


Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.113 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.114
--- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.113	Sun Mar 26 03:52:32 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp	Sun Mar 26 04:06:40 2006
@@ -22,6 +22,7 @@
 #include "llvm/CodeGen/SSARegMap.h"
 #include "llvm/Constants.h"
 #include "llvm/Function.h"
+#include "llvm/Intrinsics.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Target/TargetOptions.h"
 using namespace llvm;
@@ -136,6 +137,9 @@
   setOperationAction(ISD::STACKRESTORE      , MVT::Other, Expand);
   setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32  , Expand);
   
+  // We want to custom lower some of our intrinsics.
+  setOperationAction(ISD::INTRINSIC         , MVT::Other, Custom);
+  
   if (TM.getSubtarget<PPCSubtarget>().is64Bit()) {
     // They also have instructions for converting between i64 and fp.
     setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom);
@@ -230,6 +234,8 @@
   case PPCISD::STD_32:        return "PPCISD::STD_32";
   case PPCISD::CALL:          return "PPCISD::CALL";
   case PPCISD::RET_FLAG:      return "PPCISD::RET_FLAG";
+  case PPCISD::MFCR:          return "PPCISD::MFCR";
+  case PPCISD::VCMPo:         return "PPCISD::VCMPo";
   }
 }
 
@@ -746,6 +752,80 @@
     SDOperand VPermMask =DAG.getNode(ISD::BUILD_VECTOR, MVT::v16i8, ResultMask);
     return DAG.getNode(PPCISD::VPERM, V1.getValueType(), V1, V2, VPermMask);
   }
+  case ISD::INTRINSIC: {
+    bool HasChain = Op.getOperand(0).getValueType() == MVT::Other;
+    unsigned IntNo=cast<ConstantSDNode>(Op.getOperand(HasChain))->getValue();
+    
+    // If this is a lowered altivec predicate compare, CompareOpc is set to the
+    // opcode number of the comparison.
+    int CompareOpc = -1;
+    switch (IntNo) {
+    default: return SDOperand();    // Don't custom lower most intrinsics.
+    case Intrinsic::ppc_altivec_vcmpbfp_p:  CompareOpc = 966; break;
+    case Intrinsic::ppc_altivec_vcmpeqfp_p: CompareOpc = 198; break;
+    case Intrinsic::ppc_altivec_vcmpequb_p: CompareOpc =   6; break;
+    case Intrinsic::ppc_altivec_vcmpequh_p: CompareOpc =  70; break;
+    case Intrinsic::ppc_altivec_vcmpequw_p: CompareOpc = 134; break;
+    case Intrinsic::ppc_altivec_vcmpgefp_p: CompareOpc = 454; break;
+    case Intrinsic::ppc_altivec_vcmpgtfp_p: CompareOpc = 710; break;
+    case Intrinsic::ppc_altivec_vcmpgtsb_p: CompareOpc = 774; break;
+    case Intrinsic::ppc_altivec_vcmpgtsh_p: CompareOpc = 838; break;
+    case Intrinsic::ppc_altivec_vcmpgtsw_p: CompareOpc = 902; break;
+    case Intrinsic::ppc_altivec_vcmpgtub_p: CompareOpc = 518; break;
+    case Intrinsic::ppc_altivec_vcmpgtuh_p: CompareOpc = 582; break;
+    case Intrinsic::ppc_altivec_vcmpgtuw_p: CompareOpc = 646; break;
+    }
+    
+    assert(CompareOpc>0 && "We only lower altivec predicate compares so far!");
+
+    // Create the PPCISD altivec 'dot' comparison node.
+    std::vector<SDOperand> Ops;
+    std::vector<MVT::ValueType> VTs;
+    Ops.push_back(Op.getOperand(2));  // LHS
+    Ops.push_back(Op.getOperand(3));  // RHS
+    Ops.push_back(DAG.getConstant(CompareOpc, MVT::i32));
+    VTs.push_back(Op.getOperand(2).getValueType());
+    VTs.push_back(MVT::Flag);
+    SDOperand CompNode = DAG.getNode(PPCISD::VCMPo, VTs, Ops);
+
+    // Now that we have the comparison, emit a copy from the CR to a GPR.
+    // This is flagged to the above dot comparison.
+    SDOperand Flags = DAG.getNode(PPCISD::MFCR, MVT::i32,
+                                  DAG.getRegister(PPC::CR6, MVT::i32),
+                                  CompNode.getValue(1)); 
+
+    // Unpack the result based on how the target uses it.
+    unsigned BitNo;   // Bit # of CR6.
+    bool InvertBit;   // Invert result?
+    switch (cast<ConstantSDNode>(Op.getOperand(1))->getValue()) {
+    default:  // Can't happen, don't crash on invalid number though.
+    case 0:   // Return the value of the EQ bit of CR6.
+      BitNo = 0; InvertBit = false;
+      break;
+    case 1:   // Return the inverted value of the EQ bit of CR6.
+      BitNo = 0; InvertBit = true;
+      break;
+    case 2:   // Return the value of the LT bit of CR6.
+      BitNo = 2; InvertBit = false;
+      break;
+    case 3:   // Return the inverted value of the LT bit of CR6.
+      BitNo = 2; InvertBit = true;
+      break;
+    }
+    
+    // Shift the bit into the low position.
+    Flags = DAG.getNode(ISD::SRL, MVT::i32, Flags,
+                        DAG.getConstant(8-(3-BitNo), MVT::i32));
+    // Isolate the bit.
+    Flags = DAG.getNode(ISD::AND, MVT::i32, Flags,
+                        DAG.getConstant(1, MVT::i32));
+    
+    // If we are supposed to, toggle the bit.
+    if (InvertBit)
+      Flags = DAG.getNode(ISD::XOR, MVT::i32, Flags,
+                          DAG.getConstant(1, MVT::i32));
+    return Flags;
+  }
   }
   return SDOperand();
 }


Index: llvm/lib/Target/PowerPC/PPCISelLowering.h
diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.34 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.35
--- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.34	Sun Mar 26 03:52:32 2006
+++ llvm/lib/Target/PowerPC/PPCISelLowering.h	Sun Mar 26 04:06:40 2006
@@ -88,6 +88,17 @@
       
       /// Return with a flag operand, matched by 'blr'
       RET_FLAG,
+      
+      /// R32 = MFCR(CRREG, INFLAG) - Represents the MFCR/MFOCRF instructions.
+      /// This copies the bits corresponding to the specified CRREG into the
+      /// resultant GPR.  Bits corresponding to other CR regs are undefined.
+      MFCR,
+      
+      /// RESVEC, OUTFLAG = VCMPo(LHS, RHS, OPC) - Represents one of the
+      /// altivec VCMP*o instructions.  For lack of better number, we use the 
+      /// opcode number encoding for the OPC field to identify the compare.  For
+      /// example, 838 is VCMPGTSH.
+      VCMPo
     };
   }
 


Index: llvm/lib/Target/PowerPC/PPCInstrAltivec.td
diff -u llvm/lib/Target/PowerPC/PPCInstrAltivec.td:1.9 llvm/lib/Target/PowerPC/PPCInstrAltivec.td:1.10
--- llvm/lib/Target/PowerPC/PPCInstrAltivec.td:1.9	Sun Mar 26 03:52:32 2006
+++ llvm/lib/Target/PowerPC/PPCInstrAltivec.td	Sun Mar 26 04:06:40 2006
@@ -306,28 +306,32 @@
                                 (int_ppc_altivec_vcmpbfp VRRC:$vA, VRRC:$vB))]>;
 def VCMPBFPo  : VXRForm_1<966, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                           "vcmpbfp. $vD, $vA, $vB", VecFPCompare,
-                          []>, isVDOT;
+                          [(set VRRC:$vD, (v4f32
+                                (PPCvcmp_o VRRC:$vA, VRRC:$vB, 966)))]>, isVDOT;
 def VCMPEQFP  : VXRForm_1<198, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpeqfp $vD, $vA, $vB", VecFPCompare,
                          [(set VRRC:$vD, 
                                (int_ppc_altivec_vcmpeqfp VRRC:$vA, VRRC:$vB))]>;
 def VCMPEQFPo : VXRForm_1<198, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpeqfp. $vD, $vA, $vB", VecFPCompare,
-                         []>, isVDOT;
+                         [(set VRRC:$vD, (v4f32
+                                (PPCvcmp_o VRRC:$vA, VRRC:$vB, 198)))]>, isVDOT;
 def VCMPGEFP  : VXRForm_1<454, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgefp $vD, $vA, $vB", VecFPCompare,
                          [(set VRRC:$vD, 
                                (int_ppc_altivec_vcmpgefp VRRC:$vA, VRRC:$vB))]>;
 def VCMPGEFPo : VXRForm_1<454, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgefp. $vD, $vA, $vB", VecFPCompare,
-                         []>, isVDOT;
+                         [(set VRRC:$vD, (v4f32
+                                (PPCvcmp_o VRRC:$vA, VRRC:$vB, 454)))]>, isVDOT;
 def VCMPGTFP  : VXRForm_1<710, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgtfp $vD, $vA, $vB", VecFPCompare,
                          [(set VRRC:$vD, 
                                (int_ppc_altivec_vcmpgtfp VRRC:$vA, VRRC:$vB))]>;
 def VCMPGTFPo : VXRForm_1<710, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgtfp. $vD, $vA, $vB", VecFPCompare,
-                         []>, isVDOT;
+                         [(set VRRC:$vD, (v4f32
+                                (PPCvcmp_o VRRC:$vA, VRRC:$vB, 710)))]>, isVDOT;
 
 // i8 element comparisons.
 def VCMPEQUB  : VXRForm_1<6, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
@@ -336,21 +340,24 @@
                                (int_ppc_altivec_vcmpequb VRRC:$vA, VRRC:$vB))]>;
 def VCMPEQUBo : VXRForm_1<6, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpequb. $vD, $vA, $vB", VecFPCompare,
-                         []>, isVDOT;
+                         [(set VRRC:$vD, (v16i8
+                                (PPCvcmp_o VRRC:$vA, VRRC:$vB, 6)))]>, isVDOT;
 def VCMPGTSB  : VXRForm_1<774, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgtsb $vD, $vA, $vB", VecFPCompare,
                          [(set VRRC:$vD, 
                                (int_ppc_altivec_vcmpgtsb VRRC:$vA, VRRC:$vB))]>;
 def VCMPGTSBo : VXRForm_1<774, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgtsb. $vD, $vA, $vB", VecFPCompare,
-                         []>, isVDOT;
+                         [(set VRRC:$vD, (v16i8
+                                (PPCvcmp_o VRRC:$vA, VRRC:$vB, 774)))]>, isVDOT;
 def VCMPGTUB  : VXRForm_1<518, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgtub $vD, $vA, $vB", VecFPCompare,
                          [(set VRRC:$vD, 
                                (int_ppc_altivec_vcmpgtub VRRC:$vA, VRRC:$vB))]>;
 def VCMPGTUBo : VXRForm_1<518, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgtub. $vD, $vA, $vB", VecFPCompare,
-                         []>, isVDOT;
+                         [(set VRRC:$vD, (v16i8 
+                                (PPCvcmp_o VRRC:$vA, VRRC:$vB, 518)))]>, isVDOT;
 
 // i16 element comparisons.
 def VCMPEQUH  : VXRForm_1<70, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
@@ -359,21 +366,24 @@
                                (int_ppc_altivec_vcmpequh VRRC:$vA, VRRC:$vB))]>;
 def VCMPEQUHo : VXRForm_1<70, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpequh. $vD, $vA, $vB", VecFPCompare,
-                         []>, isVDOT;
+                         [(set VRRC:$vD, (v8i16 
+                                (PPCvcmp_o VRRC:$vA, VRRC:$vB, 70)))]>, isVDOT;
 def VCMPGTSH  : VXRForm_1<838, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgtsh $vD, $vA, $vB", VecFPCompare,
                          [(set VRRC:$vD, 
                                (int_ppc_altivec_vcmpgtsh VRRC:$vA, VRRC:$vB))]>;
 def VCMPGTSHo : VXRForm_1<838, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgtsh. $vD, $vA, $vB", VecFPCompare,
-                         []>, isVDOT;
+                         [(set VRRC:$vD, (v8i16 
+                                (PPCvcmp_o VRRC:$vA, VRRC:$vB, 838)))]>, isVDOT;
 def VCMPGTUH  : VXRForm_1<582, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgtuh $vD, $vA, $vB", VecFPCompare,
                          [(set VRRC:$vD, 
                                (int_ppc_altivec_vcmpgtuh VRRC:$vA, VRRC:$vB))]>;
 def VCMPGTUHo : VXRForm_1<582, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgtuh. $vD, $vA, $vB", VecFPCompare,
-                         []>, isVDOT;
+                         [(set VRRC:$vD, (v8i16 
+                                (PPCvcmp_o VRRC:$vA, VRRC:$vB, 582)))]>, isVDOT;
 
 // i32 element comparisons.
 def VCMPEQUW  : VXRForm_1<134, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
@@ -382,21 +392,24 @@
                                (int_ppc_altivec_vcmpequw VRRC:$vA, VRRC:$vB))]>;
 def VCMPEQUWo : VXRForm_1<134, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpequw. $vD, $vA, $vB", VecFPCompare,
-                         []>, isVDOT;
+                         [(set VRRC:$vD, (v4i32
+                                (PPCvcmp_o VRRC:$vA, VRRC:$vB, 134)))]>, isVDOT;
 def VCMPGTSW  : VXRForm_1<902, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgtsw $vD, $vA, $vB", VecFPCompare,
                          [(set VRRC:$vD, 
                                (int_ppc_altivec_vcmpgtsw VRRC:$vA, VRRC:$vB))]>;
 def VCMPGTSWo : VXRForm_1<902, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgtsw. $vD, $vA, $vB", VecFPCompare,
-                         []>, isVDOT;
+                         [(set VRRC:$vD, (v4i32
+                                (PPCvcmp_o VRRC:$vA, VRRC:$vB, 902)))]>, isVDOT;
 def VCMPGTUW  : VXRForm_1<646, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgtuw $vD, $vA, $vB", VecFPCompare,
                          [(set VRRC:$vD, 
                                (int_ppc_altivec_vcmpgtuw VRRC:$vA, VRRC:$vB))]>;
 def VCMPGTUWo : VXRForm_1<646, (ops VRRC:$vD, VRRC:$vA, VRRC:$vB),
                          "vcmpgtuw. $vD, $vA, $vB", VecFPCompare,
-                         []>, isVDOT;
+                         [(set VRRC:$vD, (v4i32
+                                (PPCvcmp_o VRRC:$vA, VRRC:$vB, 646)))]>, isVDOT;
                       
 def V_SET0 : VXForm_setzero<1220, (ops VRRC:$vD),
                       "vxor $vD, $vD, $vD", VecFP,


Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td
diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.211 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.212
--- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.211	Sat Mar 25 01:51:43 2006
+++ llvm/lib/Target/PowerPC/PPCInstrInfo.td	Sun Mar 26 04:06:40 2006
@@ -30,6 +30,10 @@
   SDTCisVT<3, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>
 ]>;
 
+def SDT_PPCvcmp_o : SDTypeProfile<1, 3, [
+  SDTCisSameAs<0, 1>, SDTCisSameAs<1, 2>, SDTCisVT<3, i32>
+]>;
+
 //===----------------------------------------------------------------------===//
 // PowerPC specific DAG Nodes.
 //
@@ -68,6 +72,8 @@
 def retflag       : SDNode<"PPCISD::RET_FLAG", SDT_PPCRetFlag,
 	                   [SDNPHasChain, SDNPOptInFlag]>;
 
+def PPCvcmp_o     : SDNode<"PPCISD::VCMPo", SDT_PPCvcmp_o, [SDNPOutFlag]>;
+
 //===----------------------------------------------------------------------===//
 // PowerPC specific transformation functions and pattern fragments.
 //
@@ -701,11 +707,11 @@
                              "mfspr $rT, 256", IntGeneral>,
                PPC970_DGroup_First, PPC970_Unit_FXU;
 
-def MFCR  : XFXForm_3<31, 19, (ops GPRC:$rT), "mfcr $rT", SprMFCR>,
-            PPC970_MicroCode, PPC970_Unit_CRU;
 def MTCRF : XFXForm_5<31, 144, (ops crbitm:$FXM, GPRC:$rS),
                       "mtcrf $FXM, $rS", BrMCRX>,
             PPC970_MicroCode, PPC970_Unit_CRU;
+def MFCR  : XFXForm_3<31, 19, (ops GPRC:$rT), "mfcr $rT", SprMFCR>,
+            PPC970_MicroCode, PPC970_Unit_CRU;
 def MFOCRF: XFXForm_5a<31, 19, (ops GPRC:$rT, crbitm:$FXM),
                        "mfcr $rT, $FXM", SprMFCR>,
             PPC970_DGroup_First, PPC970_Unit_CRU;






More information about the llvm-commits mailing list