64-bit (MMX) vectors do not need restrictive alignment.
[oota-llvm.git] / lib / Target / X86 / X86ISelLowering.cpp
index 2f629aca284ad24ceb0fdfe9e4ddb299a070e5ae..e4454709ae87a32162665ad9e65df9927e8a5ff1 100644 (file)
@@ -30,7 +30,9 @@
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
+#include "llvm/CodeGen/MachineModuleInfo.h"
 #include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/CodeGen/PseudoSourceValue.h"
 #include "llvm/CodeGen/SelectionDAG.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/Debug.h"
@@ -47,6 +49,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   X86ScalarSSEf32 = Subtarget->hasSSE1();
   X86StackPtr = Subtarget->is64Bit() ? X86::RSP : X86::ESP;
   
+  bool Fast = false;
 
   RegInfo = TM.getRegisterInfo();
 
@@ -80,7 +83,15 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   if (Subtarget->is64Bit())
     addRegisterClass(MVT::i64, X86::GR64RegisterClass);
 
-  setLoadXAction(ISD::SEXTLOAD, MVT::i1, Expand);
+  setLoadXAction(ISD::SEXTLOAD, MVT::i1, Promote);
+
+  // We don't accept any truncstore of integer registers.  
+  setTruncStoreAction(MVT::i64, MVT::i32, Expand);
+  setTruncStoreAction(MVT::i64, MVT::i16, Expand);
+  setTruncStoreAction(MVT::i64, MVT::i8 , Expand);
+  setTruncStoreAction(MVT::i32, MVT::i16, Expand);
+  setTruncStoreAction(MVT::i32, MVT::i8 , Expand);
+  setTruncStoreAction(MVT::i16, MVT::i8, Expand);
 
   // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this
   // operation.
@@ -206,7 +217,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1   , Expand);
   setOperationAction(ISD::FP_ROUND_INREG   , MVT::f32  , Expand);
   setOperationAction(ISD::FREM             , MVT::f64  , Expand);
-  setOperationAction(ISD::FLT_ROUNDS       , MVT::i32  , Custom);
+  setOperationAction(ISD::FLT_ROUNDS_      , MVT::i32  , Custom);
   
   setOperationAction(ISD::CTPOP            , MVT::i8   , Expand);
   setOperationAction(ISD::CTTZ             , MVT::i8   , Custom);
@@ -270,7 +281,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   setOperationAction(ISD::MEMSET          , MVT::Other, Custom);
   setOperationAction(ISD::MEMCPY          , MVT::Other, Custom);
 
-  // Use the default ISD::LOCATION expansion.
+  // Use the default ISD::LOCATION, ISD::DECLARE expansion.
   setOperationAction(ISD::LOCATION, MVT::Other, Expand);
   // FIXME - use subtarget debug flags
   if (!Subtarget->isTargetDarwin() &&
@@ -294,6 +305,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   
   setOperationAction(ISD::TRAMPOLINE, MVT::Other, Custom);
 
+  setOperationAction(ISD::TRAP, MVT::Other, Legal);
+
   // VASTART needs to be custom lowered to use the VarArgsFrameIndex
   setOperationAction(ISD::VASTART           , MVT::Other, Custom);
   setOperationAction(ISD::VAARG             , MVT::Other, Expand);
@@ -345,13 +358,15 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     addLegalFPImmediate(APFloat(+0.0)); // xorpd
     addLegalFPImmediate(APFloat(+0.0f)); // xorps
 
-    // Conversions to long double (in X87) go through memory.
-    setConvertAction(MVT::f32, MVT::f80, Expand);
-    setConvertAction(MVT::f64, MVT::f80, Expand);
-
-    // Conversions from long double (in X87) go through memory.
-    setConvertAction(MVT::f80, MVT::f32, Expand);
-    setConvertAction(MVT::f80, MVT::f64, Expand);
+    // Floating truncations from f80 and extensions to f80 go through memory.
+    // If optimizing, we lie about this though and handle it in
+    // InstructionSelectPreprocess so that dagcombine2 can hack on these.
+    if (Fast) {
+      setConvertAction(MVT::f32, MVT::f80, Expand);
+      setConvertAction(MVT::f64, MVT::f80, Expand);
+      setConvertAction(MVT::f80, MVT::f32, Expand);
+      setConvertAction(MVT::f80, MVT::f64, Expand);
+    }
   } else if (X86ScalarSSEf32) {
     // Use SSE for f32, x87 for f64.
     // Set up the FP register classes.
@@ -385,15 +400,17 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     addLegalFPImmediate(APFloat(-0.0)); // FLD0/FCHS
     addLegalFPImmediate(APFloat(-1.0)); // FLD1/FCHS
 
-    // SSE->x87 conversions go through memory.
-    setConvertAction(MVT::f32, MVT::f64, Expand);
-    setConvertAction(MVT::f32, MVT::f80, Expand);
-
-    // x87->SSE truncations need to go through memory.
-    setConvertAction(MVT::f80, MVT::f32, Expand);    
-    setConvertAction(MVT::f64, MVT::f32, Expand);
-    // And x87->x87 truncations also.
-    setConvertAction(MVT::f80, MVT::f64, Expand);
+    // SSE <-> X87 conversions go through memory.  If optimizing, we lie about
+    // this though and handle it in InstructionSelectPreprocess so that
+    // dagcombine2 can hack on these.
+    if (Fast) {
+      setConvertAction(MVT::f32, MVT::f64, Expand);
+      setConvertAction(MVT::f32, MVT::f80, Expand);
+      setConvertAction(MVT::f80, MVT::f32, Expand);    
+      setConvertAction(MVT::f64, MVT::f32, Expand);
+      // And x87->x87 truncations also.
+      setConvertAction(MVT::f80, MVT::f64, Expand);
+    }
 
     if (!UnsafeFPMath) {
       setOperationAction(ISD::FSIN           , MVT::f64  , Expand);
@@ -410,10 +427,14 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
     setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
 
-    // Floating truncations need to go through memory.
-    setConvertAction(MVT::f80, MVT::f32, Expand);    
-    setConvertAction(MVT::f64, MVT::f32, Expand);
-    setConvertAction(MVT::f80, MVT::f64, Expand);
+    // Floating truncations go through memory.  If optimizing, we lie about
+    // this though and handle it in InstructionSelectPreprocess so that
+    // dagcombine2 can hack on these.
+    if (Fast) {
+      setConvertAction(MVT::f80, MVT::f32, Expand);    
+      setConvertAction(MVT::f64, MVT::f32, Expand);
+      setConvertAction(MVT::f80, MVT::f64, Expand);
+    }
 
     if (!UnsafeFPMath) {
       setOperationAction(ISD::FSIN           , MVT::f64  , Expand);
@@ -436,7 +457,20 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   addRegisterClass(MVT::f80, X86::RFP80RegisterClass);
   setOperationAction(ISD::UNDEF,     MVT::f80, Expand);
   setOperationAction(ISD::FCOPYSIGN, MVT::f80, Expand);
-  setOperationAction(ISD::ConstantFP, MVT::f80, Expand);
+  {
+    setOperationAction(ISD::ConstantFP, MVT::f80, Expand);
+    APFloat TmpFlt(+0.0);
+    TmpFlt.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven);
+    addLegalFPImmediate(TmpFlt);  // FLD0
+    TmpFlt.changeSign();
+    addLegalFPImmediate(TmpFlt);  // FLD0/FCHS
+    APFloat TmpFlt2(+1.0);
+    TmpFlt2.convert(APFloat::x87DoubleExtended, APFloat::rmNearestTiesToEven);
+    addLegalFPImmediate(TmpFlt2);  // FLD1
+    TmpFlt2.changeSign();
+    addLegalFPImmediate(TmpFlt2);  // FLD1/FCHS
+  }
+    
   if (!UnsafeFPMath) {
     setOperationAction(ISD::FSIN           , MVT::f80  , Expand);
     setOperationAction(ISD::FCOS           , MVT::f80  , Expand);
@@ -636,6 +670,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
       AddPromotedToType (ISD::SELECT, (MVT::ValueType)VT, MVT::v2i64);
     }
 
+    setTruncStoreAction(MVT::f64, MVT::f32, Expand);
+
     // Custom lower v2i64 and v2f64 selects.
     setOperationAction(ISD::LOAD,               MVT::v2f64, Legal);
     setOperationAction(ISD::LOAD,               MVT::v2i64, Legal);
@@ -660,6 +696,44 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   allowUnalignedMemoryAccesses = true; // x86 supports it!
 }
 
+/// getMaxByValAlign - Helper for getByValTypeAlignment to determine
+/// the desired ByVal argument alignment.
+static void getMaxByValAlign(const Type *Ty, unsigned &MaxAlign) {
+  if (MaxAlign == 16)
+    return;
+  if (const VectorType *VTy = dyn_cast<VectorType>(Ty)) {
+    if (VTy->getBitWidth() == 128)
+      MaxAlign = 16;
+  } else if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
+    unsigned EltAlign = 0;
+    getMaxByValAlign(ATy->getElementType(), EltAlign);
+    if (EltAlign > MaxAlign)
+      MaxAlign = EltAlign;
+  } else if (const StructType *STy = dyn_cast<StructType>(Ty)) {
+    for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+      unsigned EltAlign = 0;
+      getMaxByValAlign(STy->getElementType(i), EltAlign);
+      if (EltAlign > MaxAlign)
+        MaxAlign = EltAlign;
+      if (MaxAlign == 16)
+        break;
+    }
+  }
+  return;
+}
+
+/// getByValTypeAlignment - Return the desired alignment for ByVal aggregate
+/// function arguments in the caller parameter area. For X86, aggregates
+/// that contain SSE vectors are placed at 16-byte boundaries while the rest
+/// are at 4-byte boundaries.
+unsigned X86TargetLowering::getByValTypeAlignment(const Type *Ty) const {
+  if (Subtarget->is64Bit())
+    return getTargetData()->getABITypeAlignment(Ty);
+  unsigned Align = 4;
+  if (Subtarget->hasSSE1())
+    getMaxByValAlign(Ty, Align);
+  return Align;
+}
 
 /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
 /// jumptable.
