[llvm-commits] CVS: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp X86ISelLowering.cpp X86InstrInfo.td

Evan Cheng evan.cheng at apple.com
Tue Jan 10 12:27:08 PST 2006



Changes in directory llvm/lib/Target/X86:

X86ISelDAGToDAG.cpp updated: 1.25 -> 1.26
X86ISelLowering.cpp updated: 1.25 -> 1.26
X86InstrInfo.td updated: 1.192 -> 1.193
---
Log message:

FP_TO_INT*_IN_MEM and x87 FP Select support.


---
Diffs of the changes:  (+131 -21)

 X86ISelDAGToDAG.cpp |   58 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 X86ISelLowering.cpp |   53 +++++++++++++++++++++++++++++++++++++----------
 X86InstrInfo.td     |   41 +++++++++++++++++++++++++++---------
 3 files changed, 131 insertions(+), 21 deletions(-)


Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.25 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.26
--- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.25	Mon Jan  9 17:10:28 2006
+++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp	Tue Jan 10 14:26:56 2006
@@ -18,6 +18,7 @@
 #include "llvm/GlobalValue.h"
 #include "llvm/CodeGen/MachineConstantPool.h"
 #include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Support/Debug.h"
@@ -550,6 +551,63 @@
         return CodeGenMap[N] = CurDAG->getTargetNode(Opc, VT, Result);
       break;
     }
+
+    case X86ISD::FP_TO_INT16_IN_MEM:
+    case X86ISD::FP_TO_INT32_IN_MEM:
+    case X86ISD::FP_TO_INT64_IN_MEM: {
+      assert(N.getOperand(1).getValueType() == MVT::f64);
+
+      // Change the floating point control register to use "round towards zero"
+      // mode when truncating to an integer value.
+      MachineFunction &MF = CurDAG->getMachineFunction();
+      int CWFI = MF.getFrameInfo()->CreateStackObject(2, 2);
+      SDOperand CWSlot = CurDAG->getFrameIndex(CWFI, MVT::i32);
+      SDOperand Base, Scale, Index, Disp;
+      (void)SelectAddr(CWSlot, Base, Scale, Index, Disp);
+      SDOperand Chain = N.getOperand(0);
+
+      // Save the control word.
+      Chain = CurDAG->getTargetNode(X86::FNSTCW16m, MVT::Other,
+                                    Base, Scale, Index, Disp, Chain);
+
+      // Load the old value of the high byte of the control word.
+      SDOperand OldCW =
+        CurDAG->getTargetNode(X86::MOV16rm, MVT::i16, MVT::Other,
+                              Base, Scale, Index, Disp, Chain);
+      Chain = OldCW.getValue(1);
+
+      // Set the high part to be round to zero...
+      Chain = CurDAG->getTargetNode(X86::MOV16mi, MVT::Other,
+                                    Base, Scale, Index, Disp, 
+                                    CurDAG->getConstant(0xC7F, MVT::i16),
+                                    Chain);
+
+      // Reload the modified control word now...
+      Chain = CurDAG->getTargetNode(X86::FLDCW16m, MVT::Other,
+                                    Base, Scale, Index, Disp, Chain);
+
+      // Restore the memory image of control word to original value
+      Chain = CurDAG->getTargetNode(X86::MOV16mr, MVT::Other, 
+                                    Base, Scale, Index, Disp, OldCW, Chain);
+
+      switch (Opcode) {
+      case X86ISD::FP_TO_INT16_IN_MEM: Opc = X86::FpIST16m; break;
+      case X86ISD::FP_TO_INT32_IN_MEM: Opc = X86::FpIST32m; break;
+      case X86ISD::FP_TO_INT64_IN_MEM: Opc = X86::FpIST64m; break;
+      }
+
+      SDOperand N1 = Select(N.getOperand(1));
+      SDOperand Base2, Scale2, Index2, Disp2;
+      (void)SelectAddr(N.getOperand(2), Base2, Scale2, Index2, Disp2);
+      Chain = CurDAG->getTargetNode(Opc, MVT::Other,
+                                    Base2, Scale2, Index2, Disp2, N1, Chain);
+
+      // Reload the modified control word now...
+      CodeGenMap[N] =
+        Chain = CurDAG->getTargetNode(X86::FLDCW16m, MVT::Other,
+                                      Base, Scale, Index, Disp, Chain);
+      return Chain;
+    }
   }
 
   return SelectCode(N);


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.25 llvm/lib/Target/X86/X86ISelLowering.cpp:1.26
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.25	Mon Jan  9 16:29:54 2006
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Tue Jan 10 14:26:56 2006
@@ -1192,6 +1192,26 @@
   return X86CC;
 }
 
+/// SupportedByFPCMOV - is there a floating point cmov for the specific
+/// X86 condition code.
+/// Current x86 isa includes the following FP cmov instructions:
+/// fcmovb, fcomvbe, fcomve, fcmovu, fcmovae, fcmova, fcmovne, fcmovnu.
+static bool SupportedByFPCMOV(unsigned X86CC) {
+  switch (X86CC) {
+  default:
+    return false;
+  case X86ISD::COND_B:
+  case X86ISD::COND_BE:
+  case X86ISD::COND_E:
+  case X86ISD::COND_P:
+  case X86ISD::COND_A:
+  case X86ISD::COND_AE:
+  case X86ISD::COND_NE:
+  case X86ISD::COND_NP:
+    return true;
+  }
+}
+
 /// LowerOperation - Provide custom lowering hooks for some operations.
 ///
 SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
