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

Evan Cheng evan.cheng at apple.com
Wed Jan 4 16:27:14 PST 2006



Changes in directory llvm/lib/Target/X86:

X86ISelDAGToDAG.cpp updated: 1.19 -> 1.20
X86ISelLowering.cpp updated: 1.18 -> 1.19
X86ISelLowering.h updated: 1.9 -> 1.10
X86InstrInfo.td updated: 1.186 -> 1.187
---
Log message:

DAG based isel call support.


---
Diffs of the changes:  (+197 -41)

 X86ISelDAGToDAG.cpp |   27 +++++++++
 X86ISelLowering.cpp |  141 ++++++++++++++++++++++++++++++++++++++++------------
 X86ISelLowering.h   |   11 ++++
 X86InstrInfo.td     |   59 +++++++++++++++++----
 4 files changed, 197 insertions(+), 41 deletions(-)


Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.19 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.20
--- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.19	Wed Dec 21 17:05:39 2005
+++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp	Wed Jan  4 18:27:02 2006
@@ -410,6 +410,33 @@
       return CodeGenMap[N] = CurDAG->getTargetNode(Opc, VT, Result);
       break;
     }
+
+    case ISD::ConstantFP: {
+      Opc = 0;
+      if (X86ScalarSSE) {
+        assert(cast<ConstantFPSDNode>(N)->isExactlyValue(+0.0) &&
+               "SSE only supports +0.0");
+        Opc = (NVT == MVT::f32) ? X86::FLD0SS : X86::FLD0SD;
+      }
+
+      if (cast<ConstantFPSDNode>(N)->isExactlyValue(+0.0) ||
+          cast<ConstantFPSDNode>(N)->isExactlyValue(-0.0))
+        Opc = X86::FpLD0;
+      else if (cast<ConstantFPSDNode>(N)->isExactlyValue(+1.0) ||
+               cast<ConstantFPSDNode>(N)->isExactlyValue(-1.0))
+        Opc = X86::FpLD1;
+
+      assert(Opc != 0 && "Unexpected constant!");
+
+      SDOperand Result = CurDAG->getTargetNode(Opc, NVT);
+
+      if (cast<ConstantFPSDNode>(N)->getValue() < 0.0 ||
+          cast<ConstantFPSDNode>(N)->isExactlyValue(-0.0))
+        Result = CurDAG->getTargetNode(X86::FpCHS, NVT, Result);
+
+      CodeGenMap[N] = Result;
+      return Result;
+    }
   }
 
   return SelectCode(N);


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.18 llvm/lib/Target/X86/X86ISelLowering.cpp:1.19
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.18	Mon Dec 26 21:02:18 2005
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Wed Jan  4 18:27:02 2006
@@ -457,38 +457,117 @@
     RetVals.push_back(MVT::i32);
     break;
   }
-  std::vector<SDOperand> Ops;
-  Ops.push_back(Chain);
-  Ops.push_back(Callee);
-  Ops.push_back(DAG.getConstant(NumBytes, getPointerTy()));
-  Ops.push_back(DAG.getConstant(0, getPointerTy()));
-  SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL,
-                                  RetVals, Ops);
-  Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall);
 