@@ -681,16 +755,16 @@ SDOperand X86TargetLowering::getPICJumpTableRelocBase(SDOperand Table,
 /// GetPossiblePreceedingTailCall - Get preceeding X86ISD::TAILCALL node if it
 /// exists skip possible ISD:TokenFactor.
 static SDOperand GetPossiblePreceedingTailCall(SDOperand Chain) {
-  if (Chain.getOpcode()==X86ISD::TAILCALL) {
+  if (Chain.getOpcode() == X86ISD::TAILCALL) {
     return Chain;
-  } else if (Chain.getOpcode()==ISD::TokenFactor) {
+  } else if (Chain.getOpcode() == ISD::TokenFactor) {
     if (Chain.getNumOperands() &&
-        Chain.getOperand(0).getOpcode()==X86ISD::TAILCALL)
+        Chain.getOperand(0).getOpcode() == X86ISD::TAILCALL)
       return Chain.getOperand(0);
   }
   return Chain;
 }
-    
+
 /// LowerRET - Lower an ISD::RET node.
 SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) {
   assert((Op.getNumOperands() & 1) == 1 && "ISD::RET should have odd # args");
@@ -716,14 +790,14 @@ SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) {
     SDOperand TailCall = Chain;
     SDOperand TargetAddress = TailCall.getOperand(1);
     SDOperand StackAdjustment = TailCall.getOperand(2);
-    assert ( ((TargetAddress.getOpcode() == ISD::Register &&
+    assert(((TargetAddress.getOpcode() == ISD::Register &&
                (cast<RegisterSDNode>(TargetAddress)->getReg() == X86::ECX ||
                 cast<RegisterSDNode>(TargetAddress)->getReg() == X86::R9)) ||
               TargetAddress.getOpcode() == ISD::TargetExternalSymbol ||
               TargetAddress.getOpcode() == ISD::TargetGlobalAddress) && 
              "Expecting an global address, external symbol, or register");
-    assert( StackAdjustment.getOpcode() == ISD::Constant &&
-            "Expecting a const value");
+    assert(StackAdjustment.getOpcode() == ISD::Constant &&
+           "Expecting a const value");
 
     SmallVector<SDOperand,8> Operands;
     Operands.push_back(Chain.getOperand(0));
@@ -756,31 +830,10 @@ SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) {
     // a register.
     SDOperand Value = Op.getOperand(1);
     
-    // If this is an FP return with ScalarSSE, we need to move the value from
-    // an XMM register onto the fp-stack.
-    if ((X86ScalarSSEf32 && RVLocs[0].getValVT()==MVT::f32) ||
-        (X86ScalarSSEf64 && RVLocs[0].getValVT()==MVT::f64)) {
-      SDOperand MemLoc;
-        
-      // If this is a load into a scalarsse value, don't store the loaded value
-      // back to the stack, only to reload it: just replace the scalar-sse load.
-      if (ISD::isNON_EXTLoad(Value.Val) &&
-          (Chain == Value.getValue(1) || Chain == Value.getOperand(0))) {
-        Chain  = Value.getOperand(0);
-        MemLoc = Value.getOperand(1);
-      } else {
-        // Spill the value to memory and reload it into top of stack.
-        unsigned Size = MVT::getSizeInBits(RVLocs[0].getValVT())/8;
-        MachineFunction &MF = DAG.getMachineFunction();
-        int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
-        MemLoc = DAG.getFrameIndex(SSFI, getPointerTy());
-        Chain = DAG.getStore(Op.getOperand(0), Value, MemLoc, NULL, 0);
-      }
-      SDVTList Tys = DAG.getVTList(RVLocs[0].getValVT(), MVT::Other);
-      SDOperand Ops[] = {Chain, MemLoc, DAG.getValueType(RVLocs[0].getValVT())};
-      Value = DAG.getNode(X86ISD::FLD, Tys, Ops, 3);
-      Chain = Value.getValue(1);
-    }
+    // an XMM register onto the fp-stack.  Do this with an FP_EXTEND to f80.
+    // This will get legalized into a load/store if it can't get optimized away.
+    if (isScalarFPTypeInSSEReg(RVLocs[0].getValVT()))
+      Value = DAG.getNode(ISD::FP_EXTEND, MVT::f80, Value);
     
     SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
     SDOperand Ops[] = { Chain, Value };
@@ -825,88 +878,26 @@ LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode *TheCall,
     // Copies from the FP stack are special, as ST0 isn't a valid register
     // before the fp stackifier runs.
     
-    // Copy ST0 into an RFP register with FP_GET_RESULT.
-    SDVTList Tys = DAG.getVTList(RVLocs[0].getValVT(), MVT::Other, MVT::Flag);
+    // Copy ST0 into an RFP register with FP_GET_RESULT.  If this will end up
+    // in an SSE register, copy it out as F80 and do a truncate, otherwise use
+    // the specified value type.
+    MVT::ValueType GetResultTy = RVLocs[0].getValVT();
+    if (isScalarFPTypeInSSEReg(GetResultTy))
+      GetResultTy = MVT::f80;
+    SDVTList Tys = DAG.getVTList(GetResultTy, MVT::Other, MVT::Flag);
+    
     SDOperand GROps[] = { Chain, InFlag };
     SDOperand RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, GROps, 2);
     Chain  = RetVal.getValue(1);
     InFlag = RetVal.getValue(2);
-    
-    // If we are using ScalarSSE, store ST(0) to the stack and reload it into
-    // an XMM register.
-    if ((X86ScalarSSEf32 && RVLocs[0].getValVT() == MVT::f32) ||
-        (X86ScalarSSEf64 && RVLocs[0].getValVT() == MVT::f64)) {
-      SDOperand StoreLoc;
-      const Value *SrcVal = 0;
-      int SrcValOffset = 0;
-      MVT::ValueType RetStoreVT = RVLocs[0].getValVT();
-      
-      // Determine where to store the value.  If the call result is directly
-      // used by a store, see if we can store directly into the location.  In
-      // this case, we'll end up producing a fst + movss[load] + movss[store] to
-      // the same location, and the two movss's will be nuked as dead.  This
-      // optimizes common things like "*D = atof(..)" to not need an
-      // intermediate stack slot.
-      if (SDOperand(TheCall, 0).hasOneUse() && 
-          SDOperand(TheCall, 1).hasOneUse()) {
-        // In addition to direct uses, we also support a FP_ROUND that uses the
-        // value, if it is directly stored somewhere.
-        SDNode *User = *TheCall->use_begin();
-        if (User->getOpcode() == ISD::FP_ROUND && User->hasOneUse())
-          User = *User->use_begin();
-        
-        // Ok, we have one use of the value and one use of the chain.  See if
-        // they are the same node: a store.
-        if (StoreSDNode *N = dyn_cast<StoreSDNode>(User)) {
-          // Verify that the value being stored is either the call or a
-          // truncation of the call.
-          SDNode *StoreVal = N->getValue().Val;
-          if (StoreVal == TheCall)
-            ; // ok.
-          else if (StoreVal->getOpcode() == ISD::FP_ROUND &&
-                   StoreVal->hasOneUse() && 
-                   StoreVal->getOperand(0).Val == TheCall)
-            ; // ok.
-          else
-            N = 0;  // not ok.
-            
-          if (N && N->getChain().Val == TheCall &&
-              !N->isVolatile() && !N->isTruncatingStore() && 
-              N->getAddressingMode() == ISD::UNINDEXED) {
-            StoreLoc = N->getBasePtr();
-            SrcVal = N->getSrcValue();
-            SrcValOffset = N->getSrcValueOffset();
-            RetStoreVT = N->getValue().getValueType();
-          }
-        }
-      }
 
-      // If we weren't able to optimize the result, just create a temporary
-      // stack slot.
-      if (StoreLoc.Val == 0) {
-        MachineFunction &MF = DAG.getMachineFunction();
-        int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
-        StoreLoc = DAG.getFrameIndex(SSFI, getPointerTy());
-      }
-      
-      // 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 (which could happen if a select gets lowered into
-      // multiple blocks and scheduled in between them). When stackifier is
-      // fixed, they can be uncoupled.
-      SDOperand Ops[] = {
-        Chain, RetVal, StoreLoc, DAG.getValueType(RetStoreVT), InFlag
-      };
-      Chain = DAG.getNode(X86ISD::FST, MVT::Other, Ops, 5);
-      RetVal = DAG.getLoad(RetStoreVT, Chain,
-                           StoreLoc, SrcVal, SrcValOffset);
-      Chain = RetVal.getValue(1);
-      
-      // If we optimized a truncate, then extend the result back to its desired
-      // type.
-      if (RVLocs[0].getValVT() != RetStoreVT)
-        RetVal = DAG.getNode(ISD::FP_EXTEND, RVLocs[0].getValVT(), RetVal);
-    }
+    // If we want the result in an SSE register, use an FP_TRUNCATE to get it
+    // there.
+    if (GetResultTy != RVLocs[0].getValVT())
+      RetVal = DAG.getNode(ISD::FP_ROUND, RVLocs[0].getValVT(), RetVal,
+                           // This truncation won't change the value.
+                           DAG.getIntPtrConstant(1));
+    
     ResultVals.push_back(RetVal);
   }
   
@@ -916,6 +907,44 @@ LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode *TheCall,
                      &ResultVals[0], ResultVals.size()).Val;
 }
 