@@ -1444,21 +1464,32 @@
     }
   }
   case ISD::SELECT: {
-    SDOperand Cond  = Op.getOperand(0);
-    SDOperand CC;
-    if (Cond.getOpcode() == X86ISD::SETCC) {
-      CC = Cond.getOperand(0);
-      Cond = Cond.getOperand(1);
-    } else if (Cond.getOpcode() == ISD::SETCC) {
-      CC = Cond.getOperand(2);
-      bool isFP = MVT::isFloatingPoint(Cond.getOperand(1).getValueType());
+    MVT::ValueType VT = Op.getValueType();
+    bool isFP      = MVT::isFloatingPoint(VT);
+    bool isFPStack = isFP && (X86Vector < SSE2);
+    bool isFPSSE   = isFP && (X86Vector >= SSE2);
+    bool isValid   = false;
+    SDOperand Op0 = Op.getOperand(0);
+    SDOperand Cond, CC;
+    if (Op0.getOpcode() == X86ISD::SETCC) {
+      CC   = Op0.getOperand(0);
+      Cond = Op0.getOperand(1);
+      isValid =
+        !(isFPStack &&
+          !SupportedByFPCMOV(cast<ConstantSDNode>(CC)->getSignExtended()));
+    } else if (Op0.getOpcode() == ISD::SETCC) {
+      CC = Op0.getOperand(2);
+      bool isFP = MVT::isFloatingPoint(Op0.getOperand(1).getValueType());
       unsigned X86CC = CCToX86CondCode(CC, isFP);
       CC = DAG.getConstant(X86CC, MVT::i8);
       Cond = DAG.getNode(X86ISD::CMP, MVT::Flag,
-                         Cond.getOperand(0), Cond.getOperand(1));
-    } else {
+                         Op0.getOperand(0), Op0.getOperand(1));
+      isValid = true;
+    }
+
+    if (!isValid) {
       CC = DAG.getConstant(X86ISD::COND_E, MVT::i8);
-      Cond = DAG.getNode(X86ISD::TEST, MVT::Flag, Cond, Cond);
+      Cond = DAG.getNode(X86ISD::TEST, MVT::Flag, Op0, Op0);
     }
 
     std::vector<MVT::ValueType> Tys;


Index: llvm/lib/Target/X86/X86InstrInfo.td
diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.192 llvm/lib/Target/X86/X86InstrInfo.td:1.193
--- llvm/lib/Target/X86/X86InstrInfo.td:1.192	Mon Jan  9 17:10:28 2006
+++ llvm/lib/Target/X86/X86InstrInfo.td	Tue Jan 10 14:26:56 2006
@@ -377,6 +377,13 @@
 def IMPLICIT_DEF_R32  : I<0, Pseudo, (ops R32:$dst),
                          "#IMPLICIT_DEF $dst",
                          [(set R32:$dst, (undef))]>;
+def IMPLICIT_DEF_FR32 : I<0, Pseudo, (ops FR32:$dst),
+                         "#IMPLICIT_DEF $dst",
+                         [(set FR32:$dst, (undef))]>, Requires<[HasSSE2]>;
+def IMPLICIT_DEF_FR64 : I<0, Pseudo, (ops FR64:$dst),
+                         "#IMPLICIT_DEF $dst",
+                         [(set FR64:$dst, (undef))]>, Requires<[HasSSE2]>;
+
 
 let isTerminator = 1 in
   let Defs = [FP0, FP1, FP2, FP3, FP4, FP5, FP6] in
@@ -2687,14 +2694,30 @@
 
 // Floating point cmovs.
 let isTwoAddress = 1 in {
-  def FpCMOVB  : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
-  def FpCMOVBE : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
-  def FpCMOVE  : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
-  def FpCMOVP  : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
-  def FpCMOVAE : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
-  def FpCMOVA  : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
-  def FpCMOVNE : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
-  def FpCMOVNP : FpI<(ops RST:$dst, RFP:$src1, RFP:$src2), CondMovFP, []>;
+  def FpCMOVB  : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
+                     [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
+                                      X86_COND_B, STATUS))]>;
+  def FpCMOVBE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
+                     [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
+                                      X86_COND_BE, STATUS))]>;
+  def FpCMOVE  : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
+                     [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
+                                      X86_COND_E, STATUS))]>;
+  def FpCMOVP  : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
+                     [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
+                                      X86_COND_P, STATUS))]>;
+  def FpCMOVAE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
+                     [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
+                                      X86_COND_AE, STATUS))]>;
+  def FpCMOVA  : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
+                     [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
+                                      X86_COND_A, STATUS))]>;
+  def FpCMOVNE : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
+                     [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
+                                      X86_COND_NE, STATUS))]>;
+  def FpCMOVNP : FpI<(ops RFP:$dst, RFP:$src1, RFP:$src2), CondMovFP,
+                     [(set RFP:$dst, (X86cmov RFP:$src1, RFP:$src2,
+                                      X86_COND_NP, STATUS))]>;
 }
 
 def FCMOVB  : FPI<0xC0, AddRegFrm, (ops RST:$op),
@@ -2866,8 +2889,6 @@
 def : Pat<(f64 fp64immneg0), (FpCHS (FpLD0))>, Requires<[FPStack]>;
 def : Pat<(f64 fp64immneg1), (FpCHS (FpLD1))>, Requires<[FPStack]>;
 
-// FR64 undef
-def : Pat<(f64 (undef)), (FLD0SD)>, Requires<[HasSSE2]>;
 // RFP undef
 def : Pat<(f64 (undef)), (FpLD0)>,  Requires<[FPStack]>;
 






More information about the llvm-commits mailing list