Always use FP stack instructions to perform i64 to f64 as well as f64 to i64
authorEvan Cheng <evan.cheng@apple.com>
Mon, 30 Jan 2006 08:02:57 +0000 (08:02 +0000)
committerEvan Cheng <evan.cheng@apple.com>
Mon, 30 Jan 2006 08:02:57 +0000 (08:02 +0000)
conversions. SSE does not have instructions to handle these tasks.

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

lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86ISelLowering.h
lib/Target/X86/X86InstrInfo.td

index 9503bc13c48c87407fa95a4ce56ed2c607897022..e71ce868d4fcf3954b98a4d83fb07cf1e1f68c05 100644 (file)
@@ -68,11 +68,12 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   setOperationAction(ISD::SINT_TO_FP       , MVT::i1   , Promote);
   setOperationAction(ISD::SINT_TO_FP       , MVT::i8   , Promote);
 
+  // We can handle SINT_TO_FP and FP_TO_SINT from/to i64 even though i64
+  // isn't legal.
+  setOperationAction(ISD::SINT_TO_FP       , MVT::i64  , Custom);
+  setOperationAction(ISD::FP_TO_SINT       , MVT::i64  , Custom);
+
   if (!X86ScalarSSE) {
-    // We can handle SINT_TO_FP and FP_TO_SINT from/TO i64 even though i64
-    // isn't legal.
-    setOperationAction(ISD::SINT_TO_FP     , MVT::i64  , Custom);
-    setOperationAction(ISD::FP_TO_SINT     , MVT::i64  , Custom);
     setOperationAction(ISD::FP_TO_SINT     , MVT::i32  , Custom);
     setOperationAction(ISD::FP_TO_SINT     , MVT::i16  , Custom);
   }