+/// LowerCallResultToTwo64BitRegs - Lower the result values of an x86-64
+/// ISD::CALL where the results are known to be in two 64-bit registers,
+/// e.g. XMM0 and XMM1. This simplify store the two values back to the
+/// fixed stack slot allocated for StructRet.
+SDNode *X86TargetLowering::
+LowerCallResultToTwo64BitRegs(SDOperand Chain, SDOperand InFlag,
+                              SDNode *TheCall, unsigned Reg1, unsigned Reg2,
+                              MVT::ValueType VT, SelectionDAG &DAG) {
+  SDOperand RetVal1 = DAG.getCopyFromReg(Chain, Reg1, VT, InFlag);
+  Chain = RetVal1.getValue(1);
+  InFlag = RetVal1.getValue(2);
+  SDOperand RetVal2 = DAG.getCopyFromReg(Chain, Reg2, VT, InFlag);
+  Chain = RetVal2.getValue(1);
+  InFlag = RetVal2.getValue(2);
+  SDOperand FIN = TheCall->getOperand(5);
+  Chain = DAG.getStore(Chain, RetVal1, FIN, NULL, 0);
+  FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN, DAG.getIntPtrConstant(8));
+  Chain = DAG.getStore(Chain, RetVal2, FIN, NULL, 0);
+  return Chain.Val;
+}
+
+/// LowerCallResultToTwoX87Regs - Lower the result values of an x86-64 ISD::CALL
+/// where the results are known to be in ST0 and ST1.
+SDNode *X86TargetLowering::
+LowerCallResultToTwoX87Regs(SDOperand Chain, SDOperand InFlag,
+                            SDNode *TheCall, SelectionDAG &DAG) {
+  SmallVector<SDOperand, 8> ResultVals;
+  const MVT::ValueType VTs[] = { MVT::f80, MVT::f80, MVT::Other, MVT::Flag };
+  SDVTList Tys = DAG.getVTList(VTs, 4);
+  SDOperand Ops[] = { Chain, InFlag };
+  SDOperand RetVal = DAG.getNode(X86ISD::FP_GET_RESULT2, Tys, Ops, 2);
+  Chain = RetVal.getValue(2);
+  SDOperand FIN = TheCall->getOperand(5);
+  Chain = DAG.getStore(Chain, RetVal.getValue(1), FIN, NULL, 0);
+  FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN, DAG.getIntPtrConstant(16));
+  Chain = DAG.getStore(Chain, RetVal, FIN, NULL, 0);
+  return Chain.Val;
+}
 
 //===----------------------------------------------------------------------===//
 //                C & StdCall & Fast Calling Convention implementation
@@ -1007,21 +1036,60 @@ X86TargetLowering::NameDecorationForFORMAL_ARGUMENTS(SDOperand Op) {
   return None;
 }
 
+
+// IsPossiblyOverwrittenArgumentOfTailCall - Check if the operand could possibly
+// be overwritten when lowering the outgoing arguments in a tail call. Currently
+// the implementation of this call is very conservative and assumes all
+// arguments sourcing from FORMAL_ARGUMENTS or a CopyFromReg with virtual
+// registers would be overwritten by direct lowering.  
+// Possible improvement:
+// Check FORMAL_ARGUMENTS corresponding MERGE_VALUES for CopyFromReg nodes
+// indicating inreg passed arguments which also need not be lowered to a safe
+// stack slot.
+static bool IsPossiblyOverwrittenArgumentOfTailCall(SDOperand Op) {
+  RegisterSDNode * OpReg = NULL;
+  if (Op.getOpcode() == ISD::FORMAL_ARGUMENTS ||
+      (Op.getOpcode()== ISD::CopyFromReg &&
+       (OpReg = cast<RegisterSDNode>(Op.getOperand(1))) &&
+       OpReg->getReg() >= MRegisterInfo::FirstVirtualRegister))
+    return true;
+  return false;
+}
+
+// CreateCopyOfByValArgument - Make a copy of an aggregate at address specified
+// by "Src" to address "Dst" with size and alignment information specified by
+// the specific parameter attribute. The copy will be passed as a byval function
+// parameter.
+static SDOperand 
+CreateCopyOfByValArgument(SDOperand Src, SDOperand Dst, SDOperand Chain,
+                          unsigned Flags, SelectionDAG &DAG) {
+  unsigned Align = 1 <<
+    ((Flags & ISD::ParamFlags::ByValAlign) >> ISD::ParamFlags::ByValAlignOffs);
+  unsigned Size = (Flags & ISD::ParamFlags::ByValSize) >>
+    ISD::ParamFlags::ByValSizeOffs;
+  SDOperand AlignNode    = DAG.getConstant(Align, MVT::i32);
+  SDOperand SizeNode     = DAG.getConstant(Size, MVT::i32);
+  SDOperand AlwaysInline = DAG.getConstant(1, MVT::i32);
+  return DAG.getMemcpy(Chain, Dst, Src, SizeNode, AlignNode, AlwaysInline);
+}
+
 SDOperand X86TargetLowering::LowerMemArgument(SDOperand Op, SelectionDAG &DAG,
                                               const CCValAssign &VA,
                                               MachineFrameInfo *MFI,
                                               SDOperand Root, unsigned i) {
   // Create the nodes corresponding to a load from this parameter slot.
+  unsigned Flags = cast<ConstantSDNode>(Op.getOperand(3 + i))->getValue();
+  bool isByVal = Flags & ISD::ParamFlags::ByVal;
+
+  // FIXME: For now, all byval parameter objects are marked mutable. This
+  // can be changed with more analysis.
   int FI = MFI->CreateFixedObject(MVT::getSizeInBits(VA.getValVT())/8,
-                                  VA.getLocMemOffset());
+                                  VA.getLocMemOffset(), !isByVal);
   SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
-
-  unsigned Flags =  cast<ConstantSDNode>(Op.getOperand(3 + i))->getValue();
-
-  if (Flags & ISD::ParamFlags::ByVal)
+  if (isByVal)
     return FIN;
-  else
-    return DAG.getLoad(VA.getValVT(), Root, FIN, NULL, 0);
+  return DAG.getLoad(VA.getValVT(), Root, FIN,
+                     PseudoSourceValue::getFixedStack(), FI);
 }
 
 SDOperand
@@ -1069,9 +1137,9 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
         RC = X86::GR32RegisterClass;
       else if (Is64Bit && RegVT == MVT::i64)
         RC = X86::GR64RegisterClass;
-      else if (Is64Bit && RegVT == MVT::f32)
+      else if (RegVT == MVT::f32)
         RC = X86::FR32RegisterClass;
-      else if (Is64Bit && RegVT == MVT::f64)
+      else if (RegVT == MVT::f64)
         RC = X86::FR64RegisterClass;
       else {
         assert(MVT::isVector(RegVT));
@@ -1144,29 +1212,34 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
       SmallVector<SDOperand, 8> MemOps;
       SDOperand RSFIN = DAG.getFrameIndex(RegSaveFrameIndex, getPointerTy());
       SDOperand FIN = DAG.getNode(ISD::ADD, getPointerTy(), RSFIN,
-                                  DAG.getConstant(VarArgsGPOffset,
-                                  getPointerTy()));
+                                  DAG.getIntPtrConstant(VarArgsGPOffset));
       for (; NumIntRegs != 6; ++NumIntRegs) {
         unsigned VReg = AddLiveIn(MF, GPR64ArgRegs[NumIntRegs],
                                   X86::GR64RegisterClass);
         SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::i64);
-        SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
+        SDOperand Store =
+          DAG.getStore(Val.getValue(1), Val, FIN,
+                       PseudoSourceValue::getFixedStack(),
+                       RegSaveFrameIndex);
         MemOps.push_back(Store);
         FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
-                          DAG.getConstant(8, getPointerTy()));
+                          DAG.getIntPtrConstant(8));
       }
       
       // Now store the XMM (fp + vector) parameter registers.
       FIN = DAG.getNode(ISD::ADD, getPointerTy(), RSFIN,
-                        DAG.getConstant(VarArgsFPOffset, getPointerTy()));
+                        DAG.getIntPtrConstant(VarArgsFPOffset));
       for (; NumXMMRegs != 8; ++NumXMMRegs) {
         unsigned VReg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs],
                                   X86::VR128RegisterClass);
         SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::v4f32);
-        SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
+        SDOperand Store =
+          DAG.getStore(Val.getValue(1), Val, FIN,
+                       PseudoSourceValue::getFixedStack(),
+                       RegSaveFrameIndex);
         MemOps.push_back(Store);
         FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
-                          DAG.getConstant(16, getPointerTy()));
+                          DAG.getIntPtrConstant(16));
       }
       if (!MemOps.empty())
           Root = DAG.getNode(ISD::TokenFactor, MVT::Other,
@@ -1209,6 +1282,82 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
                      &ArgValues[0], ArgValues.size()).getValue(Op.ResNo);
 }
 
