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

Evan Cheng evan.cheng at apple.com
Tue Dec 20 18:39:33 PST 2005



Changes in directory llvm/lib/Target/X86:

X86ISelDAGToDAG.cpp updated: 1.16 -> 1.17
X86ISelLowering.cpp updated: 1.11 -> 1.12
X86ISelLowering.h updated: 1.5 -> 1.6
X86InstrInfo.td updated: 1.175 -> 1.176
X86RegisterInfo.td updated: 1.25 -> 1.26
---
Log message:

* Added lowering hook for external weak global address. It inserts a load
  for Darwin.
* Added lowering hook for ISD::RET. It inserts CopyToRegs for the return
  value (or store / fld / copy to ST(0) for floating point value). This
  eliminate the need to write C++ code to handle RET with variable number
  of operands.


---
Diffs of the changes:  (+135 -22)

 X86ISelDAGToDAG.cpp |   17 -----------
 X86ISelLowering.cpp |   79 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 X86ISelLowering.h   |   17 +++++++++++
 X86InstrInfo.td     |   37 +++++++++++++++++++++---
 X86RegisterInfo.td  |    7 +++-
 5 files changed, 135 insertions(+), 22 deletions(-)


Index: llvm/lib/Target/X86/X86ISelDAGToDAG.cpp
diff -u llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.16 llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.17
--- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp:1.16	Mon Dec 19 16:36:02 2005
+++ llvm/lib/Target/X86/X86ISelDAGToDAG.cpp	Tue Dec 20 20:39:21 2005
@@ -173,22 +173,7 @@
 
   case ISD::GlobalAddress:
     if (AM.GV == 0) {
-      GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
-      // For Darwin, external and weak symbols are indirect, so we want to load
-      // the value at address GV, not the value of GV itself.  This means that
-      // the GlobalAddress must be in the base or index register of the address,
-      // not the GV offset field.
-      if (Subtarget->getIndirectExternAndWeakGlobals() &&
-          (GV->hasWeakLinkage() || GV->isExternal())) {
-        AM.Base.Reg =
-          CurDAG->getTargetNode(X86::MOV32rm, MVT::i32, MVT::Other,
-                                CurDAG->getRegister(0, MVT::i32),
-                                getI8Imm(1), CurDAG->getRegister(0, MVT::i32),
-                                CurDAG->getTargetGlobalAddress(GV, MVT::i32),
-                                CurDAG->getEntryNode());
-      } else {
-        AM.GV = GV;
-      }
+      AM.GV = cast<GlobalAddressSDNode>(N)->getGlobal();
       return false;
     }
     break;


Index: llvm/lib/Target/X86/X86ISelLowering.cpp
diff -u llvm/lib/Target/X86/X86ISelLowering.cpp:1.11 llvm/lib/Target/X86/X86ISelLowering.cpp:1.12
--- llvm/lib/Target/X86/X86ISelLowering.cpp:1.11	Tue Dec 20 00:22:03 2005
+++ llvm/lib/Target/X86/X86ISelLowering.cpp	Tue Dec 20 20:39:21 2005
@@ -197,6 +197,68 @@
   return  LowerCCCCallTo(Chain, RetTy, isVarArg, isTailCall, Callee, Args, DAG);
 }
 
+SDOperand X86TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op,
+                                           SelectionDAG &DAG) {
+  if (!X86DAGIsel)
+    return DAG.getNode(ISD::RET, MVT::Other, Chain, Op);
+
+  SDOperand Copy;
+  MVT::ValueType OpVT = Op.getValueType();
+  switch (OpVT) {
+    default: assert(0 && "Unknown type to return!");
+    case MVT::i32:
+      Copy = DAG.getCopyToReg(Chain, X86::EAX, Op, SDOperand());
+      break;
+    case MVT::i64: {
+      SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, 
+                                 DAG.getConstant(1, MVT::i32));
+      SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op,
+                                 DAG.getConstant(0, MVT::i32));
+      Copy = DAG.getCopyToReg(Chain, X86::EAX, Hi, SDOperand());
+      Copy = DAG.getCopyToReg(Copy,  X86::EDX, Lo, Copy.getValue(1));
+      break;
+    }
+    case MVT::f32:
+      assert(X86ScalarSSE && "MVT::f32 only legal with scalar sse fp");
+      // Fallthrough intended
+    case MVT::f64:
+      if (!X86ScalarSSE) {
+        std::vector<MVT::ValueType> Tys;
+        Tys.push_back(MVT::Other);
+        Tys.push_back(MVT::Flag);
+        std::vector<SDOperand> Ops;
+        Ops.push_back(Chain);
+        Ops.push_back(Op);
+        Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops);
+      } else {
+        // Spill the value to memory and reload it into top of stack.
+        unsigned Size = MVT::getSizeInBits(OpVT)/8;
+        MachineFunction &MF = DAG.getMachineFunction();
+        int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
+        SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
+        Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain, Op,
+                            StackSlot, DAG.getSrcValue(NULL));
+        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(OpVT));
+        Copy = DAG.getNode(X86ISD::FLD, Tys, Ops);
+        Tys.clear();
+        Tys.push_back(MVT::Other);
+        Tys.push_back(MVT::Flag);
+        Ops.clear();
+        Ops.push_back(Copy.getValue(1));
+        Ops.push_back(Copy);
+        Copy = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops);
+      }
+      break;
+  }
+  return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1));
+}
+
 //===----------------------------------------------------------------------===//
 //                    C Calling Convention implementation
 //===----------------------------------------------------------------------===//
