Add FP versions of the binary operators, keeping the int and fp worlds seperate.
Though I have done extensive testing, it is possible that this will break
things in configs I can't test.  Please let me know if this causes a problem
and I'll fix it ASAP.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23505 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/Alpha/AlphaISelLowering.cpp b/lib/Target/Alpha/AlphaISelLowering.cpp
index 910166e..2e5a832 100644
--- a/lib/Target/Alpha/AlphaISelLowering.cpp
+++ b/lib/Target/Alpha/AlphaISelLowering.cpp
@@ -68,8 +68,8 @@
   setOperationAction(ISD::SEXTLOAD, MVT::i8,  Expand);
   setOperationAction(ISD::SEXTLOAD, MVT::i16, Expand);
   
-  setOperationAction(ISD::SREM, MVT::f32, Expand);
-  setOperationAction(ISD::SREM, MVT::f64, Expand);
+  setOperationAction(ISD::FREM, MVT::f32, Expand);
+  setOperationAction(ISD::FREM, MVT::f64, Expand);
   
   setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand);
   
diff --git a/lib/Target/Alpha/AlphaISelPattern.cpp b/lib/Target/Alpha/AlphaISelPattern.cpp
index 1a20b29..c30c459 100644
--- a/lib/Target/Alpha/AlphaISelPattern.cpp
+++ b/lib/Target/Alpha/AlphaISelPattern.cpp
@@ -1275,10 +1275,7 @@
       case ISD::SHL: Opc = Alpha::SL; break;
       case ISD::SRL: Opc = Alpha::SRL; break;
       case ISD::SRA: Opc = Alpha::SRA; break;
-      case ISD::MUL:
-        Opc = isFP ? (DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS)
-          : Alpha::MULQ;
-        break;
+      case ISD::MUL: Opc = Alpha::MULQ; break;
       };
       Tmp1 = SelectExpr(N.getOperand(0));
       Tmp2 = SelectExpr(N.getOperand(1));
@@ -1288,25 +1285,7 @@
 
   case ISD::ADD:
   case ISD::SUB:
-    if (isFP) {
-      ConstantFPSDNode *CN;
-      if (opcode == ISD::ADD)
-        Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS;
-      else
-        Opc = DestType == MVT::f64 ? Alpha::SUBT : Alpha::SUBS;
-      if (opcode == ISD::SUB
-          && (CN = dyn_cast<ConstantFPSDNode>(N.getOperand(0)))
-          && (CN->isExactlyValue(+0.0) || CN->isExactlyValue(-0.0)))
-      {
-        Tmp2 = SelectExpr(N.getOperand(1));
-        BuildMI(BB, Alpha::CPYSN, 2, Result).addReg(Tmp2).addReg(Tmp2);
-      } else {
-        Tmp1 = SelectExpr(N.getOperand(0));
-        Tmp2 = SelectExpr(N.getOperand(1));
-        BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
-      }
-      return Result;
-    } else {
+    {
       bool isAdd = opcode == ISD::ADD;
 
       //first check for Scaled Adds and Subs!
@@ -1369,15 +1348,25 @@
       }
       return Result;
     }
-
+  case ISD::FADD:
+  case ISD::FSUB:
+  case ISD::FMUL:
+  case ISD::FDIV: {
+    if (opcode == ISD::FADD)
+      Opc = DestType == MVT::f64 ? Alpha::ADDT : Alpha::ADDS;
+    else if (opcode == ISD::FSUB)
+      Opc = DestType == MVT::f64 ? Alpha::SUBT : Alpha::SUBS;
+    else if (opcode == ISD::FMUL)
+      Opc = DestType == MVT::f64 ? Alpha::MULT : Alpha::MULS;
+    else
+      Opc = DestType == MVT::f64 ? Alpha::DIVT : Alpha::DIVS;
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+    BuildMI(BB, Opc, 2, Result).addReg(Tmp1).addReg(Tmp2);
+    return Result;
+  }
   case ISD::SDIV:
-    if (isFP) {
-      Tmp1 = SelectExpr(N.getOperand(0));
-      Tmp2 = SelectExpr(N.getOperand(1));
-      BuildMI(BB, DestType == MVT::f64 ? Alpha::DIVT : Alpha::DIVS, 2, Result)
-        .addReg(Tmp1).addReg(Tmp2);
-      return Result;
-    } else {
+    {
       //check if we can convert into a shift!
       if (isSIntImmediate(N.getOperand(1), SImm) &&
           SImm != 0 && isPowerOf2_64(llabs(SImm))) {
diff --git a/lib/Target/IA64/IA64ISelPattern.cpp b/lib/Target/IA64/IA64ISelPattern.cpp
index 3af4a97..04b331c 100644
--- a/lib/Target/IA64/IA64ISelPattern.cpp
+++ b/lib/Target/IA64/IA64ISelPattern.cpp
@@ -72,8 +72,8 @@
       setOperationAction(ISD::SEXTLOAD         , MVT::i16  , Expand);
       setOperationAction(ISD::SEXTLOAD         , MVT::i32  , Expand);
 
-      setOperationAction(ISD::SREM             , MVT::f32  , Expand);
-      setOperationAction(ISD::SREM             , MVT::f64  , Expand);
+      setOperationAction(ISD::FREM             , MVT::f32  , Expand);
+      setOperationAction(ISD::FREM             , MVT::f64  , Expand);
 
       setOperationAction(ISD::UREM             , MVT::f32  , Expand);
       setOperationAction(ISD::UREM             , MVT::f64  , Expand);
@@ -1240,20 +1240,28 @@
     BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(Tmp2);
     return Result;
   }
-
-  case ISD::ADD: {
-    if(DestType == MVT::f64 && N.getOperand(0).getOpcode() == ISD::MUL &&
-       N.getOperand(0).Val->hasOneUse()) { // if we can fold this add
-                                           // into an fma, do so:
-      // ++FusedFP; // Statistic
+    
+  case ISD::FADD: {
+    if (N.getOperand(0).getOpcode() == ISD::FMUL &&
+        N.getOperand(0).Val->hasOneUse()) { // if we can fold this add
+                                            // into an fma, do so:
+                                            // ++FusedFP; // Statistic
       Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
       Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
       Tmp3 = SelectExpr(N.getOperand(1));
       BuildMI(BB, IA64::FMA, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
       return Result; // early exit
     }
+    
+    //else, fallthrough:
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+    BuildMI(BB, IA64::FADD, 2, Result).addReg(Tmp1).addReg(Tmp2);
+    return Result;
+  }
 
-    if(DestType != MVT::f64 && N.getOperand(0).getOpcode() == ISD::SHL &&
+  case ISD::ADD: {
+    if (N.getOperand(0).getOpcode() == ISD::SHL &&
         N.getOperand(0).Val->hasOneUse()) { // if we might be able to fold
                                             // this add into a shladd, try:
       ConstantSDNode *CSD = NULL;
@@ -1273,75 +1281,71 @@
 
     //else, fallthrough:
     Tmp1 = SelectExpr(N.getOperand(0));
-    if(DestType != MVT::f64) { // integer addition:
-        switch (ponderIntegerAdditionWith(N.getOperand(1), Tmp3)) {
-          case 1: // adding a constant that's 14 bits
-            BuildMI(BB, IA64::ADDIMM14, 2, Result).addReg(Tmp1).addSImm(Tmp3);
-            return Result; // early exit
-        } // fallthrough and emit a reg+reg ADD:
-        Tmp2 = SelectExpr(N.getOperand(1));
-        BuildMI(BB, IA64::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2);
-    } else { // this is a floating point addition
-      Tmp2 = SelectExpr(N.getOperand(1));
-      BuildMI(BB, IA64::FADD, 2, Result).addReg(Tmp1).addReg(Tmp2);
-    }
+    switch (ponderIntegerAdditionWith(N.getOperand(1), Tmp3)) {
+      case 1: // adding a constant that's 14 bits
+        BuildMI(BB, IA64::ADDIMM14, 2, Result).addReg(Tmp1).addSImm(Tmp3);
+        return Result; // early exit
+    } // fallthrough and emit a reg+reg ADD:
+    Tmp2 = SelectExpr(N.getOperand(1));
+    BuildMI(BB, IA64::ADD, 2, Result).addReg(Tmp1).addReg(Tmp2);
     return Result;
   }
 
+  case ISD::FMUL: 
+    Tmp1 = SelectExpr(N.getOperand(0));
+    Tmp2 = SelectExpr(N.getOperand(1));
+    BuildMI(BB, IA64::FMPY, 2, Result).addReg(Tmp1).addReg(Tmp2);
+    return Result;
+    
   case ISD::MUL: {
 
-    if(DestType != MVT::f64) { // TODO: speed!
+    // TODO: speed!
 /* FIXME if(N.getOperand(1).getOpcode() != ISD::Constant) { // if not a const mul
  */
-        // boring old integer multiply with xma
-        Tmp1 = SelectExpr(N.getOperand(0));
-        Tmp2 = SelectExpr(N.getOperand(1));
-
-        unsigned TempFR1=MakeReg(MVT::f64);
-        unsigned TempFR2=MakeReg(MVT::f64);
-        unsigned TempFR3=MakeReg(MVT::f64);
-        BuildMI(BB, IA64::SETFSIG, 1, TempFR1).addReg(Tmp1);
-        BuildMI(BB, IA64::SETFSIG, 1, TempFR2).addReg(Tmp2);
-        BuildMI(BB, IA64::XMAL, 1, TempFR3).addReg(TempFR1).addReg(TempFR2)
-          .addReg(IA64::F0);
-        BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(TempFR3);
-        return Result; // early exit
-     /* FIXME } else { // we are multiplying by an integer constant! yay
-        return Reg = SelectExpr(BuildConstmulSequence(N)); // avert your eyes!
-      } */
-    }
-    else { // floating point multiply
+      // boring old integer multiply with xma
       Tmp1 = SelectExpr(N.getOperand(0));
       Tmp2 = SelectExpr(N.getOperand(1));
-      BuildMI(BB, IA64::FMPY, 2, Result).addReg(Tmp1).addReg(Tmp2);
-      return Result;
-    }
+
+      unsigned TempFR1=MakeReg(MVT::f64);
+      unsigned TempFR2=MakeReg(MVT::f64);
+      unsigned TempFR3=MakeReg(MVT::f64);
+      BuildMI(BB, IA64::SETFSIG, 1, TempFR1).addReg(Tmp1);
+      BuildMI(BB, IA64::SETFSIG, 1, TempFR2).addReg(Tmp2);
+      BuildMI(BB, IA64::XMAL, 1, TempFR3).addReg(TempFR1).addReg(TempFR2)
+        .addReg(IA64::F0);
+      BuildMI(BB, IA64::GETFSIG, 1, Result).addReg(TempFR3);
+      return Result; // early exit
+   /* FIXME } else { // we are multiplying by an integer constant! yay
+      return Reg = SelectExpr(BuildConstmulSequence(N)); // avert your eyes!
+    } */
   }
 
-  case ISD::SUB: {
-    if(DestType == MVT::f64 && N.getOperand(0).getOpcode() == ISD::MUL &&
+  case ISD::FSUB:
+    if(N.getOperand(0).getOpcode() == ISD::FMUL &&
        N.getOperand(0).Val->hasOneUse()) { // if we can fold this sub
                                            // into an fms, do so:
-      // ++FusedFP; // Statistic
+                                           // ++FusedFP; // Statistic
       Tmp1 = SelectExpr(N.getOperand(0).getOperand(0));
       Tmp2 = SelectExpr(N.getOperand(0).getOperand(1));
       Tmp3 = SelectExpr(N.getOperand(1));
       BuildMI(BB, IA64::FMS, 3, Result).addReg(Tmp1).addReg(Tmp2).addReg(Tmp3);
       return Result; // early exit
     }
+
     Tmp2 = SelectExpr(N.getOperand(1));
-    if(DestType != MVT::f64) { // integer subtraction:
-        switch (ponderIntegerSubtractionFrom(N.getOperand(0), Tmp3)) {
-          case 1: // subtracting *from* an 8 bit constant:
-            BuildMI(BB, IA64::SUBIMM8, 2, Result).addSImm(Tmp3).addReg(Tmp2);
-            return Result; // early exit
-        } // fallthrough and emit a reg+reg SUB:
-        Tmp1 = SelectExpr(N.getOperand(0));
-        BuildMI(BB, IA64::SUB, 2, Result).addReg(Tmp1).addReg(Tmp2);
-    } else { // this is a floating point subtraction
-      Tmp1 = SelectExpr(N.getOperand(0));
-      BuildMI(BB, IA64::FSUB, 2, Result).addReg(Tmp1).addReg(Tmp2);
-    }
+    Tmp1 = SelectExpr(N.getOperand(0));
+    BuildMI(BB, IA64::FSUB, 2, Result).addReg(Tmp1).addReg(Tmp2);
+    return Result;
+    
+  case ISD::SUB: {
+    Tmp2 = SelectExpr(N.getOperand(1));
+    switch (ponderIntegerSubtractionFrom(N.getOperand(0), Tmp3)) {
+      case 1: // subtracting *from* an 8 bit constant:
+        BuildMI(BB, IA64::SUBIMM8, 2, Result).addSImm(Tmp3).addReg(Tmp2);
+        return Result; // early exit
+    } // fallthrough and emit a reg+reg SUB:
+    Tmp1 = SelectExpr(N.getOperand(0));
+    BuildMI(BB, IA64::SUB, 2, Result).addReg(Tmp1).addReg(Tmp2);
     return Result;
   }
 
@@ -1584,6 +1588,7 @@
     return Result;
   }
 
+  case ISD::FDIV:
   case ISD::SDIV:
   case ISD::UDIV:
   case ISD::SREM:
@@ -1601,8 +1606,10 @@
     bool isSigned=false;
 
     switch(N.getOpcode()) {
+      case ISD::FDIV:
       case ISD::SDIV:  isModulus=false; isSigned=true;  break;
       case ISD::UDIV:  isModulus=false; isSigned=false; break;
+      case ISD::FREM:
       case ISD::SREM:  isModulus=true;  isSigned=true;  break;
       case ISD::UREM:  isModulus=true;  isSigned=false; break;
     }
diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp
index f3ce7a7..36596be 100644
--- a/lib/Target/X86/X86ISelPattern.cpp
+++ b/lib/Target/X86/X86ISelPattern.cpp
@@ -158,7 +158,7 @@
       setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1   , Expand);
       setOperationAction(ISD::FP_ROUND_INREG   , MVT::f32  , Expand);
       setOperationAction(ISD::SEXTLOAD         , MVT::i1   , Expand);
-      setOperationAction(ISD::SREM             , MVT::f64  , Expand);
+      setOperationAction(ISD::FREM             , MVT::f64  , Expand);
       setOperationAction(ISD::CTPOP            , MVT::i8   , Expand);
       setOperationAction(ISD::CTTZ             , MVT::i8   , Expand);
       setOperationAction(ISD::CTLZ             , MVT::i8   , Expand);
@@ -205,12 +205,12 @@
         setOperationAction(ISD::FCOS , MVT::f64, Expand);
         setOperationAction(ISD::FABS , MVT::f64, Expand);
         setOperationAction(ISD::FNEG , MVT::f64, Expand);
-        setOperationAction(ISD::SREM , MVT::f64, Expand);
+        setOperationAction(ISD::FREM , MVT::f64, Expand);
         setOperationAction(ISD::FSIN , MVT::f32, Expand);
         setOperationAction(ISD::FCOS , MVT::f32, Expand);
         setOperationAction(ISD::FABS , MVT::f32, Expand);
         setOperationAction(ISD::FNEG , MVT::f32, Expand);
-        setOperationAction(ISD::SREM , MVT::f32, Expand);
+        setOperationAction(ISD::FREM , MVT::f32, Expand);
 
         addLegalFPImmediate(+0.0); // xorps / xorpd
       } else {
@@ -2513,6 +2513,7 @@
     }
     return Result;
 
+  case ISD::FADD:
   case ISD::ADD:
     Op0 = N.getOperand(0);
     Op1 = N.getOperand(1);
@@ -2703,6 +2704,8 @@
     return Result;
   }
 
+  case ISD::FSUB:
+  case ISD::FMUL:
   case ISD::SUB:
   case ISD::MUL:
   case ISD::AND:
@@ -2810,7 +2813,9 @@
       }
       switch (Node->getOpcode()) {
       default: assert(0 && "Unreachable!");
+      case ISD::FSUB:
       case ISD::SUB: Opc = X86ScalarSSE ? SSE_SUBTab[Opc] : SUBTab[Opc]; break;
+      case ISD::FMUL:
       case ISD::MUL: Opc = X86ScalarSSE ? SSE_MULTab[Opc] : MULTab[Opc]; break;
       case ISD::AND: Opc = ANDTab[Opc]; break;
       case ISD::OR:  Opc =  ORTab[Opc]; break;
@@ -2824,7 +2829,7 @@
     }
 
     if (isFoldableLoad(Op0, Op1, true))
-      if (Node->getOpcode() != ISD::SUB) {
+      if (Node->getOpcode() != ISD::SUB && Node->getOpcode() != ISD::FSUB) {
         std::swap(Op0, Op1);
         goto FoldOps;
       } else {
@@ -2860,7 +2865,9 @@
       }
       switch (Node->getOpcode()) {
       default: assert(0 && "Unreachable!");
+      case ISD::FSUB:
       case ISD::SUB: Opc = X86ScalarSSE ? SSE_SUBTab[Opc] : SUBTab[Opc]; break;
+      case ISD::FMUL:
       case ISD::MUL: Opc = X86ScalarSSE ? SSE_MULTab[Opc] : MULTab[Opc]; break;
       case ISD::AND: Opc = ANDTab[Opc]; break;
       case ISD::OR:  Opc =  ORTab[Opc]; break;
@@ -2902,7 +2909,9 @@
     }
     switch (Node->getOpcode()) {
     default: assert(0 && "Unreachable!");
+    case ISD::FSUB:
     case ISD::SUB: Opc = X86ScalarSSE ? SSE_SUBTab[Opc] : SUBTab[Opc]; break;
+    case ISD::FMUL:
     case ISD::MUL: Opc = X86ScalarSSE ? SSE_MULTab[Opc] : MULTab[Opc]; break;
     case ISD::AND: Opc = ANDTab[Opc]; break;
     case ISD::OR:  Opc =  ORTab[Opc]; break;
@@ -3006,6 +3015,8 @@
                  N.getValueType(), Result);
     return Result;
 
+  case ISD::FDIV:
+  case ISD::FREM:
   case ISD::SDIV:
   case ISD::UDIV:
   case ISD::SREM:
@@ -3013,7 +3024,7 @@
     assert((N.getOpcode() != ISD::SREM || MVT::isInteger(N.getValueType())) &&
            "We don't support this operator!");
 
-    if (N.getOpcode() == ISD::SDIV) {
+    if (N.getOpcode() == ISD::SDIV || N.getOpcode() == ISD::FDIV) {
       // We can fold loads into FpDIVs, but not really into any others.
       if (N.getValueType() == MVT::f64 && !X86ScalarSSE) {
         // Check for reversed and unreversed DIV.
@@ -3756,9 +3767,12 @@
   default:
     std::cerr << "CANNOT [mem] op= val: ";
     StVal.Val->dump(); std::cerr << "\n";
+  case ISD::FMUL:
   case ISD::MUL:
+  case ISD::FDIV:
   case ISD::SDIV:
   case ISD::UDIV:
+  case ISD::FREM:
   case ISD::SREM:
   case ISD::UREM: return false;
 
@@ -3837,7 +3851,8 @@
 
   // If we have [mem] = V op [mem], try to turn it into:
   // [mem] = [mem] op V.
-  if (Op1 == TheLoad && StVal.getOpcode() != ISD::SUB &&
+  if (Op1 == TheLoad && 
+      StVal.getOpcode() != ISD::SUB && StVal.getOpcode() != ISD::FSUB &&
       StVal.getOpcode() != ISD::SHL && StVal.getOpcode() != ISD::SRA &&
       StVal.getOpcode() != ISD::SRL)
     std::swap(Op0, Op1);