+SDOperand
+X86TargetLowering::LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG,
+                                    const SDOperand &StackPtr,
+                                    const CCValAssign &VA,
+                                    SDOperand Chain,
+                                    SDOperand Arg) {
+  unsigned LocMemOffset = VA.getLocMemOffset();
+  SDOperand PtrOff = DAG.getIntPtrConstant(LocMemOffset);
+  PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
+  SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo());
+  unsigned Flags    = cast<ConstantSDNode>(FlagsOp)->getValue();
+  if (Flags & ISD::ParamFlags::ByVal) {
+    return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG);
+  }
+  return DAG.getStore(Chain, Arg, PtrOff,
+                      PseudoSourceValue::getStack(), LocMemOffset);
+}
+
+/// ClassifyX86_64SRetCallReturn - Classify how to implement a x86-64
+/// struct return call to the specified function. X86-64 ABI specifies
+/// some SRet calls are actually returned in registers. Since current
+/// LLVM cannot represent multi-value calls, they are represent as 
+/// calls where the results are passed in a hidden struct provided by
+/// the caller. This function examines the type of the struct to
+/// determine the correct way to implement the call.
+X86::X86_64SRet
+X86TargetLowering::ClassifyX86_64SRetCallReturn(const Function *Fn) {
+  // FIXME: Disabled for now.
+  return X86::InMemory;
+
+  const PointerType *PTy = cast<PointerType>(Fn->arg_begin()->getType());
+  const Type *RTy = PTy->getElementType();
+  unsigned Size = getTargetData()->getABITypeSize(RTy);
+  if (Size != 16 && Size != 32)
+    return X86::InMemory;
+
+  if (Size == 32) {
+    const StructType *STy = dyn_cast<StructType>(RTy);
+    if (!STy) return X86::InMemory;
+    if (STy->getNumElements() == 2 &&
+        STy->getElementType(0) == Type::X86_FP80Ty &&
+        STy->getElementType(1) == Type::X86_FP80Ty)
+      return X86::InX87;
+  }
+
+  bool AllFP = true;
+  for (Type::subtype_iterator I = RTy->subtype_begin(), E = RTy->subtype_end();
+       I != E; ++I) {
+    const Type *STy = I->get();
+    if (!STy->isFPOrFPVector()) {
+      AllFP = false;
+      break;
+    }
+  }
+
+  if (AllFP)
+    return X86::InSSE;
+  return X86::InGPR64;
+}
+
+void X86TargetLowering::X86_64AnalyzeSRetCallOperands(SDNode *TheCall,
+                                                      CCAssignFn *Fn,
+                                                      CCState &CCInfo) {
+  unsigned NumOps = (TheCall->getNumOperands() - 5) / 2;
+  for (unsigned i = 1; i != NumOps; ++i) {
+    MVT::ValueType ArgVT = TheCall->getOperand(5+2*i).getValueType();
+    SDOperand FlagOp = TheCall->getOperand(5+2*i+1);
+    unsigned ArgFlags =cast<ConstantSDNode>(FlagOp)->getValue();
+    if (Fn(i, ArgVT, ArgVT, CCValAssign::Full, ArgFlags, CCInfo)) {
+      cerr << "Call operand #" << i << " has unhandled type "
+           << MVT::getValueTypeString(ArgVT) << "\n";
+      abort();
+    }
+  }
+}
+
 SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   MachineFunction &MF = DAG.getMachineFunction();
   SDOperand Chain     = Op.getOperand(0);
@@ -1218,6 +1367,7 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
                         && CC == CallingConv::Fast && PerformTailCallOpt;
   SDOperand Callee    = Op.getOperand(4);
   bool Is64Bit        = Subtarget->is64Bit();
+  bool IsStructRet    = CallIsStructReturn(Op);
 
   assert(!(isVarArg && CC == CallingConv::Fast) &&
          "Var args not supported with calling convention fastcc");
@@ -1225,7 +1375,24 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   // Analyze operands of the call, assigning locations to each operand.
   SmallVector<CCValAssign, 16> ArgLocs;
   CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
-  CCInfo.AnalyzeCallOperands(Op.Val, CCAssignFnForNode(Op));
+  CCAssignFn *CCFn = CCAssignFnForNode(Op);
+
+  X86::X86_64SRet SRetMethod = X86::InMemory;
+  if (Is64Bit && IsStructRet)
+    // FIXME: We can't figure out type of the sret structure for indirect
+    // calls. We need to copy more information from CallSite to the ISD::CALL
+    // node.
+    if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee))
+      SRetMethod =
+        ClassifyX86_64SRetCallReturn(dyn_cast<Function>(G->getGlobal()));
+
+  // UGLY HACK! For x86-64, some 128-bit aggregates are returns in a pair of
+  // registers. Unfortunately, llvm does not support i128 yet so we pretend it's
+  // a sret call.
+  if (SRetMethod != X86::InMemory)
+    X86_64AnalyzeSRetCallOperands(Op.Val, CCFn, CCInfo);
+  else 
+    CCInfo.AnalyzeCallOperands(Op.Val, CCFn);
   
   // Get a count of how many bytes are to be pushed on the stack.
   unsigned NumBytes = CCInfo.getNextStackOffset();
@@ -1252,7 +1419,7 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
       MF.getInfo<X86MachineFunctionInfo>()->setTCReturnAddrDelta(FPDiff);
   }
 
-  Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, getPointerTy()));
+  Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes));
 
   SDOperand RetAddrFrIdx, NewRetAddrFrIdx;
   if (IsTailCall) {
@@ -1277,9 +1444,9 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
 
   SDOperand StackPtr;
 
-  // Walk the register/memloc assignments, inserting copies/loads.
-  // For tail calls, lower arguments first to the stack slot where they would 
-  // normally - in case of a normal function call - be.
+  // Walk the register/memloc assignments, inserting copies/loads.  For tail
+  // calls, lower arguments which could otherwise be possibly overwritten to the
+  // stack slot where they would go on normal function calls.
   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
     CCValAssign &VA = ArgLocs[i];
     SDOperand Arg = Op.getOperand(5+2*VA.getValNo());
@@ -1302,12 +1469,14 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
     if (VA.isRegLoc()) {
       RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
     } else {
-      assert(VA.isMemLoc());
-      if (StackPtr.Val == 0)
-        StackPtr = DAG.getRegister(getStackPtrReg(), getPointerTy());
-
-      MemOpChains.push_back(LowerMemOpCallTo(Op, DAG, StackPtr, VA, Chain,
-                                             Arg));
+      if (!IsTailCall || IsPossiblyOverwrittenArgumentOfTailCall(Arg)) {
+        assert(VA.isMemLoc());
+        if (StackPtr.Val == 0)
+          StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr, getPointerTy());
+        
+        MemOpChains.push_back(LowerMemOpCallTo(Op, DAG, StackPtr, VA, Chain,
+                                               Arg));
+      }
     }
   }
   
@@ -1361,58 +1530,53 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
     InFlag = Chain.getValue(1);
   }
 
-  // Copy from stack slots to stack slot of a tail called function. This needs
-  // to be done because if we would lower the arguments directly to their real
-  // stack slot we might end up overwriting each other.
-  // TODO: To make this more efficient (sometimes saving a store/load) we could
-  // analyse the arguments and emit this store/load/store sequence only for
-  // arguments which would be overwritten otherwise.
+  // For tail calls lower the arguments to the 'real' stack slot.
   if (IsTailCall) {
     SmallVector<SDOperand, 8> MemOpChains2;
-    SDOperand PtrOff;
     SDOperand FIN;
     int FI = 0;
     for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
       CCValAssign &VA = ArgLocs[i];
       if (!VA.isRegLoc()) {
+        assert(VA.isMemLoc());
+        SDOperand Arg = Op.getOperand(5+2*VA.getValNo());
         SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo());
         unsigned Flags    = cast<ConstantSDNode>(FlagsOp)->getValue();
-        
-        // Get source stack slot. 
-        SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(),
-                                           getPointerTy());
-        PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
         // Create frame index.
         int32_t Offset = VA.getLocMemOffset()+FPDiff;
         uint32_t OpSize = (MVT::getSizeInBits(VA.getLocVT())+7)/8;
         FI = MF.getFrameInfo()->CreateFixedObject(OpSize, Offset);
         FIN = DAG.getFrameIndex(FI, MVT::i32);