@@ -526,12 +527,11 @@ X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy,
         Chain  = RetVal.getValue(1);
         InFlag = RetVal.getValue(2);
         if (X86ScalarSSE) {
-          // FIXME:Currently the FST is flagged to the FP_GET_RESULT. This
-          // shouldn't be necessary except for RFP cannot be live across
+          // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This
+          // shouldn't be necessary except that RFP cannot be live across
           // multiple blocks. When stackifier is fixed, they can be uncoupled.
-          unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
           MachineFunction &MF = DAG.getMachineFunction();
-          int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
+          int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
           SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
           Tys.clear();
           Tys.push_back(MVT::Other);
@@ -1027,12 +1027,11 @@ X86TargetLowering::LowerFastCCCallTo(SDOperand Chain, const Type *RetTy,
         Chain  = RetVal.getValue(1);
         InFlag = RetVal.getValue(2);
         if (X86ScalarSSE) {
-          // FIXME:Currently the FST is flagged to the FP_GET_RESULT. This
-          // shouldn't be necessary except for RFP cannot be live across
+          // FIXME: Currently the FST is flagged to the FP_GET_RESULT. This
+          // shouldn't be necessary except that RFP cannot be live across
           // multiple blocks. When stackifier is fixed, they can be uncoupled.
-          unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
           MachineFunction &MF = DAG.getMachineFunction();
-          int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
+          int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
           SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
           Tys.clear();
           Tys.push_back(MVT::Other);
@@ -1461,12 +1460,38 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     // Build the FILD
     std::vector<MVT::ValueType> Tys;
     Tys.push_back(MVT::f64);
+    Tys.push_back(MVT::Other);
     Tys.push_back(MVT::Flag);
     std::vector<SDOperand> Ops;
     Ops.push_back(Chain);
     Ops.push_back(StackSlot);
     Ops.push_back(DAG.getValueType(SrcVT));
     Result = DAG.getNode(X86ISD::FILD, Tys, Ops);
+
+    if (X86ScalarSSE) {
+      assert(Op.getValueType() == MVT::f64 && "Invalid SINT_TO_FP to lower!");
+      Chain = Result.getValue(1);
+      SDOperand InFlag = Result.getValue(2);
+
+      // FIXME: Currently the FST is flagged to the FILD. This
+      // shouldn't be necessary except that RFP cannot be live across
+      // multiple blocks. When stackifier is fixed, they can be uncoupled.
+      MachineFunction &MF = DAG.getMachineFunction();
+      int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
+      SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
+      std::vector<MVT::ValueType> Tys;
+      Tys.push_back(MVT::Other);
+      std::vector<SDOperand> Ops;
+      Ops.push_back(Chain);
+      Ops.push_back(Result);
+      Ops.push_back(StackSlot);
+      Ops.push_back(DAG.getValueType(MVT::f64));
+      Ops.push_back(InFlag);
+      Chain = DAG.getNode(X86ISD::FST, Tys, Ops);
+      Result = DAG.getLoad(Op.getValueType(), Chain, StackSlot,
+                           DAG.getSrcValue(NULL));
+    }
+
     return Result;
   }
   case ISD::FP_TO_SINT: {
@@ -1488,10 +1513,29 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
     case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break;
     }
 
+    SDOperand Chain = DAG.getEntryNode();
+    SDOperand Value = Op.getOperand(0);
+    if (X86ScalarSSE) {
+      assert(Op.getValueType() == MVT::i64 && "Invalid FP_TO_SINT to lower!");
+      Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Value, StackSlot, 
+                          DAG.getSrcValue(0));
+      std::vector<MVT::ValueType> Tys;
+      Tys.push_back(MVT::f64);
+      Tys.push_back(MVT::Other);
+      std::vector<SDOperand> Ops;
+      Ops.push_back(Chain);
+      Ops.push_back(StackSlot);
+      Ops.push_back(DAG.getValueType(MVT::f64));
+      Value = DAG.getNode(X86ISD::FLD, Tys, Ops);
+      Chain = Value.getValue(1);
+      SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
+      StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
+    }
+
     // Build the FP_TO_INT*_IN_MEM
     std::vector<SDOperand> Ops;
-    Ops.push_back(DAG.getEntryNode());
-    Ops.push_back(Op.getOperand(0));
+    Ops.push_back(Chain);
+    Ops.push_back(Value);
     Ops.push_back(StackSlot);
     SDOperand FIST = DAG.getNode(Opc, MVT::Other, Ops);
 
index fc601702d5c2a3cf7d282ea1af1b8bdb2bf31446..81ce0911d56183a930592928c74a23e999251329 100644 (file)
@@ -44,7 +44,7 @@ namespace llvm {
       /// FILD - This instruction implements SINT_TO_FP with the integer source
       /// in memory and FP reg result.  This corresponds to the X86::FILD*m
       /// instructions. It has three inputs (token chain, address, and source
-      /// type) and two outputs (FP value and token chain).
+      /// type) and three outputs (FP value, token chain, and a flag).
       FILD,
 
       /// FP_TO_INT*_IN_MEM - This instruction implements FP_TO_SINT with the
index b3941b4fc5753e411934f4b7baf0542bac51eeb7..5c620627b2ae1431518d933d01643443ff8073c7 100644 (file)
@@ -103,7 +103,7 @@ def X86fld     : SDNode<"X86ISD::FLD",      SDTX86Fld,
 def X86fst     : SDNode<"X86ISD::FST",      SDTX86Fst,
                         [SDNPHasChain, SDNPInFlag]>;
 def X86fild    : SDNode<"X86ISD::FILD",     SDTX86Fild,
-                        [SDNPHasChain]>;
+                        [SDNPHasChain, SDNPOutFlag]>;
 def X86fp_to_i16mem : SDNode<"X86ISD::FP_TO_INT16_IN_MEM", SDTX86FpToIMem,
                         [SDNPHasChain]>;
 def X86fp_to_i32mem : SDNode<"X86ISD::FP_TO_INT32_IN_MEM", SDTX86FpToIMem,
@@ -3018,10 +3018,13 @@ def : Pat<(X86fld addr:$src, f64), (FpLD64m addr:$src)>;
 def : Pat<(X86fst RFP:$src, addr:$op, f32), (FpST32m addr:$op, RFP:$src)>;
 def : Pat<(X86fst RFP:$src, addr:$op, f64), (FpST64m addr:$op, RFP:$src)>;
 
-// Floatin point constant -0.0 and -1.0
+// Floating point constant -0.0 and -1.0
 def : Pat<(f64 fp64immneg0), (FpCHS (FpLD0))>, Requires<[FPStack]>;
 def : Pat<(f64 fp64immneg1), (FpCHS (FpLD1))>, Requires<[FPStack]>;
 
+// Used to conv. i64 to f64 since there isn't a SSE version.
+def : Pat<(X86fild addr:$src, i64), (FpILD64m addr:$src)>, Requires<[HasSSE2]>;
+
 //===----------------------------------------------------------------------===//
 // Some peepholes
 //===----------------------------------------------------------------------===//