@@ -968,6 +1030,20 @@
     return DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
                        Op.getOperand(0), Op.getOperand(2), CC, Cond);
   }
+  case ISD::GlobalAddress:
+    GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
+    // For Darwin, external and weak symbols are indirect, so we want to load
+    // the value at address GV, not the value of GV itself.  This means that
+    // the GlobalAddress must be in the base or index register of the address,
+    // not the GV offset field.
+    if (getTargetMachine().
+        getSubtarget<X86Subtarget>().getIndirectExternAndWeakGlobals() &&
+        (GV->hasWeakLinkage() || GV->isExternal()))
+      return DAG.getLoad(MVT::i32, DAG.getEntryNode(), Op,
+                         DAG.getSrcValue(NULL));
+    else
+      return Op;
+    break;
   }
 }
 
@@ -978,6 +1054,8 @@
   case X86ISD::FP_TO_INT16_IN_MEM: return "X86ISD::FP_TO_INT16_IN_MEM";
   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::FP_SET_RESULT:      return "X86ISD::FP_SET_RESULT";
   case X86ISD::CALL:               return "X86ISD::CALL";
   case X86ISD::TAILCALL:           return "X86ISD::TAILCALL";
   case X86ISD::RDTSC_DAG:          return "X86ISD::RDTSC_DAG";
@@ -985,5 +1063,6 @@
   case X86ISD::TEST:               return "X86ISD::TEST";
   case X86ISD::CMOV:               return "X86ISD::CMOV";
   case X86ISD::BRCOND:             return "X86ISD::BRCOND";
+  case X86ISD::RET_FLAG:           return "X86ISD::RET_FLAG";
   }
 }


Index: llvm/lib/Target/X86/X86ISelLowering.h
diff -u llvm/lib/Target/X86/X86ISelLowering.h:1.5 llvm/lib/Target/X86/X86ISelLowering.h:1.6
--- llvm/lib/Target/X86/X86ISelLowering.h:1.5	Tue Dec 20 00:22:03 2005
+++ llvm/lib/Target/X86/X86ISelLowering.h	Tue Dec 20 20:39:21 2005
@@ -40,6 +40,17 @@
       FP_TO_INT32_IN_MEM,
       FP_TO_INT64_IN_MEM,
 
+      /// FLD - This instruction implements an extending load to FP stack slots.
+      /// This corresponds to the X86::FLD32m / X86::FLD64m. It takes a chain
+      /// operand, ptr to load from, and a VALUETYPE node indicating the type
+      /// to load.
+      FLD,
+
+      /// 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.
+      FP_SET_RESULT,
+
       /// CALL/TAILCALL - These operations represent an abstract X86 call
       /// instruction, which includes a bunch of information.  In particular the
       /// operands of these node are:
@@ -75,6 +86,9 @@
 
       /// X86 conditional branches.
       BRCOND,
+
+      // Return with a flag operand.
+      RET_FLAG,
     };
   }
 
@@ -113,6 +127,9 @@
                 bool isTailCall, SDOperand Callee, ArgListTy &Args,
                 SelectionDAG &DAG);
 
+    virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op,
+                                    SelectionDAG &DAG);
+    
     virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
                                    Value *VAListV, SelectionDAG &DAG);
     virtual std::pair<SDOperand,SDOperand>


Index: llvm/lib/Target/X86/X86InstrInfo.td
diff -u llvm/lib/Target/X86/X86InstrInfo.td:1.175 llvm/lib/Target/X86/X86InstrInfo.td:1.176
--- llvm/lib/Target/X86/X86InstrInfo.td:1.175	Tue Dec 20 16:59:50 2005
+++ llvm/lib/Target/X86/X86InstrInfo.td	Tue Dec 20 20:39:21 2005
@@ -28,11 +28,25 @@
                                   [SDTCisVT<0, OtherVT>,
                                    SDTCisVT<1, OtherVT>, SDTCisVT<2, FlagVT>]>;
 