+        SDOperand Source = Arg;
+        if (IsPossiblyOverwrittenArgumentOfTailCall(Arg)) {
+          // Copy from stack slots to stack slot of a tail called function. This
+          // needs to be done because if we would lower the arguments directly
+          // to their real stack slot we might end up overwriting each other.
+          // Get source stack slot.
+          Source = DAG.getIntPtrConstant(VA.getLocMemOffset());
+          if (StackPtr.Val == 0)
+            StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr, getPointerTy());
+          Source = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, Source);
+          if ((Flags & ISD::ParamFlags::ByVal)==0) 
+            Source = DAG.getLoad(VA.getValVT(), Chain, Source, NULL, 0);
+        } 
+
         if (Flags & ISD::ParamFlags::ByVal) {
           // Copy relative to framepointer.
-          unsigned Align = 1 << ((Flags & ISD::ParamFlags::ByValAlign) >>
-                                 ISD::ParamFlags::ByValAlignOffs);
-
-          unsigned  Size = (Flags & ISD::ParamFlags::ByValSize) >>
-            ISD::ParamFlags::ByValSizeOffs;
-          SDOperand AlignNode = DAG.getConstant(Align, MVT::i32);
-          SDOperand  SizeNode = DAG.getConstant(Size, MVT::i32);
-          SDOperand AlwaysInline = DAG.getConstant(1, MVT::i1);
-
-          MemOpChains2.push_back(DAG.getMemcpy(Chain, FIN, PtrOff, SizeNode, 
-                                               AlignNode,AlwaysInline));
+          MemOpChains2.push_back(CreateCopyOfByValArgument(Source, FIN, Chain,
+                                                           Flags, DAG));
         } else {
-          SDOperand LoadedArg = DAG.getLoad(VA.getValVT(), Chain, PtrOff,
-                                            NULL, 0);
           // Store relative to framepointer.
-          MemOpChains2.push_back(DAG.getStore(Chain, LoadedArg, FIN, NULL, 0));
-        }
+          MemOpChains2.push_back(
+            DAG.getStore(Chain, Source, FIN,
+                         PseudoSourceValue::getFixedStack(), FI));
+        }            
       }
     }
 
     if (!MemOpChains2.empty())
       Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
-                          &MemOpChains2[0], MemOpChains.size());
+                          &MemOpChains2[0], MemOpChains2.size());
 
     // Store the return address to the appropriate stack slot.
     if (FPDiff)
@@ -1452,8 +1616,8 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
 
   if (IsTailCall) {
     Ops.push_back(Chain);
-    Ops.push_back(DAG.getConstant(NumBytes, getPointerTy()));
-    Ops.push_back(DAG.getConstant(0, getPointerTy()));
+    Ops.push_back(DAG.getIntPtrConstant(NumBytes));
+    Ops.push_back(DAG.getIntPtrConstant(0));
     if (InFlag.Val)
       Ops.push_back(InFlag);
     Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], Ops.size());
@@ -1478,10 +1642,9 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
 
   // Add argument registers to the end of the list so that they are known live
   // into the call.
-  if (IsTailCall)
-    for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
-      Ops.push_back(DAG.getRegister(RegsToPass[i].first,
-                                    RegsToPass[i].second.getValueType()));
+  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
+    Ops.push_back(DAG.getRegister(RegsToPass[i].first,
+                                  RegsToPass[i].second.getValueType()));
   
   if (InFlag.Val)
     Ops.push_back(InFlag);
@@ -1502,7 +1665,7 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   unsigned NumBytesForCalleeToPush;
   if (IsCalleePop(Op))
     NumBytesForCalleeToPush = NumBytes;    // Callee pops everything
-  else if (!Is64Bit && CallIsStructReturn(Op))
+  else if (!Is64Bit && IsStructRet)
     // If this is is a call to a struct-return function, the callee
     // pops the hidden struct pointer, so we have to push it back.
     // This is common for Darwin/X86, Linux & Mingw32 targets.
@@ -1512,59 +1675,31 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   
   // Returns a flag for retval copy to use.
   Chain = DAG.getCALLSEQ_END(Chain,
-                             DAG.getConstant(NumBytes, getPointerTy()),
-                             DAG.getConstant(NumBytesForCalleeToPush,
-                                             getPointerTy()),
+                             DAG.getIntPtrConstant(NumBytes),
+                             DAG.getIntPtrConstant(NumBytesForCalleeToPush),
                              InFlag);
   InFlag = Chain.getValue(1);
 
   // Handle result values, copying them out of physregs into vregs that we
   // return.
-  return SDOperand(LowerCallResult(Chain, InFlag, Op.Val, CC, DAG), Op.ResNo);
-}
-
-
-//===----------------------------------------------------------------------===//
-//                   FastCall Calling Convention implementation
-//===----------------------------------------------------------------------===//
-//
-// The X86 'fastcall' calling convention passes up to two integer arguments in
-// registers (an appropriate portion of ECX/EDX), passes arguments in C order,
-// and requires that the callee pop its arguments off the stack (allowing proper
-// tail calls), and has the same return value conventions as C calling convs.
-//
-// This calling convention always arranges for the callee pop value to be 8n+4
-// bytes, which is needed for tail recursion elimination and stack alignment
-// reasons.
-
-SDOperand
-X86TargetLowering::LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG,
-                                    const SDOperand &StackPtr,
-                                    const CCValAssign &VA,
-                                    SDOperand Chain,
-                                    SDOperand Arg) {
-  SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), getPointerTy());
-  PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
-  SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo());
-  unsigned Flags    = cast<ConstantSDNode>(FlagsOp)->getValue();
-  if (Flags & ISD::ParamFlags::ByVal) {
-    unsigned Align = 1 << ((Flags & ISD::ParamFlags::ByValAlign) >>
-                           ISD::ParamFlags::ByValAlignOffs);
-
-    unsigned  Size = (Flags & ISD::ParamFlags::ByValSize) >>
-        ISD::ParamFlags::ByValSizeOffs;
-
-    SDOperand AlignNode = DAG.getConstant(Align, MVT::i32);
-    SDOperand  SizeNode = DAG.getConstant(Size, MVT::i32);
-    SDOperand AlwaysInline = DAG.getConstant(1, MVT::i32);
-
-    return DAG.getMemcpy(Chain, PtrOff, Arg, SizeNode, AlignNode,
-                         AlwaysInline);
-  } else {
-    return DAG.getStore(Chain, Arg, PtrOff, NULL, 0);
+  switch (SRetMethod) {
+  default:
+    return SDOperand(LowerCallResult(Chain, InFlag, Op.Val, CC, DAG), Op.ResNo);
+  case X86::InGPR64:
+    return SDOperand(LowerCallResultToTwo64BitRegs(Chain, InFlag, Op.Val,
+                                                   X86::RAX, X86::RDX,
+                                                   MVT::i64, DAG), Op.ResNo);
+  case X86::InSSE:
+    return SDOperand(LowerCallResultToTwo64BitRegs(Chain, InFlag, Op.Val,
+                                                   X86::XMM0, X86::XMM1,
+                                                   MVT::f64, DAG), Op.ResNo);
+  case X86::InX87:
+    return SDOperand(LowerCallResultToTwoX87Regs(Chain, InFlag, Op.Val, DAG),
+                     Op.ResNo);
   }
 }
 
+
 //===----------------------------------------------------------------------===//
 //                Fast Calling Convention (tail call) implementation
 //===----------------------------------------------------------------------===//
@@ -2725,7 +2860,7 @@ static SDOperand LowerBuildVectorv16i8(SDOperand Op, unsigned NonZeros,
 
       if (ThisElt.Val)
         V = DAG.getNode(ISD::INSERT_VECTOR_ELT, MVT::v8i16, V, ThisElt,
-                        DAG.getConstant(i/2, TLI.getPointerTy()));
+                        DAG.getIntPtrConstant(i/2));
     }
   }
 
@@ -2753,7 +2888,7 @@ static SDOperand LowerBuildVectorv8i16(SDOperand Op, unsigned NonZeros,
         First = false;
       }
       V = DAG.getNode(ISD::INSERT_VECTOR_ELT, MVT::v8i16, V, Op.getOperand(i),
-                      DAG.getConstant(i, TLI.getPointerTy()));
+                      DAG.getIntPtrConstant(i));
     }
   }
 
@@ -3562,7 +3697,7 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
     Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(),
                       Vec, DAG.getNode(ISD::UNDEF, Vec.getValueType()), Mask);
     return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, VT, Vec,
-                       DAG.getConstant(0, getPointerTy()));
+                       DAG.getIntPtrConstant(0));
   } else if (MVT::getSizeInBits(VT) == 64) {
     unsigned Idx = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
     if (Idx == 0)
@@ -3582,7 +3717,7 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
     Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(),
                       Vec, DAG.getNode(ISD::UNDEF, Vec.getValueType()), Mask);
     return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, VT, Vec,
-                       DAG.getConstant(0, getPointerTy()));
+                       DAG.getIntPtrConstant(0));
   }
 
   return SDOperand();
@@ -3605,20 +3740,10 @@ X86TargetLowering::LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
     if (N1.getValueType() != MVT::i32)
       N1 = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, N1);
     if (N2.getValueType() != MVT::i32)
-      N2 = DAG.getConstant(cast<ConstantSDNode>(N2)->getValue(),getPointerTy());
+      N2 = DAG.getIntPtrConstant(cast<ConstantSDNode>(N2)->getValue());
     return DAG.getNode(X86ISD::PINSRW, VT, N0, N1, N2);
   }
-
-  N1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, N1);
-  unsigned Idx = cast<ConstantSDNode>(N2)->getValue();
-  MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4);
-  MVT::ValueType MaskEVT = MVT::getVectorElementType(MaskVT);
-  SmallVector<SDOperand, 4> MaskVec;
-  for (unsigned i = 0; i < 4; ++i)
-    MaskVec.push_back(DAG.getConstant((i == Idx) ? i+4 : i, MaskEVT));
-  return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, N0, N1,
-                     DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
-                                 &MaskVec[0], MaskVec.size()));
+  return SDOperand();
 }
 
 SDOperand
@@ -3655,6 +3780,9 @@ SDOperand
 X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
   GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
   SDOperand Result = DAG.getTargetGlobalAddress(GV, getPointerTy());
