Be nice to CellSPU: for this target getSetCCResultType
[oota-llvm.git] / lib / CodeGen / SelectionDAG / LegalizeDAG.cpp
index 6e7aa1964ac7964e98293a5f047302745bd5ebef..96b427bd8067a186aa383dedeffa44939798d6cd 100644 (file)
@@ -193,6 +193,11 @@ private:
                                     SmallPtrSet<SDNode*, 32> &NodesLeadingTo);
 
   void LegalizeSetCCOperands(SDValue &LHS, SDValue &RHS, SDValue &CC);
+  void LegalizeSetCCCondCode(MVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC);
+  void LegalizeSetCC(MVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC) {
+    LegalizeSetCCOperands(LHS, RHS, CC);
+    LegalizeSetCCCondCode(VT, LHS, RHS, CC);
+  }
     
   SDValue ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned,
                           SDValue &Hi);
@@ -456,7 +461,7 @@ static SDValue ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP,
     if (CFP->isValueValidForType(SVT, CFP->getValueAPF()) &&
         // Only do this if the target has a native EXTLOAD instruction from
         // smaller type.
-        TLI.isLoadXLegal(ISD::EXTLOAD, SVT) &&
+        TLI.isLoadExtLegal(ISD::EXTLOAD, SVT) &&
         TLI.ShouldShrinkFPConstant(OrigVT)) {
       const Type *SType = SVT.getTypeForMVT();
       LLVMC = cast<ConstantFP>(ConstantExpr::getFPTrunc(LLVMC, SType));
@@ -1886,10 +1891,10 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
     Tmp3 = Node->getOperand(3);              // RHS
     Tmp4 = Node->getOperand(1);              // CC
 
-    LegalizeSetCCOperands(Tmp2, Tmp3, Tmp4);
+    LegalizeSetCC(Node->getValueType(0), Tmp2, Tmp3, Tmp4);
     LastCALLSEQ_END = DAG.getEntryNode();
 
-    // If we didn't get both a LHS and RHS back from LegalizeSetCCOperands,
+    // If we didn't get both a LHS and RHS back from LegalizeSetCC,
     // the LHS is a legal SETCC itself.  In this case, we need to compare
     // the result against zero to select between true and false values.
     if (Tmp3.getNode() == 0) {
@@ -1981,7 +1986,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
           // nice to have an effective generic way of getting these benefits...
           // Until such a way is found, don't insist on promoting i1 here.
           (SrcVT != MVT::i1 ||
-           TLI.getLoadXAction(ExtType, MVT::i1) == TargetLowering::Promote)) {
+           TLI.getLoadExtAction(ExtType, MVT::i1) == TargetLowering::Promote)) {
         // Promote to a byte-sized load if not loading an integral number of
         // bytes.  For example, promote EXTLOAD:i20 -> EXTLOAD:i24.
         unsigned NewWidth = SrcVT.getStoreSizeInBits();
@@ -2086,7 +2091,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
         Tmp1 = LegalizeOp(Result);
         Tmp2 = LegalizeOp(Ch);
       } else {
-        switch (TLI.getLoadXAction(ExtType, SrcVT)) {
+        switch (TLI.getLoadExtAction(ExtType, SrcVT)) {
         default: assert(0 && "This action is not supported yet!");
         case TargetLowering::Custom:
           isCustom = true;
@@ -2772,9 +2777,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
     Tmp4 = LegalizeOp(Node->getOperand(3));   // False
     SDValue CC = Node->getOperand(4);
     
-    LegalizeSetCCOperands(Tmp1, Tmp2, CC);
+    LegalizeSetCC(Node->getValueType(0), Tmp1, Tmp2, CC);
     
-    // If we didn't get both a LHS and RHS back from LegalizeSetCCOperands,
+    // If we didn't get both a LHS and RHS back from LegalizeSetCC,
     // the LHS is a legal SETCC itself.  In this case, we need to compare
     // the result against zero to select between true and false values.
     if (Tmp2.getNode() == 0) {
@@ -2798,7 +2803,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) {
     Tmp1 = Node->getOperand(0);
     Tmp2 = Node->getOperand(1);
     Tmp3 = Node->getOperand(2);
-    LegalizeSetCCOperands(Tmp1, Tmp2, Tmp3);
+    LegalizeSetCC(Node->getValueType(0), Tmp1, Tmp2, Tmp3);
     
     // If we had to Expand the SetCC operands into a SELECT node, then it may 
     // not always be possible to return a true LHS & RHS.  In this case, just 
@@ -4877,6 +4882,50 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS,
   RHS = Tmp2;
 }
 
+/// LegalizeSetCCCondCode - Legalize a SETCC with given LHS and RHS and
+/// condition code CC on the current target. This routine assumes LHS and rHS
+/// have already been legalized by LegalizeSetCCOperands. It expands SETCC with
+/// illegal condition code into AND / OR of multiple SETCC values.
+void SelectionDAGLegalize::LegalizeSetCCCondCode(MVT VT,
+                                                 SDValue &LHS, SDValue &RHS,
+                                                 SDValue &CC) {
+  MVT OpVT = LHS.getValueType();
+  ISD::CondCode CCCode = cast<CondCodeSDNode>(CC)->get();
+  switch (TLI.getCondCodeAction(CCCode, OpVT)) {
+  default: assert(0 && "Unknown condition code action!");
+  case TargetLowering::Legal:
+    // Nothing to do.
+    break;
+  case TargetLowering::Expand: {
+    ISD::CondCode CC1 = ISD::SETCC_INVALID, CC2 = ISD::SETCC_INVALID;
+    unsigned Opc = 0;
+    switch (CCCode) {
+    default: assert(0 && "Don't know how to expand this condition!"); abort();
+    case ISD::SETOEQ: CC1 = ISD::SETEQ; CC2 = ISD::SETO;  Opc = ISD::AND; break;
+    case ISD::SETOGT: CC1 = ISD::SETGT; CC2 = ISD::SETO;  Opc = ISD::AND; break;
+    case ISD::SETOGE: CC1 = ISD::SETGE; CC2 = ISD::SETO;  Opc = ISD::AND; break;
+    case ISD::SETOLT: CC1 = ISD::SETLT; CC2 = ISD::SETO;  Opc = ISD::AND; break;
+    case ISD::SETOLE: CC1 = ISD::SETLE; CC2 = ISD::SETO;  Opc = ISD::AND; break;
+    case ISD::SETONE: CC1 = ISD::SETNE; CC2 = ISD::SETO;  Opc = ISD::AND; break;
+    case ISD::SETUEQ: CC1 = ISD::SETEQ; CC2 = ISD::SETUO; Opc = ISD::OR;  break;
+    case ISD::SETUGT: CC1 = ISD::SETGT; CC2 = ISD::SETUO; Opc = ISD::OR;  break;
+    case ISD::SETUGE: CC1 = ISD::SETGE; CC2 = ISD::SETUO; Opc = ISD::OR;  break;
+    case ISD::SETULT: CC1 = ISD::SETLT; CC2 = ISD::SETUO; Opc = ISD::OR;  break;
+    case ISD::SETULE: CC1 = ISD::SETLE; CC2 = ISD::SETUO; Opc = ISD::OR;  break;
+    case ISD::SETUNE: CC1 = ISD::SETNE; CC2 = ISD::SETUO; Opc = ISD::OR;  break;
+    // FIXME: Implement more expansions.
+    }
+
+    SDValue SetCC1 = DAG.getSetCC(VT, LHS, RHS, CC1);
+    SDValue SetCC2 = DAG.getSetCC(VT, LHS, RHS, CC2);
+    LHS = DAG.getNode(Opc, VT, SetCC1, SetCC2);
+    RHS = SDValue();
+    CC  = SDValue();
+    break;
+  }
+  }
+}
+
 /// EmitStackConvert - Emit a store/load combination to the stack.  This stores
 /// SrcOp to a stack slot of type SlotVT, truncating it if needed.  It then does
 /// a load from the stack slot to DestVT, extending it if needed.
@@ -5424,6 +5473,22 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) {
       Hi = Source;
     }
 
+    // Check to see if the target has a custom way to lower this.  If so, use it.
+    // (Note we've already expanded the operand in this case.)
+    switch (TLI.getOperationAction(ISD::UINT_TO_FP, SourceVT)) {
+    default: assert(0 && "This action not implemented for this operation!");
+    case TargetLowering::Legal:
+    case TargetLowering::Expand:
+      break;   // This case is handled below.
+    case TargetLowering::Custom: {
+      SDValue NV = TLI.LowerOperation(DAG.getNode(ISD::UINT_TO_FP, DestTy,
+                                                    Source), DAG);
+      if (NV.getNode())
+        return LegalizeOp(NV);
+      break;   // The target decided this was legal after all
+    }
+    }
+
     // If this is unsigned, and not supported, first perform the conversion to
     // signed, then adjust the result if the sign bit is set.
     SDValue SignedConv = ExpandIntToFP(true, DestTy, Source);