-  SDOperand ResultVal;
-  switch (RetTyVT) {
-  case MVT::isVoid: break;
-  default:
-    ResultVal = TheCall.getValue(1);
-    break;
-  case MVT::i1:
-  case MVT::i8:
-  case MVT::i16:
-    ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1));
-    break;
-  case MVT::f32:
-    // FIXME: we would really like to remember that this FP_ROUND operation is
-    // okay to eliminate if we allow excess FP precision.
-    ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1));
-    break;
-  case MVT::i64:
-    ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1),
-                            TheCall.getValue(2));
-    break;
-  }
+  if (X86DAGIsel) {
+    std::vector<MVT::ValueType> NodeTys;
+    NodeTys.push_back(MVT::Other);   // Returns a chain
+    NodeTys.push_back(MVT::Flag);    // Returns a flag for retval copy to use.
 
-  return std::make_pair(ResultVal, Chain);
+    std::vector<SDOperand> Ops;
+    Ops.push_back(Chain);
+    Ops.push_back(Callee);
+
+    Chain = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL,
+                        NodeTys, Ops);
+    SDOperand InFlag = Chain.getValue(1);
+
+    SDOperand RetVal;
+    if (RetTyVT != MVT::isVoid) {
+      switch (RetTyVT) {
+      default: assert(0 && "Unknown value type to return!");
+      case MVT::i1:
+      case MVT::i8:
+        RetVal = DAG.getCopyFromReg(Chain, X86::AL, MVT::i8, InFlag);
+        Chain = RetVal.getValue(1);
+        break;
+      case MVT::i16:
+        RetVal = DAG.getCopyFromReg(Chain, X86::AX, MVT::i16, InFlag);
+        Chain = RetVal.getValue(1);
+        break;
+      case MVT::i32:
+        RetVal = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag);
+        Chain = RetVal.getValue(1);
+        break;
+      case MVT::i64: {
+        SDOperand Lo = DAG.getCopyFromReg(Chain, X86::EAX, MVT::i32, InFlag);
+        SDOperand Hi = DAG.getCopyFromReg(Lo.getValue(1), X86::EDX, MVT::i32, 
+                                          Lo.getValue(2));
+        RetVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi);
+        Chain = Hi.getValue(1);
+        break;
+      }
+      case MVT::f32:
+      case MVT::f64: {
+        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(InFlag);
+        RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, Ops);
+        Chain = RetVal.getValue(1);
+        if (X86ScalarSSE) {
+          unsigned Size = MVT::getSizeInBits(MVT::f64)/8;
+          MachineFunction &MF = DAG.getMachineFunction();
+          int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
+          SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
+          Tys.clear();
+          Tys.push_back(MVT::Other);
+          Ops.clear();
+          Ops.push_back(Chain);
+          Ops.push_back(RetVal);
+          Ops.push_back(StackSlot);
+          Ops.push_back(DAG.getValueType(RetTyVT));
+          Chain = DAG.getNode(X86ISD::FST, Tys, Ops);
+          RetVal = DAG.getLoad(RetTyVT, Chain, StackSlot,
+                               DAG.getSrcValue(NULL));
+          Chain = RetVal.getValue(1);
+        } else if (RetTyVT == MVT::f32)
+          RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal);
+        break;
+      }
+      }
+    }
+
+    Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
+                        DAG.getConstant(NumBytes, getPointerTy()),
+                        DAG.getConstant(0, getPointerTy()));
+    return std::make_pair(RetVal, Chain);
+  } else {
+    std::vector<SDOperand> Ops;
+    Ops.push_back(Chain);
+    Ops.push_back(Callee);
+    Ops.push_back(DAG.getConstant(NumBytes, getPointerTy()));
+    Ops.push_back(DAG.getConstant(0, getPointerTy()));
+
+    SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL,
+                                    RetVals, Ops);
+
+    SDOperand ResultVal;
+    switch (RetTyVT) {
+    case MVT::isVoid: break;
+    default:
+      ResultVal = TheCall.getValue(1);
+      break;
+    case MVT::i1:
+    case MVT::i8:
+    case MVT::i16:
+      ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1));
+      break;
+    case MVT::f32:
+      // FIXME: we would really like to remember that this FP_ROUND operation is
+      // okay to eliminate if we allow excess FP precision.
+      ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1));
+      break;
+    case MVT::i64:
+      ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1),
+                              TheCall.getValue(2));
+      break;
+    }
+
+    Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall);
+    return std::make_pair(ResultVal, Chain);
+  }
 }
 
 SDOperand
@@ -1085,6 +1164,8 @@
   case X86ISD::FP_TO_INT32_IN_MEM: return "X86ISD::FP_TO_INT32_IN_MEM";
   case X86ISD::FP_TO_INT64_IN_MEM: return "X86ISD::FP_TO_INT64_IN_MEM";
   case X86ISD::FLD:                return "X86ISD::FLD";
+  case X86ISD::FST:                return "X86ISD::FST";
+  case X86ISD::FP_GET_RESULT:      return "X86ISD::FP_GET_RESULT";
   case X86ISD::FP_SET_RESULT:      return "X86ISD::FP_SET_RESULT";
   case X86ISD::CALL:               return "X86ISD::CALL";
   case X86ISD::TAILCALL:           return "X86ISD::TAILCALL";


Index: llvm/lib/Target/X86/X86ISelLowering.h
diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.9 llvm/lib/Target/X86/X86ISelLowering.h:1.10
--- llvm/lib/Target/X86/X86ISelLowering.h:1.9	Fri Dec 23 01:31:11 2005
+++ llvm/lib/Target/X86/X86ISelLowering.h	Wed Jan  4 18:27:02 2006
@@ -46,6 +46,17 @@
       /// to load to.
       FLD,
 