+  // If it's a debug information descriptor, don't mess with it.
+  if (DAG.isVerifiedDebugInfoDesc(Op))
+    return Result;
   Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
   // With PIC, the address is actually $g + Offset.
   if (getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
@@ -3670,7 +3798,8 @@ X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
   // the GV offset field. Platform check is inside GVRequiresExtraLoad() call
   // The same applies for external symbols during PIC codegen
   if (Subtarget->GVRequiresExtraLoad(GV, getTargetMachine(), false))
-    Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
+    Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result,
+                         PseudoSourceValue::getGOT(), 0);
 
   return Result;
 }
@@ -3728,7 +3857,8 @@ LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
   SDOperand Offset = DAG.getNode(X86ISD::Wrapper, PtrVT, TGA);
 
   if (GA->getGlobal()->isDeclaration()) // initial exec TLS model
-    Offset = DAG.getLoad(PtrVT, DAG.getEntryNode(), Offset, NULL, 0);
+    Offset = DAG.getLoad(PtrVT, DAG.getEntryNode(), Offset,
+                         PseudoSourceValue::getGOT(), 0);
 
   // The address of the thread local variable is the add of the thread
   // pointer with the offset of the variable.
@@ -3860,21 +3990,20 @@ SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
   int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
   SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
   SDOperand Chain = DAG.getStore(DAG.getEntryNode(), Op.getOperand(0),
-                                 StackSlot, NULL, 0);
+                                 StackSlot,
+                                 PseudoSourceValue::getFixedStack(),
+                                 SSFI);
 
   // These are really Legal; caller falls through into that case.
-  if (SrcVT==MVT::i32 && Op.getValueType() == MVT::f32 && X86ScalarSSEf32)
+  if (SrcVT == MVT::i32 && isScalarFPTypeInSSEReg(Op.getValueType()))
     return Result;
-  if (SrcVT==MVT::i32 && Op.getValueType() == MVT::f64 && X86ScalarSSEf64)
-    return Result;
-  if (SrcVT==MVT::i64 && Op.getValueType() != MVT::f80 && 
+  if (SrcVT == MVT::i64 && Op.getValueType() != MVT::f80 && 
       Subtarget->is64Bit())
     return Result;
 
   // Build the FILD
   SDVTList Tys;
-  bool useSSE = (X86ScalarSSEf32 && Op.getValueType() == MVT::f32) ||
-                (X86ScalarSSEf64 && Op.getValueType() == MVT::f64);
+  bool useSSE = isScalarFPTypeInSSEReg(Op.getValueType());
   if (useSSE)
     Tys = DAG.getVTList(MVT::f64, MVT::Other, MVT::Flag);
   else
@@ -3904,7 +4033,8 @@ SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
     Ops.push_back(DAG.getValueType(Op.getValueType()));
     Ops.push_back(InFlag);
     Chain = DAG.getNode(X86ISD::FST, Tys, &Ops[0], Ops.size());
-    Result = DAG.getLoad(Op.getValueType(), Chain, StackSlot, NULL, 0);
+    Result = DAG.getLoad(Op.getValueType(), Chain, StackSlot,
+                         PseudoSourceValue::getFixedStack(), SSFI);
   }
 
   return Result;
@@ -3917,10 +4047,7 @@ FP_TO_SINTHelper(SDOperand Op, SelectionDAG &DAG) {
 
   // These are really Legal.
   if (Op.getValueType() == MVT::i32 && 
-      X86ScalarSSEf32 && Op.getOperand(0).getValueType() == MVT::f32)
-    return std::make_pair(SDOperand(), SDOperand());
-  if (Op.getValueType() == MVT::i32 && 
-      X86ScalarSSEf64 && Op.getOperand(0).getValueType() == MVT::f64)
+      isScalarFPTypeInSSEReg(Op.getOperand(0).getValueType()))
     return std::make_pair(SDOperand(), SDOperand());
   if (Subtarget->is64Bit() &&
       Op.getValueType() == MVT::i64 &&
@@ -3943,10 +4070,10 @@ FP_TO_SINTHelper(SDOperand Op, SelectionDAG &DAG) {
 
   SDOperand Chain = DAG.getEntryNode();
   SDOperand Value = Op.getOperand(0);
-  if ((X86ScalarSSEf32 && Op.getOperand(0).getValueType() == MVT::f32) ||
-      (X86ScalarSSEf64 && Op.getOperand(0).getValueType() == MVT::f64)) {
+  if (isScalarFPTypeInSSEReg(Op.getOperand(0).getValueType())) {
     assert(Op.getValueType() == MVT::i64 && "Invalid FP_TO_SINT to lower!");
-    Chain = DAG.getStore(Chain, Value, StackSlot, NULL, 0);
+    Chain = DAG.getStore(Chain, Value, StackSlot,
+                         PseudoSourceValue::getFixedStack(), SSFI);
     SDVTList Tys = DAG.getVTList(Op.getOperand(0).getValueType(), MVT::Other);
     SDOperand Ops[] = {
       Chain, StackSlot, DAG.getValueType(Op.getOperand(0).getValueType())
@@ -4005,7 +4132,8 @@ SDOperand X86TargetLowering::LowerFABS(SDOperand Op, SelectionDAG &DAG) {
   }
   Constant *C = ConstantVector::get(CV);
   SDOperand CPIdx = DAG.getConstantPool(C, getPointerTy(), 4);
-  SDOperand Mask = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, NULL, 0,
+  SDOperand Mask = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
+                               PseudoSourceValue::getConstantPool(), 0,
                                false, 16);
   return DAG.getNode(X86ISD::FAND, VT, Op.getOperand(0), Mask);
 }
@@ -4033,7 +4161,8 @@ SDOperand X86TargetLowering::LowerFNEG(SDOperand Op, SelectionDAG &DAG) {
   }
   Constant *C = ConstantVector::get(CV);
   SDOperand CPIdx = DAG.getConstantPool(C, getPointerTy(), 4);
-  SDOperand Mask = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, NULL, 0,
+  SDOperand Mask = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
+                               PseudoSourceValue::getConstantPool(), 0,
                                false, 16);
   if (MVT::isVector(VT)) {
     return DAG.getNode(ISD::BIT_CONVERT, VT,
@@ -4060,7 +4189,7 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
   }
   // And if it is bigger, shrink it first.
   if (MVT::getSizeInBits(SrcVT) > MVT::getSizeInBits(VT)) {
-    Op1 = DAG.getNode(ISD::FP_ROUND, VT, Op1);
+    Op1 = DAG.getNode(ISD::FP_ROUND, VT, Op1, DAG.getIntPtrConstant(1));
     SrcVT = VT;
     SrcTy = MVT::getTypeForValueType(SrcVT);
   }
@@ -4081,7 +4210,8 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
   }
   Constant *C = ConstantVector::get(CV);
   SDOperand CPIdx = DAG.getConstantPool(C, getPointerTy(), 4);
-  SDOperand Mask1 = DAG.getLoad(SrcVT, DAG.getEntryNode(), CPIdx, NULL, 0,
+  SDOperand Mask1 = DAG.getLoad(SrcVT, DAG.getEntryNode(), CPIdx,
+                                PseudoSourceValue::getConstantPool(), 0,
                                 false, 16);
   SDOperand SignBit = DAG.getNode(X86ISD::FAND, SrcVT, Op1, Mask1);
 
@@ -4093,7 +4223,7 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
                           DAG.getConstant(32, MVT::i32));
     SignBit = DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32, SignBit);
     SignBit = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::f32, SignBit,
-                          DAG.getConstant(0, getPointerTy()));
+                          DAG.getIntPtrConstant(0));
   }
 
   // Clear first operand sign bit.
@@ -4109,7 +4239,8 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
   }
   C = ConstantVector::get(CV);
   CPIdx = DAG.getConstantPool(C, getPointerTy(), 4);
-  SDOperand Mask2 = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, NULL, 0,
+  SDOperand Mask2 = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
+                                PseudoSourceValue::getConstantPool(), 0,
                                 false, 16);
   SDOperand Val = DAG.getNode(X86ISD::FAND, VT, Op0, Mask2);
 
@@ -4173,13 +4304,12 @@ SDOperand X86TargetLowering::LowerSELECT(SDOperand Op, SelectionDAG &DAG) {
     SDOperand Cmp = Cond.getOperand(1);
     unsigned Opc = Cmp.getOpcode();
     MVT::ValueType VT = Op.getValueType();
+    
     bool IllegalFPCMov = false;
-    if (VT == MVT::f32 && !X86ScalarSSEf32)
-      IllegalFPCMov = !hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended());
-    else if (VT == MVT::f64 && !X86ScalarSSEf64)
-      IllegalFPCMov = !hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended());
-    else if (VT == MVT::f80)
+    if (MVT::isFloatingPoint(VT) && !MVT::isVector(VT) &&
+        !isScalarFPTypeInSSEReg(VT))  // FPStack?
       IllegalFPCMov = !hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended());