-def X86cmp    : SDNode<"X86ISD::CMP" ,   SDTX86CmpTest, []>;
-def X86test   : SDNode<"X86ISD::TEST",   SDTX86CmpTest, []>;
+def SDTX86RetFlag : SDTypeProfile<0, 1, [SDTCisVT<0, FlagVT>]>;
 
-def X86cmov   : SDNode<"X86ISD::CMOV",   SDTX86Cmov,    []>;
-def X86Brcond : SDNode<"X86ISD::BRCOND", SDTX86BrCond,  [SDNPHasChain]>;
+def SDTX86Fld     : SDTypeProfile<1, 2, [SDTCisFP<0>,
+                                         SDTCisPtrTy<1>, SDTCisVT<2, OtherVT>]>;
+
+def SDTX86FpSet   : SDTypeProfile<0, 1, [SDTCisFP<0>]>;
+
+def X86cmp    : SDNode<"X86ISD::CMP" ,     SDTX86CmpTest, []>;
+def X86test   : SDNode<"X86ISD::TEST",     SDTX86CmpTest, []>;
+
+def X86cmov   : SDNode<"X86ISD::CMOV",     SDTX86Cmov,    []>;
+def X86Brcond : SDNode<"X86ISD::BRCOND",   SDTX86BrCond,  [SDNPHasChain]>;
+
+def X86retflag: SDNode<"X86ISD::RET_FLAG", SDTX86RetFlag, [SDNPHasChain]>;
+
+def X86fld    : SDNode<"X86ISD::FLD",      SDTX86Fld,     [SDNPHasChain]>;
+
+def X86fpset  : SDNode<"X86ISD::FP_SET_RESULT",
+                                           SDTX86FpSet,   [SDNPHasChain]>;
 
 //===----------------------------------------------------------------------===//
 // X86 Operand Definitions.
@@ -274,6 +288,8 @@
 let isTerminator = 1, isReturn = 1, isBarrier = 1 in
   def RETI : Ii16<0xC2, RawFrm, (ops i16imm:$amt), "ret $amt", []>;
 
+def : Pat<(X86retflag FLAG), (RET)>;
+
 // All branches are RawFrm, Void, Branch, and Terminators
 let isBranch = 1, isTerminator = 1 in
   class IBr<bits<8> opcode, dag ops, string asm, list<dag> pattern> :
@@ -2188,10 +2204,21 @@
                 (ops RFP:$dst, RFP:$src1, RFP:$src2), "",
                 []>;    // f1 = fdiv f2, f3
 
+def FpLD32m  : FPI<0xD9, MRM0m, ZeroArgFP,
+                   (ops RFP:$dst, f32mem:$src),
+                   "fld{s} $src",
+                   [(set RFP:$dst, (X86fld addr:$src, f32))]>;
+
+def FpLD64m  : FPI<0xDD, MRM0m, ZeroArgFP,
+                   (ops RFP:$dst, f64mem:$src),
+                   "fld{l} $src",
+                   [(set RFP:$dst, (X86fld addr:$src, f64))]>;
+
 def FpGETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP:$dst), "", []>,
                   Imp<[ST0], []>;  // FPR = ST(0)
 
-def FpSETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP:$src), "", []>,
+def FpSETRESULT : FPI<0, Pseudo, SpecialFP, (ops RFP:$src), "",
+                      [(X86fpset RFP:$src)]>,
                   Imp<[], [ST0]>;  // ST(0) = FPR
 
 // FADD reg, mem: Before stackification, these are represented by:


Index: llvm/lib/Target/X86/X86RegisterInfo.td
diff -u llvm/lib/Target/X86/X86RegisterInfo.td:1.25 llvm/lib/Target/X86/X86RegisterInfo.td:1.26
--- llvm/lib/Target/X86/X86RegisterInfo.td:1.25	Tue Dec 20 16:59:51 2005
+++ llvm/lib/Target/X86/X86RegisterInfo.td	Tue Dec 20 20:39:21 2005
@@ -142,6 +142,11 @@
   }];
 }
 
-def FLAGS_REGS : RegisterClass<"X86", [FlagVT], 32, [STATUS]> {
+// FIXME:
+// HACKTROCITY: define a flags reg class for things that need to take a flag.
+// this should really be handled by tablgen.
+let Namespace = "X86" in
+  def FLAG : Register<"FLAG">;
+def FLAGS_REGS : RegisterClass<"X86", [FlagVT], 32, [STATUS, FLAG]> {
     let Size = 32;
 }






More information about the llvm-commits mailing list