+      /// FST - This instruction implements a truncating store to FP stack
+      /// slots. This corresponds to the X86::FST32m / X86::FST64m. It takes a
+      /// chain operand, value to store, address, and a ValueType to store it
+      /// as.
+      FST,
+
+      /// FP_SET_RESULT - This corresponds to FpGETRESULT pseudo instrcuction
+      /// which copies from ST(0) to the destination. It takes a chain and writes
+      /// a RFP result and a chain.
+      FP_GET_RESULT,
+
       /// FP_SET_RESULT - This corresponds to FpSETRESULT pseudo instrcuction
       /// which copies the source operand to ST(0). It takes a chain and writes
       /// a chain and a flag.


Index: llvm/lib/Target/X86/X86InstrInfo.td
diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.186 llvm/lib/Target/X86/X86InstrInfo.td:1.187
--- llvm/lib/Target/X86/X86InstrInfo.td:1.186	Mon Dec 26 03:11:45 2005
+++ llvm/lib/Target/X86/X86InstrInfo.td	Wed Jan  4 18:27:02 2006
@@ -36,7 +36,11 @@
 
 def SDTX86Fld     : SDTypeProfile<1, 2, [SDTCisVT<0, f64>,
                                          SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
+def SDTX86Fst     : SDTypeProfile<0, 3, [SDTCisFP<0>,
+                                         SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
 
+
+def SDTX86FpGet   : SDTypeProfile<1, 0, [SDTCisVT<0, f64>]>;
 def SDTX86FpSet   : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
 
 def X86cmp     : SDNode<"X86ISD::CMP" ,     SDTX86CmpTest,  []>;
@@ -49,10 +53,24 @@
 def X86retflag : SDNode<"X86ISD::RET_FLAG", SDTX86RetFlag,  [SDNPHasChain]>;
 
 def X86fld     : SDNode<"X86ISD::FLD",      SDTX86Fld,      [SDNPHasChain]>;
+def X86fst     : SDNode<"X86ISD::FST",      SDTX86Fst,      [SDNPHasChain]>;
 
+def X86fpget   : SDNode<"X86ISD::FP_GET_RESULT",
+                                            SDTX86FpGet,    [SDNPHasChain]>;
 def X86fpset   : SDNode<"X86ISD::FP_SET_RESULT",
                                             SDTX86FpSet,    [SDNPHasChain]>;
 
+def SDT_X86CallSeqStart : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>;
+def SDT_X86CallSeqEnd   : SDTypeProfile<0, 2, [ SDTCisVT<0, i32>,
+                                                SDTCisVT<1, i32> ]>;
+def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_X86CallSeqStart,
+                           [SDNPHasChain]>;
+def callseq_end   : SDNode<"ISD::CALLSEQ_END",   SDT_X86CallSeqEnd,
+                           [SDNPHasChain]>;
+
+def SDT_X86Call   : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>;
+def call          : SDNode<"X86ISD::CALL", SDT_X86Call, [SDNPHasChain]>;
+
 //===----------------------------------------------------------------------===//
 // X86 Operand Definitions.
 //
@@ -275,9 +293,11 @@
 def PHI : I<0, Pseudo, (ops variable_ops), "PHINODE", []>;        // PHI node.
 def NOOP : I<0x90, RawFrm, (ops), "nop", []>; // nop
 
-def ADJCALLSTACKDOWN : I<0, Pseudo, (ops i32imm:$amt), "#ADJCALLSTACKDOWN", []>;
+def ADJCALLSTACKDOWN : I<0, Pseudo, (ops i32imm:$amt), "#ADJCALLSTACKDOWN",
+                         [(callseq_start imm:$amt)]>;
 def ADJCALLSTACKUP   : I<0, Pseudo, (ops i32imm:$amt1, i32imm:$amt2),
-                         "#ADJCALLSTACKUP", []>;
+                         "#ADJCALLSTACKUP",
+                         [(callseq_end imm:$amt1, imm:$amt2)]>;
 def IMPLICIT_USE     : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_USE", []>;
 def IMPLICIT_DEF     : I<0, Pseudo, (ops variable_ops), "#IMPLICIT_DEF", []>;
 let isTerminator = 1 in
@@ -301,9 +321,6 @@
   }
 }
 