+    
     if ((Opc == X86ISD::CMP ||
          Opc == X86ISD::COMI ||
          Opc == X86ISD::UCOMI) && !IllegalFPCMov) {
@@ -4258,7 +4388,7 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDOperand Op,
   SDOperand Flag;
   
   MVT::ValueType IntPtr = getPointerTy();
-  MVT::ValueType SPTy = (Subtarget->is64Bit() ? MVT::i64 : MVT::i32);
+  MVT::ValueType SPTy = Subtarget->is64Bit() ? MVT::i64 : MVT::i32;
 
   Chain = DAG.getCopyToReg(Chain, X86::EAX, Size, Flag);
   Flag = Chain.getValue(1);
@@ -4349,7 +4479,7 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
     if (AVT > MVT::i8) {
       if (I) {
         unsigned UBytes = MVT::getSizeInBits(AVT) / 8;
-        Count = DAG.getConstant(I->getValue() / UBytes, getPointerTy());
+        Count = DAG.getIntPtrConstant(I->getValue() / UBytes);
         BytesLeft = I->getValue() % UBytes;
       } else {
         assert(AVT >= MVT::i32 &&
@@ -4461,7 +4591,7 @@ SDOperand X86TargetLowering::LowerMEMCPYInline(SDOperand Chain,
   }
 
   unsigned UBytes = MVT::getSizeInBits(AVT) / 8;
-  SDOperand Count = DAG.getConstant(Size / UBytes, getPointerTy());
+  SDOperand Count = DAG.getIntPtrConstant(Size / UBytes);
   BytesLeft = Size % UBytes;
 
   SDOperand InFlag(0, 0);
@@ -4566,14 +4696,13 @@ SDNode *X86TargetLowering::ExpandREADCYCLECOUNTER(SDNode *N, SelectionDAG &DAG){
 }
 
 SDOperand X86TargetLowering::LowerVASTART(SDOperand Op, SelectionDAG &DAG) {
-  SrcValueSDNode *SV = cast<SrcValueSDNode>(Op.getOperand(2));
+  const Value *SV = cast<SrcValueSDNode>(Op.getOperand(2))->getValue();
 
   if (!Subtarget->is64Bit()) {
     // vastart just stores the address of the VarArgsFrameIndex slot into the
     // memory location argument.
     SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
-    return DAG.getStore(Op.getOperand(0), FR,Op.getOperand(1), SV->getValue(),
-                        SV->getOffset());
+    return DAG.getStore(Op.getOperand(0), FR,Op.getOperand(1), SV, 0);
   }
 
   // __va_list_tag:
@@ -4586,31 +4715,26 @@ SDOperand X86TargetLowering::LowerVASTART(SDOperand Op, SelectionDAG &DAG) {
   // Store gp_offset
   SDOperand Store = DAG.getStore(Op.getOperand(0),
                                  DAG.getConstant(VarArgsGPOffset, MVT::i32),
-                                 FIN, SV->getValue(), SV->getOffset());
+                                 FIN, SV, 0);
   MemOps.push_back(Store);
 
   // Store fp_offset
-  FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
-                    DAG.getConstant(4, getPointerTy()));
+  FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN, DAG.getIntPtrConstant(4));
   Store = DAG.getStore(Op.getOperand(0),
                        DAG.getConstant(VarArgsFPOffset, MVT::i32),
-                       FIN, SV->getValue(), SV->getOffset());
+                       FIN, SV, 0);
   MemOps.push_back(Store);
 
   // Store ptr to overflow_arg_area
-  FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
-                    DAG.getConstant(4, getPointerTy()));
+  FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN, DAG.getIntPtrConstant(4));
   SDOperand OVFIN = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
-  Store = DAG.getStore(Op.getOperand(0), OVFIN, FIN, SV->getValue(),
-                       SV->getOffset());
+  Store = DAG.getStore(Op.getOperand(0), OVFIN, FIN, SV, 0);
   MemOps.push_back(Store);
 
   // Store ptr to reg_save_area.
-  FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
-                    DAG.getConstant(8, getPointerTy()));
+  FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN, DAG.getIntPtrConstant(8));
   SDOperand RSFIN = DAG.getFrameIndex(RegSaveFrameIndex, getPointerTy());
-  Store = DAG.getStore(Op.getOperand(0), RSFIN, FIN, SV->getValue(),
-                       SV->getOffset());
+  Store = DAG.getStore(Op.getOperand(0), RSFIN, FIN, SV, 0);
   MemOps.push_back(Store);
   return DAG.getNode(ISD::TokenFactor, MVT::Other, &MemOps[0], MemOps.size());
 }
@@ -4620,24 +4744,21 @@ SDOperand X86TargetLowering::LowerVACOPY(SDOperand Op, SelectionDAG &DAG) {
   SDOperand Chain = Op.getOperand(0);
   SDOperand DstPtr = Op.getOperand(1);
   SDOperand SrcPtr = Op.getOperand(2);
-  SrcValueSDNode *DstSV = cast<SrcValueSDNode>(Op.getOperand(3));
-  SrcValueSDNode *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4));
+  const Value *DstSV = cast<SrcValueSDNode>(Op.getOperand(3))->getValue();
+  const Value *SrcSV = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
 
-  SrcPtr = DAG.getLoad(getPointerTy(), Chain, SrcPtr,
-                       SrcSV->getValue(), SrcSV->getOffset());
+  SrcPtr = DAG.getLoad(getPointerTy(), Chain, SrcPtr, SrcSV, 0);
   Chain = SrcPtr.getValue(1);
   for (unsigned i = 0; i < 3; ++i) {
-    SDOperand Val = DAG.getLoad(MVT::i64, Chain, SrcPtr,
-                                SrcSV->getValue(), SrcSV->getOffset());
+    SDOperand Val = DAG.getLoad(MVT::i64, Chain, SrcPtr, SrcSV, 0);
     Chain = Val.getValue(1);
-    Chain = DAG.getStore(Chain, Val, DstPtr,
-                         DstSV->getValue(), DstSV->getOffset());
+    Chain = DAG.getStore(Chain, Val, DstPtr, DstSV, 0);
     if (i == 2)
       break;
     SrcPtr = DAG.getNode(ISD::ADD, getPointerTy(), SrcPtr, 
-                         DAG.getConstant(8, getPointerTy()));
+                         DAG.getIntPtrConstant(8));
     DstPtr = DAG.getNode(ISD::ADD, getPointerTy(), DstPtr, 
-                         DAG.getConstant(8, getPointerTy()));
+                         DAG.getIntPtrConstant(8));
   }
   return Chain;
 }
@@ -4768,7 +4889,7 @@ SDOperand X86TargetLowering::LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG) {
     
   SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG);
   return DAG.getNode(ISD::SUB, getPointerTy(), RetAddrFI, 
-                     DAG.getConstant(4, getPointerTy()));
+                     DAG.getIntPtrConstant(4));
 }
 
 SDOperand X86TargetLowering::LowerFRAME_TO_ARGS_OFFSET(SDOperand Op,
@@ -4777,7 +4898,7 @@ SDOperand X86TargetLowering::LowerFRAME_TO_ARGS_OFFSET(SDOperand Op,
   if (Subtarget->is64Bit())
     return SDOperand();
   
-  return DAG.getConstant(8, getPointerTy());
+  return DAG.getIntPtrConstant(8);
 }
 
 SDOperand X86TargetLowering::LowerEH_RETURN(SDOperand Op, SelectionDAG &DAG)
@@ -4794,7 +4915,7 @@ SDOperand X86TargetLowering::LowerEH_RETURN(SDOperand Op, SelectionDAG &DAG)
                                     getPointerTy());
 
   SDOperand StoreAddr = DAG.getNode(ISD::SUB, getPointerTy(), Frame,
-                                    DAG.getConstant(-4UL, getPointerTy()));
+                                    DAG.getIntPtrConstant(-4UL));
   StoreAddr = DAG.getNode(ISD::ADD, getPointerTy(), StoreAddr, Offset);
   Chain = DAG.getStore(Chain, Handler, StoreAddr, NULL, 0);
   Chain = DAG.getCopyToReg(Chain, X86::ECX, StoreAddr);
@@ -4811,12 +4932,61 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
   SDOperand FPtr = Op.getOperand(2); // nested function
   SDOperand Nest = Op.getOperand(3); // 'nest' parameter value
 
-  SrcValueSDNode *TrmpSV = cast<SrcValueSDNode>(Op.getOperand(4));
+  const Value *TrmpAddr = cast<SrcValueSDNode>(Op.getOperand(4))->getValue();
+
+  const X86InstrInfo *TII =
+    ((X86TargetMachine&)getTargetMachine()).getInstrInfo();
 
   if (Subtarget->is64Bit()) {
-    return SDOperand(); // not yet supported
+    SDOperand OutChains[6];
+
+    // Large code-model.
+
+    const unsigned char JMP64r  = TII->getBaseOpcodeFor(X86::JMP64r);
+    const unsigned char MOV64ri = TII->getBaseOpcodeFor(X86::MOV64ri);
+
+    const unsigned char N86R10 =
+      ((const X86RegisterInfo*)RegInfo)->getX86RegNum(X86::R10);
+    const unsigned char N86R11 =
+      ((const X86RegisterInfo*)RegInfo)->getX86RegNum(X86::R11);
+
+    const unsigned char REX_WB = 0x40 | 0x08 | 0x01; // REX prefix
+
+    // Load the pointer to the nested function into R11.
+    unsigned OpCode = ((MOV64ri | N86R11) << 8) | REX_WB; // movabsq r11
+    SDOperand Addr = Trmp;
+    OutChains[0] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
+                                TrmpAddr, 0);
+
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(2, MVT::i64));
+    OutChains[1] = DAG.getStore(Root, FPtr, Addr, TrmpAddr, 2, false, 2);
+
+    // Load the 'nest' parameter value into R10.
+    // R10 is specified in X86CallingConv.td
+    OpCode = ((MOV64ri | N86R10) << 8) | REX_WB; // movabsq r10
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(10, MVT::i64));
+    OutChains[2] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
+                                TrmpAddr, 10);
+
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(12, MVT::i64));
+    OutChains[3] = DAG.getStore(Root, Nest, Addr, TrmpAddr, 12, false, 2);
+
+    // Jump to the nested function.
+    OpCode = (JMP64r << 8) | REX_WB; // jmpq *...
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(20, MVT::i64));
+    OutChains[4] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
+                                TrmpAddr, 20);
+
+    unsigned char ModRM = N86R11 | (4 << 3) | (3 << 6); // ...r11
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(22, MVT::i64));
+    OutChains[5] = DAG.getStore(Root, DAG.getConstant(ModRM, MVT::i8), Addr,
+                                TrmpAddr, 22);
+
+    SDOperand Ops[] =
+      { Trmp, DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains, 6) };
+    return DAG.getNode(ISD::MERGE_VALUES, Op.Val->getVTList(), Ops, 2);
   } else {
-    Function *Func = (Function *)
+    const Function *Func =
       cast<Function>(cast<SrcValueSDNode>(Op.getOperand(5))->getValue());
     unsigned CC = Func->getCallingConv();
     unsigned NestReg;
@@ -4858,32 +5028,28 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
       break;
     }
 
-    const X86InstrInfo *TII =
-      ((X86TargetMachine&)getTargetMachine()).getInstrInfo();
-
     SDOperand OutChains[4];
     SDOperand Addr, Disp;
 
     Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(10, MVT::i32));
     Disp = DAG.getNode(ISD::SUB, MVT::i32, FPtr, Addr);
 
-    unsigned char MOV32ri = TII->getBaseOpcodeFor(X86::MOV32ri);
-    unsigned char N86Reg  = ((X86RegisterInfo*)RegInfo)->getX86RegNum(NestReg);
+    const unsigned char MOV32ri = TII->getBaseOpcodeFor(X86::MOV32ri);
+    const unsigned char N86Reg =
+      ((const X86RegisterInfo*)RegInfo)->getX86RegNum(NestReg);
     OutChains[0] = DAG.getStore(Root, DAG.getConstant(MOV32ri|N86Reg, MVT::i8),
-                                Trmp, TrmpSV->getValue(), TrmpSV->getOffset());
+                                Trmp, TrmpAddr, 0);
 
     Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(1, MVT::i32));
-    OutChains[1] = DAG.getStore(Root, Nest, Addr, TrmpSV->getValue(),
-                                TrmpSV->getOffset() + 1, false, 1);
+    OutChains[1] = DAG.getStore(Root, Nest, Addr, TrmpAddr, 1, false, 1);
 
-    unsigned char JMP = TII->getBaseOpcodeFor(X86::JMP);
+    const unsigned char JMP = TII->getBaseOpcodeFor(X86::JMP);
     Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(5, MVT::i32));
     OutChains[2] = DAG.getStore(Root, DAG.getConstant(JMP, MVT::i8), Addr,
-                                TrmpSV->getValue() + 5, TrmpSV->getOffset());
+                                TrmpAddr, 5, false, 1);
 
     Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(6, MVT::i32));
-    OutChains[3] = DAG.getStore(Root, Disp, Addr, TrmpSV->getValue(),
-                                TrmpSV->getOffset() + 6, false, 1);
+    OutChains[3] = DAG.getStore(Root, Disp, Addr, TrmpAddr, 6, false, 1);
 
     SDOperand Ops[] =
       { Trmp, DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains, 4) };
@@ -4891,7 +5057,7 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
   }
 }
 
-SDOperand X86TargetLowering::LowerFLT_ROUNDS(SDOperand Op, SelectionDAG &DAG) {
+SDOperand X86TargetLowering::LowerFLT_ROUNDS_(SDOperand Op, SelectionDAG &DAG) {
   /*
    The rounding mode is in bits 11:10 of FPSR, and has the following
    settings:
@@ -5052,7 +5218,7 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
   case ISD::EH_RETURN:          return LowerEH_RETURN(Op, DAG);
   case ISD::TRAMPOLINE:         return LowerTRAMPOLINE(Op, DAG);
-  case ISD::FLT_ROUNDS:         return LowerFLT_ROUNDS(Op, DAG);
+  case ISD::FLT_ROUNDS_:        return LowerFLT_ROUNDS_(Op, DAG);
   case ISD::CTLZ:               return LowerCTLZ(Op, DAG);
   case ISD::CTTZ:               return LowerCTTZ(Op, DAG);
       
@@ -5090,6 +5256,7 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
   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_GET_RESULT2:     return "X86ISD::FP_GET_RESULT2";
   case X86ISD::FP_SET_RESULT:      return "X86ISD::FP_SET_RESULT";
   case X86ISD::CALL:               return "X86ISD::CALL";
   case X86ISD::TAILCALL:           return "X86ISD::TAILCALL";
@@ -5230,8 +5397,8 @@ bool X86TargetLowering::isVectorClearMaskLegal(std::vector<SDOperand> &BVOps,
 //===----------------------------------------------------------------------===//
 
 MachineBasicBlock *
-X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
-                                           MachineBasicBlock *BB) {
+X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
+                                               MachineBasicBlock *BB) {
   const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
   switch (MI->getOpcode()) {
   default: assert(false && "Unexpected instr type to insert");
@@ -5485,19 +5652,10 @@ static bool isConsecutiveLoad(SDNode *N, SDNode *Base, int Dist, int Size,
 static bool isBaseAlignment16(SDNode *Base, MachineFrameInfo *MFI,
                               const X86Subtarget *Subtarget) {
   GlobalValue *GV;
-  int64_t Offset;
+  int64_t Offset = 0;
   if (isGAPlusOffset(Base, GV, Offset))
     return (GV->getAlignment() >= 16 && (Offset % 16) == 0);
-  else {
-    assert(Base->getOpcode() == ISD::FrameIndex && "Unexpected base node!");
-    int BFI = cast<FrameIndexSDNode>(Base)->getIndex();
-    if (BFI < 0)
-      // Fixed objects do not specify alignment, however the offsets are known.
-      return ((Subtarget->getStackAlignment() % 16) == 0 &&
-              (MFI->getObjectOffset(BFI) % 16) == 0);
-    else
-      return MFI->getObjectAlignment(BFI) >= 16;
-  }
+  // DAG combine handles the stack object case.
   return false;
 }
 
@@ -5616,16 +5774,45 @@ static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
   return SDOperand();
 }
 
+/// PerformFORCombine - Do target-specific dag combines on X86ISD::FOR and
+/// X86ISD::FXOR nodes.
+static SDOperand PerformFORCombine(SDNode *N, SelectionDAG &DAG) {
+  assert(N->getOpcode() == X86ISD::FOR || N->getOpcode() == X86ISD::FXOR);
+  // F[X]OR(0.0, x) -> x
+  // F[X]OR(x, 0.0) -> x
+  if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(N->getOperand(0)))
+    if (C->getValueAPF().isPosZero())
+      return N->getOperand(1);
+  if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(N->getOperand(1)))
+    if (C->getValueAPF().isPosZero())
+      return N->getOperand(0);
+  return SDOperand();
+}
+
+/// PerformFANDCombine - Do target-specific dag combines on X86ISD::FAND nodes.
+static SDOperand PerformFANDCombine(SDNode *N, SelectionDAG &DAG) {
+  // FAND(0.0, x) -> 0.0
+  // FAND(x, 0.0) -> 0.0
+  if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(N->getOperand(0)))
+    if (C->getValueAPF().isPosZero())
+      return N->getOperand(0);
+  if (ConstantFPSDNode *C = dyn_cast<ConstantFPSDNode>(N->getOperand(1)))
+    if (C->getValueAPF().isPosZero())
+      return N->getOperand(1);
+  return SDOperand();
+}
+
 
 SDOperand X86TargetLowering::PerformDAGCombine(SDNode *N,
                                                DAGCombinerInfo &DCI) const {
   SelectionDAG &DAG = DCI.DAG;
   switch (N->getOpcode()) {
   default: break;
-  case ISD::VECTOR_SHUFFLE:
-    return PerformShuffleCombine(N, DAG, Subtarget);
-  case ISD::SELECT:
-    return PerformSELECTCombine(N, DAG, Subtarget);
+  case ISD::VECTOR_SHUFFLE: return PerformShuffleCombine(N, DAG, Subtarget);
+  case ISD::SELECT:         return PerformSELECTCombine(N, DAG, Subtarget);
+  case X86ISD::FXOR:
+  case X86ISD::FOR:         return PerformFORCombine(N, DAG);
+  case X86ISD::FAND:        return PerformFANDCombine(N, DAG);
   }
 
   return SDOperand();
@@ -5657,6 +5844,22 @@ X86TargetLowering::getConstraintType(const std::string &Constraint) const {
   return TargetLowering::getConstraintType(Constraint);
 }
 
+/// LowerXConstraint - try to replace an X constraint, which matches anything,
+/// with another that has more specific requirements based on the type of the
+/// corresponding operand.
+void X86TargetLowering::lowerXConstraint(MVT::ValueType ConstraintVT, 
+                                         std::string& s) const {
+  if (MVT::isFloatingPoint(ConstraintVT)) {
+    if (Subtarget->hasSSE2())
+      s = "Y";
+    else if (Subtarget->hasSSE1())
+      s = "x";
+    else
+      s = "f";
+  } else
+    return TargetLowering::lowerXConstraint(ConstraintVT, s);
+}
+
 /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
 /// vector.  If it is invalid, don't add anything to Ops.
 void X86TargetLowering::LowerAsmOperandForConstraint(SDOperand Op,