-def : Pat<(X86retflag 0),        (RET)>;
-def : Pat<(X86retflag imm:$amt), (RETI imm:$amt)>;
-
 // All branches are RawFrm, Void, Branch, and Terminators
 let isBranch = 1, isTerminator = 1, noResults = 1 in
   class IBr<bits<8> opcode, dag ops, string asm, list<dag> pattern> :
@@ -342,15 +359,25 @@
 //===----------------------------------------------------------------------===//
 //  Call Instructions...
 //
-let isCall = 1, noResults = 1 in
+// FIXME: How about hasInFlag = 1? A fastcall would require an incoming flag
+// to stick the CopyToRegs to the call.
+let isCall = 1, noResults = 1, hasOutFlag = 1 in
   // All calls clobber the non-callee saved registers...
   let Defs = [EAX, ECX, EDX, FP0, FP1, FP2, FP3, FP4, FP5, FP6, ST0,
               XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7] in {
-    def CALLpcrel32 : I<0xE8, RawFrm, (ops calltarget:$dst), "call $dst", []>;
-    def CALL32r     : I<0xFF, MRM2r, (ops R32:$dst), "call {*}$dst", []>;
-    def CALL32m     : I<0xFF, MRM2m, (ops i32mem:$dst), "call {*}$dst", []>;
+    def CALLpcrel32 : I<0xE8, RawFrm, (ops calltarget:$dst), "call $dst",
+                      []>;
+    def CALL32r     : I<0xFF, MRM2r, (ops R32:$dst), "call {*}$dst",
+                      []>;
+    def CALL32m     : I<0xFF, MRM2m, (ops i32mem:$dst), "call {*}$dst",
+                      []>;
   }
 
+def : Pat<(call tglobaladdr:$dst),
+          (CALLpcrel32 tglobaladdr:$dst)>;
+def : Pat<(call externalsym:$dst),
+          (CALLpcrel32 externalsym:$dst)>;
+
 // Tail call stuff.
 let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, noResults = 1 in
   def TAILJMPd : IBr<0xE9, (ops calltarget:$dst), "jmp $dst  # TAIL CALL", []>;
@@ -2309,11 +2336,17 @@
 }
 
 // Random Pseudo Instructions.
-def FpGETRESULT : FpI<(ops RFP:$dst), SpecialFP, []>;     // FPR = ST(0)
+let hasInFlag = 1 in
+  def FpGETRESULT : FpI<(ops RFP:$dst), SpecialFP, []>;   // FPR = ST(0)
+
+// Do not inline into instruction def. since it isn't predicated on FPStack.
+def : Pat<(X86fpget), (FpGETRESULT)>;
+
 let noResults = 1, hasOutFlag = 1 in 
   def FpSETRESULT : FpI<(ops RFP:$src), SpecialFP,
                         []>, Imp<[], [ST0]>;              // ST(0) = FPR
 
+// Do not inline into instruction def. since it isn't predicated on FPStack.
 def : Pat<(X86fpset RFP:$src), (FpSETRESULT RFP:$src)>;
 
 def FpMOV       : FpI<(ops RFP:$dst, RFP:$src), SpecialFP, []>; // f1 = fmov f2
@@ -2359,7 +2392,7 @@
                     [(set RFP:$dst, (fsub RFP:$src1, (loadf64 addr:$src2)))]>;
                 // ST(0) = ST(0) - [mem64]
 def FpSUBR32m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
-                    [(set RFP:$dst, (fadd (extloadf64f32 addr:$src2),
+                    [(set RFP:$dst, (fsub (extloadf64f32 addr:$src2),
                                      RFP:$src1))]>;
                 // ST(0) = [mem32] - ST(0)
 def FpSUBR64m : FpI<(ops RFP:$dst, RFP:$src1, f32mem:$src2), OneArgFPRW,
@@ -2503,6 +2536,10 @@
                 [(truncstore RFP:$src, addr:$op, f32)]>;
 def FpST64m   : FpI<(ops f64mem:$op, RFP:$src), OneArgFP,
                 [(store RFP:$src, addr:$op)]>;
+
+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)>;
+
 def FpSTP32m  : FpI<(ops f32mem:$op, RFP:$src), OneArgFP, []>;
 def FpSTP64m  : FpI<(ops f64mem:$op, RFP:$src), OneArgFP, []>;
 def FpIST16m  : FpI<(ops i16mem:$op, RFP:$src), OneArgFP, []>;






More information about the llvm-commits mailing list