This situation can occur:
[oota-llvm.git] / lib / Target / X86 / X86ISelLowering.cpp
index df30aa545ea8564a99365cd98c0f215be6a0563c..13fe5cc159d21b82dda6f02bdb6c5a6e00af0d63 100644 (file)
@@ -25,7 +25,6 @@
 #include "llvm/Intrinsics.h"
 #include "llvm/ADT/BitVector.h"
 #include "llvm/ADT/VectorExtras.h"
-#include "llvm/Analysis/ScalarEvolutionExpressions.h"
 #include "llvm/CodeGen/CallingConvLower.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/StringExtras.h"
-#include "llvm/ParamAttrsList.h"
 using namespace llvm;
 
-X86TargetLowering::X86TargetLowering(TargetMachine &TM)
+// Forward declarations.
+static SDOperand getMOVLMask(unsigned NumElems, SelectionDAG &DAG);
+
+X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
   : TargetLowering(TM) {
   Subtarget = &TM.getSubtarget<X86Subtarget>();
   X86ScalarSSEf64 = Subtarget->hasSSE2();
@@ -57,7 +58,6 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
 
   // X86 is weird, it always uses i8 for shift amounts and setcc results.
   setShiftAmountType(MVT::i8);
-  setSetCCResultType(MVT::i8);
   setSetCCResultContents(ZeroOrOneSetCCResult);
   setSchedulingPreference(SchedulingForRegPressure);
   setShiftAmountFlavor(Mask);   // shl X, 32 == shl X, 0
@@ -208,14 +208,15 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   setOperationAction(ISD::BRCOND           , MVT::Other, Custom);
   setOperationAction(ISD::BR_CC            , MVT::Other, Expand);
   setOperationAction(ISD::SELECT_CC        , MVT::Other, Expand);
-  setOperationAction(ISD::MEMMOVE          , MVT::Other, Expand);
   if (Subtarget->is64Bit())
     setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i32, Legal);
   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16  , Legal);
   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8   , Legal);
   setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1   , Expand);
   setOperationAction(ISD::FP_ROUND_INREG   , MVT::f32  , Expand);
+  setOperationAction(ISD::FREM             , MVT::f32  , Expand);
   setOperationAction(ISD::FREM             , MVT::f64  , Expand);
+  setOperationAction(ISD::FREM             , MVT::f80  , Expand);
   setOperationAction(ISD::FLT_ROUNDS_      , MVT::i32  , Custom);
   
   setOperationAction(ISD::CTPOP            , MVT::i8   , Expand);
@@ -265,6 +266,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   setOperationAction(ISD::JumpTable       , MVT::i32  , Custom);
   setOperationAction(ISD::GlobalAddress   , MVT::i32  , Custom);
   setOperationAction(ISD::GlobalTLSAddress, MVT::i32  , Custom);
+  if (Subtarget->is64Bit())
+    setOperationAction(ISD::GlobalTLSAddress, MVT::i64, Custom);
   setOperationAction(ISD::ExternalSymbol  , MVT::i32  , Custom);
   if (Subtarget->is64Bit()) {
     setOperationAction(ISD::ConstantPool  , MVT::i64  , Custom);
@@ -276,13 +279,24 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   setOperationAction(ISD::SHL_PARTS       , MVT::i32  , Custom);
   setOperationAction(ISD::SRA_PARTS       , MVT::i32  , Custom);
   setOperationAction(ISD::SRL_PARTS       , MVT::i32  , Custom);
-  // X86 wants to expand memset / memcpy itself.
-  setOperationAction(ISD::MEMSET          , MVT::Other, Custom);
-  setOperationAction(ISD::MEMCPY          , MVT::Other, Custom);
+  if (Subtarget->is64Bit()) {
+    setOperationAction(ISD::SHL_PARTS     , MVT::i64  , Custom);
+    setOperationAction(ISD::SRA_PARTS     , MVT::i64  , Custom);
+    setOperationAction(ISD::SRL_PARTS     , MVT::i64  , Custom);
+  }
+
+  if (Subtarget->hasSSE1())
+    setOperationAction(ISD::PREFETCH      , MVT::Other, Legal);
 
   if (!Subtarget->hasSSE2())
     setOperationAction(ISD::MEMBARRIER    , MVT::Other, Expand);
 
+  // Expand certain atomics
+  setOperationAction(ISD::ATOMIC_LCS     , MVT::i8, Custom);
+  setOperationAction(ISD::ATOMIC_LCS     , MVT::i16, Custom);
+  setOperationAction(ISD::ATOMIC_LCS     , MVT::i32, Custom);
+  setOperationAction(ISD::ATOMIC_LCS     , MVT::i64, Custom);
+  setOperationAction(ISD::ATOMIC_LSS     , MVT::i32, Expand);
 
   // Use the default ISD::LOCATION, ISD::DECLARE expansion.
   setOperationAction(ISD::LOCATION, MVT::Other, Expand);
@@ -312,12 +326,14 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
 
   // VASTART needs to be custom lowered to use the VarArgsFrameIndex
   setOperationAction(ISD::VASTART           , MVT::Other, Custom);
-  setOperationAction(ISD::VAARG             , MVT::Other, Expand);
   setOperationAction(ISD::VAEND             , MVT::Other, Expand);
-  if (Subtarget->is64Bit())
+  if (Subtarget->is64Bit()) {
+    setOperationAction(ISD::VAARG           , MVT::Other, Custom);
     setOperationAction(ISD::VACOPY          , MVT::Other, Custom);
-  else
+  } else {
+    setOperationAction(ISD::VAARG           , MVT::Other, Expand);
     setOperationAction(ISD::VACOPY          , MVT::Other, Expand);
+  }
 
   setOperationAction(ISD::STACKSAVE,          MVT::Other, Expand);
   setOperationAction(ISD::STACKRESTORE,       MVT::Other, Expand);
@@ -349,10 +365,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     // We don't support sin/cos/fmod
     setOperationAction(ISD::FSIN , MVT::f64, Expand);
     setOperationAction(ISD::FCOS , MVT::f64, Expand);
-    setOperationAction(ISD::FREM , MVT::f64, Expand);
     setOperationAction(ISD::FSIN , MVT::f32, Expand);
     setOperationAction(ISD::FCOS , MVT::f32, Expand);
-    setOperationAction(ISD::FREM , MVT::f32, Expand);
 
     // Expand FP immediates into loads from the stack, except for the special
     // cases we handle.
@@ -389,7 +403,6 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     // We don't support sin/cos/fmod
     setOperationAction(ISD::FSIN , MVT::f32, Expand);
     setOperationAction(ISD::FCOS , MVT::f32, Expand);
-    setOperationAction(ISD::FREM , MVT::f32, Expand);
 
     // Special cases we handle for FP constants.
     addLegalFPImmediate(APFloat(+0.0f)); // xorps
@@ -479,43 +492,44 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   // will selectively turn on ones that can be effectively codegen'd.
   for (unsigned VT = (unsigned)MVT::FIRST_VECTOR_VALUETYPE;
        VT <= (unsigned)MVT::LAST_VECTOR_VALUETYPE; ++VT) {
-    setOperationAction(ISD::ADD , (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::SUB , (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::FADD, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::FNEG, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::FSUB, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::MUL , (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::FMUL, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::SDIV, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::UDIV, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::FDIV, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::SREM, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::UREM, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::LOAD, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::VECTOR_SHUFFLE,     (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::INSERT_VECTOR_ELT,  (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::FABS, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::FSIN, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::FCOS, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::FREM, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::FPOWI, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::FSQRT, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::FCOPYSIGN, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::SMUL_LOHI, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::UMUL_LOHI, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::SDIVREM, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::UDIVREM, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::FPOW, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::CTPOP, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::CTTZ, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::CTLZ, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::SHL, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::SRA, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::SRL, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::ROTL, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::ROTR, (MVT::ValueType)VT, Expand);
-    setOperationAction(ISD::BSWAP, (MVT::ValueType)VT, Expand);
+    setOperationAction(ISD::ADD , (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::SUB , (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FADD, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FNEG, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FSUB, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::MUL , (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FMUL, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::SDIV, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::UDIV, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FDIV, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::SREM, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::UREM, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::LOAD, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::VECTOR_SHUFFLE,     (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::EXTRACT_VECTOR_ELT, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::INSERT_VECTOR_ELT,  (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FABS, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FSIN, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FCOS, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FREM, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FPOWI, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FSQRT, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FCOPYSIGN, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::SMUL_LOHI, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::UMUL_LOHI, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::SDIVREM, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::UDIVREM, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FPOW, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::CTPOP, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::CTTZ, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::CTLZ, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::SHL, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::SRA, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::SRL, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::ROTL, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::ROTR, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::BSWAP, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::VSETCC, (MVT::SimpleValueType)VT, Expand);
   }
 
   if (Subtarget->hasMMX()) {
@@ -600,6 +614,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     setOperationAction(ISD::VECTOR_SHUFFLE,     MVT::v4f32, Custom);
     setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Custom);
     setOperationAction(ISD::SELECT,             MVT::v4f32, Custom);
+    setOperationAction(ISD::VSETCC,             MVT::v4f32, Legal);
   }
 
   if (Subtarget->hasSSE2()) {
@@ -625,6 +640,12 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     setOperationAction(ISD::FSQRT,              MVT::v2f64, Legal);
     setOperationAction(ISD::FNEG,               MVT::v2f64, Custom);
 
+    setOperationAction(ISD::VSETCC,             MVT::v2f64, Legal);
+    setOperationAction(ISD::VSETCC,             MVT::v16i8, Legal);
+    setOperationAction(ISD::VSETCC,             MVT::v8i16, Legal);
+    setOperationAction(ISD::VSETCC,             MVT::v4i32, Legal);
+    setOperationAction(ISD::VSETCC,             MVT::v2i64, Legal);
+
     setOperationAction(ISD::SCALAR_TO_VECTOR,   MVT::v16i8, Custom);
     setOperationAction(ISD::SCALAR_TO_VECTOR,   MVT::v8i16, Custom);
     setOperationAction(ISD::INSERT_VECTOR_ELT,  MVT::v8i16, Custom);
@@ -632,13 +653,14 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     setOperationAction(ISD::INSERT_VECTOR_ELT,  MVT::v4f32, Custom);
 
     // Custom lower build_vector, vector_shuffle, and extract_vector_elt.
-    for (unsigned VT = (unsigned)MVT::v16i8; VT != (unsigned)MVT::v2i64; VT++) {
+    for (unsigned i = (unsigned)MVT::v16i8; i != (unsigned)MVT::v2i64; ++i) {
+      MVT VT = (MVT::SimpleValueType)i;
       // Do not attempt to custom lower non-power-of-2 vectors
-      if (!isPowerOf2_32(MVT::getVectorNumElements(VT)))
+      if (!isPowerOf2_32(VT.getVectorNumElements()))
         continue;
-      setOperationAction(ISD::BUILD_VECTOR,        (MVT::ValueType)VT, Custom);
-      setOperationAction(ISD::VECTOR_SHUFFLE,      (MVT::ValueType)VT, Custom);
-      setOperationAction(ISD::EXTRACT_VECTOR_ELT,  (MVT::ValueType)VT, Custom);
+      setOperationAction(ISD::BUILD_VECTOR,       VT, Custom);
+      setOperationAction(ISD::VECTOR_SHUFFLE,     VT, Custom);
+      setOperationAction(ISD::EXTRACT_VECTOR_ELT, VT, Custom);
     }
     setOperationAction(ISD::BUILD_VECTOR,       MVT::v2f64, Custom);
     setOperationAction(ISD::BUILD_VECTOR,       MVT::v2i64, Custom);
@@ -653,16 +675,16 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
 
     // Promote v16i8, v8i16, v4i32 load, select, and, or, xor to v2i64.
     for (unsigned VT = (unsigned)MVT::v16i8; VT != (unsigned)MVT::v2i64; VT++) {
-      setOperationAction(ISD::AND,    (MVT::ValueType)VT, Promote);
-      AddPromotedToType (ISD::AND,    (MVT::ValueType)VT, MVT::v2i64);
-      setOperationAction(ISD::OR,     (MVT::ValueType)VT, Promote);
-      AddPromotedToType (ISD::OR,     (MVT::ValueType)VT, MVT::v2i64);
-      setOperationAction(ISD::XOR,    (MVT::ValueType)VT, Promote);
-      AddPromotedToType (ISD::XOR,    (MVT::ValueType)VT, MVT::v2i64);
-      setOperationAction(ISD::LOAD,   (MVT::ValueType)VT, Promote);
-      AddPromotedToType (ISD::LOAD,   (MVT::ValueType)VT, MVT::v2i64);
-      setOperationAction(ISD::SELECT, (MVT::ValueType)VT, Promote);
-      AddPromotedToType (ISD::SELECT, (MVT::ValueType)VT, MVT::v2i64);
+      setOperationAction(ISD::AND,    (MVT::SimpleValueType)VT, Promote);
+      AddPromotedToType (ISD::AND,    (MVT::SimpleValueType)VT, MVT::v2i64);
+      setOperationAction(ISD::OR,     (MVT::SimpleValueType)VT, Promote);
+      AddPromotedToType (ISD::OR,     (MVT::SimpleValueType)VT, MVT::v2i64);
+      setOperationAction(ISD::XOR,    (MVT::SimpleValueType)VT, Promote);
+      AddPromotedToType (ISD::XOR,    (MVT::SimpleValueType)VT, MVT::v2i64);
+      setOperationAction(ISD::LOAD,   (MVT::SimpleValueType)VT, Promote);
+      AddPromotedToType (ISD::LOAD,   (MVT::SimpleValueType)VT, MVT::v2i64);
+      setOperationAction(ISD::SELECT, (MVT::SimpleValueType)VT, Promote);
+      AddPromotedToType (ISD::SELECT, (MVT::SimpleValueType)VT, MVT::v2i64);
     }
 
     setTruncStoreAction(MVT::f64, MVT::f32, Expand);
@@ -672,11 +694,13 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     setOperationAction(ISD::LOAD,               MVT::v2i64, Legal);
     setOperationAction(ISD::SELECT,             MVT::v2f64, Custom);
     setOperationAction(ISD::SELECT,             MVT::v2i64, Custom);
+    
   }
   
   if (Subtarget->hasSSE41()) {
     // FIXME: Do we need to handle scalar-to-vector here?
     setOperationAction(ISD::MUL,                MVT::v4i32, Legal);
+    setOperationAction(ISD::MUL,                MVT::v2i64, Legal);
 
     // i8 and i16 vectors are custom , because the source register and source
     // source memory operand types are not the same width.  f32 vectors are
@@ -690,7 +714,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v16i8, Custom);
     setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v8i16, Custom);
     setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4i32, Legal);
-    setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Legal);
+    setOperationAction(ISD::EXTRACT_VECTOR_ELT, MVT::v4f32, Custom);
 
     if (Subtarget->is64Bit()) {
       setOperationAction(ISD::INSERT_VECTOR_ELT,  MVT::v2i64, Legal);
@@ -703,6 +727,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
 
   // We have target-specific dag combine patterns for the following nodes:
   setTargetDAGCombine(ISD::VECTOR_SHUFFLE);
+  setTargetDAGCombine(ISD::BUILD_VECTOR);
   setTargetDAGCombine(ISD::SELECT);
   setTargetDAGCombine(ISD::STORE);
 
@@ -712,10 +737,17 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   // be smaller when we are in optimizing for size mode.
   maxStoresPerMemset = 16; // For %llvm.memset -> sequence of stores
   maxStoresPerMemcpy = 16; // For %llvm.memcpy -> sequence of stores
-  maxStoresPerMemmove = 16; // For %llvm.memmove -> sequence of stores
+  maxStoresPerMemmove = 3; // For %llvm.memmove -> sequence of stores
   allowUnalignedMemoryAccesses = true; // x86 supports it!
+  setPrefLoopAlignment(16);
 }
 
+
+MVT X86TargetLowering::getSetCCResultType(const SDOperand &) const {
+  return MVT::i8;
+}
+
+
 /// getMaxByValAlign - Helper for getByValTypeAlignment to determine
 /// the desired ByVal argument alignment.
 static void getMaxByValAlign(const Type *Ty, unsigned &MaxAlign) {
@@ -755,6 +787,23 @@ unsigned X86TargetLowering::getByValTypeAlignment(const Type *Ty) const {
   return Align;
 }
 
+/// getOptimalMemOpType - Returns the target specific optimal type for load
+/// and store operations as a result of memset, memcpy, and memmove
+/// lowering. It returns MVT::iAny if SelectionDAG should be responsible for
+/// determining it.
+MVT
+X86TargetLowering::getOptimalMemOpType(uint64_t Size, unsigned Align,
+                                       bool isSrcConst, bool isSrcStr) const {
+  if ((isSrcConst || isSrcStr) && Subtarget->hasSSE2() && Size >= 16)
+    return MVT::v4i32;
+  if ((isSrcConst || isSrcStr) && Subtarget->hasSSE1() && Size >= 16)
+    return MVT::v4f32;
+  if (Subtarget->is64Bit() && Size >= 8)
+    return MVT::i64;
+  return MVT::i32;
+}
+
+
 /// getPICJumpTableRelocaBase - Returns relocation base for the given PIC
 /// jumptable.
 SDOperand X86TargetLowering::getPICJumpTableRelocBase(SDOperand Table,
@@ -772,19 +821,6 @@ SDOperand X86TargetLowering::getPICJumpTableRelocBase(SDOperand Table,
 
 #include "X86GenCallingConv.inc"
 
-/// GetPossiblePreceedingTailCall - Get preceeding X86ISD::TAILCALL node if it
-/// exists skip possible ISD:TokenFactor.
-static SDOperand GetPossiblePreceedingTailCall(SDOperand Chain) {
-  if (Chain.getOpcode() == X86ISD::TAILCALL) {
-    return Chain;
-  } else if (Chain.getOpcode() == ISD::TokenFactor) {
-    if (Chain.getNumOperands() &&
-        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");
@@ -805,7 +841,7 @@ SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) {
   SDOperand Chain = Op.getOperand(0);
   
   // Handle tail call return.
-  Chain = GetPossiblePreceedingTailCall(Chain);
+  Chain = GetPossiblePreceedingTailCall(Chain, X86ISD::TAILCALL);
   if (Chain.getOpcode() == X86ISD::TAILCALL) {
     SDOperand TailCall = Chain;
     SDOperand TargetAddress = TailCall.getOperand(1);
@@ -835,37 +871,60 @@ SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) {
   // Regular return.
   SDOperand Flag;
 
+  SmallVector<SDOperand, 6> RetOps;
+  RetOps.push_back(Chain); // Operand #0 = Chain (updated below)
+  // Operand #1 = Bytes To Pop
+  RetOps.push_back(DAG.getConstant(getBytesToPopOnReturn(), MVT::i16));
+  
   // Copy the result values into the output registers.
-  if (RVLocs.size() != 1 || !RVLocs[0].isRegLoc() ||
-      RVLocs[0].getLocReg() != X86::ST0) {
-    for (unsigned i = 0; i != RVLocs.size(); ++i) {
-      CCValAssign &VA = RVLocs[i];
-      assert(VA.isRegLoc() && "Can only return in registers!");
-      Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), Op.getOperand(i*2+1),
-                               Flag);
-      Flag = Chain.getValue(1);
-    }
-  } else {
-    // We need to handle a destination of ST0 specially, because it isn't really
-    // a register.
-    SDOperand Value = Op.getOperand(1);
+  for (unsigned i = 0; i != RVLocs.size(); ++i) {
+    CCValAssign &VA = RVLocs[i];
+    assert(VA.isRegLoc() && "Can only return in registers!");
+    SDOperand ValToCopy = Op.getOperand(i*2+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);
+    // Returns in ST0/ST1 are handled specially: these are pushed as operands to
+    // the RET instruction and handled by the FP Stackifier.
+    if (RVLocs[i].getLocReg() == X86::ST0 ||
+        RVLocs[i].getLocReg() == X86::ST1) {
+      // If this is a copy from an xmm register to ST(0), use an FPExtend to
+      // change the value to the FP stack register class.
+      if (isScalarFPTypeInSSEReg(RVLocs[i].getValVT()))
+        ValToCopy = DAG.getNode(ISD::FP_EXTEND, MVT::f80, ValToCopy);
+      RetOps.push_back(ValToCopy);
+      // Don't emit a copytoreg.
+      continue;
+    }
     
-    SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
-    SDOperand Ops[] = { Chain, Value };
-    Chain = DAG.getNode(X86ISD::FP_SET_RESULT, Tys, Ops, 2);
+    Chain = DAG.getCopyToReg(Chain, VA.getLocReg(), ValToCopy, Flag);
+    Flag = Chain.getValue(1);
+  }
+
+  // The x86-64 ABI for returning structs by value requires that we copy
+  // the sret argument into %rax for the return. We saved the argument into
+  // a virtual register in the entry block, so now we copy the value out
+  // and into %rax.
+  if (Subtarget->is64Bit() &&
+      DAG.getMachineFunction().getFunction()->hasStructRetAttr()) {
+    MachineFunction &MF = DAG.getMachineFunction();
+    X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
+    unsigned Reg = FuncInfo->getSRetReturnReg();
+    if (!Reg) {
+      Reg = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64));
+      FuncInfo->setSRetReturnReg(Reg);
+    }
+    SDOperand Val = DAG.getCopyFromReg(Chain, Reg, getPointerTy());
+
+    Chain = DAG.getCopyToReg(Chain, X86::RAX, Val, Flag);
     Flag = Chain.getValue(1);
   }
   
-  SDOperand BytesToPop = DAG.getConstant(getBytesToPopOnReturn(), MVT::i16);
+  RetOps[0] = Chain;  // Update chain.
+
+  // Add the flag if we have it.
   if (Flag.Val)
-    return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Chain, BytesToPop, Flag);
-  else
-    return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, Chain, BytesToPop);
+    RetOps.push_back(Flag);
+  
+  return DAG.getNode(X86ISD::RET_FLAG, MVT::Other, &RetOps[0], RetOps.size());
 }
 
 
@@ -887,38 +946,31 @@ LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode *TheCall,
   SmallVector<SDOperand, 8> ResultVals;
   
   // Copy all of the result registers out of their specified physreg.
-  if (RVLocs.size() != 1 || RVLocs[0].getLocReg() != X86::ST0) {
-    for (unsigned i = 0; i != RVLocs.size(); ++i) {
-      Chain = DAG.getCopyFromReg(Chain, RVLocs[i].getLocReg(),
-                                 RVLocs[i].getValVT(), InFlag).getValue(1);
-      InFlag = Chain.getValue(2);
-      ResultVals.push_back(Chain.getValue(0));
-    }
-  } else {
-    // Copies from the FP stack are special, as ST0 isn't a valid register
-    // before the fp stackifier runs.
+  for (unsigned i = 0; i != RVLocs.size(); ++i) {
+    MVT CopyVT = RVLocs[i].getValVT();
     
-    // 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);
+    // If this is a call to a function that returns an fp value on the floating
+    // point stack, but where we prefer to use the value in xmm registers, copy
+    // it out as F80 and use a truncate to move it from fp stack reg to xmm reg.
+    if (RVLocs[i].getLocReg() == X86::ST0 &&
+        isScalarFPTypeInSSEReg(RVLocs[i].getValVT())) {
+      CopyVT = MVT::f80;
+    }
     
-    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 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));
+    Chain = DAG.getCopyFromReg(Chain, RVLocs[i].getLocReg(),
+                               CopyVT, InFlag).getValue(1);
+    SDOperand Val = Chain.getValue(0);
+    InFlag = Chain.getValue(2);
+
+    if (CopyVT != RVLocs[i].getValVT()) {
+      // Round the F80 the right size, which also moves to the appropriate xmm
+      // register.
+      Val = DAG.getNode(ISD::FP_ROUND, RVLocs[i].getValVT(), Val,
+                        // This truncation won't change the value.
+                        DAG.getIntPtrConstant(1));
+    }
     
-    ResultVals.push_back(RetVal);
+    ResultVals.push_back(Val);
   }
   
   // Merge everything together with a MERGE_VALUES node.
@@ -927,44 +979,6 @@ 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
@@ -993,9 +1007,8 @@ static bool CallIsStructReturn(SDOperand Op) {
   unsigned NumOps = (Op.getNumOperands() - 5) / 2;
   if (!NumOps)
     return false;
-  
-  ConstantSDNode *Flags = cast<ConstantSDNode>(Op.getOperand(6));
-  return Flags->getValue() & ISD::ParamFlags::StructReturn;
+
+  return cast<ARG_FLAGSSDNode>(Op.getOperand(6))->getArgFlags().isSRet();
 }
 
 /// ArgsAreStructReturn - Determines whether a FORMAL_ARGUMENTS node uses struct
@@ -1004,13 +1017,12 @@ static bool ArgsAreStructReturn(SDOperand Op) {
   unsigned NumArgs = Op.Val->getNumValues() - 1;
   if (!NumArgs)
     return false;
-  
-  ConstantSDNode *Flags = cast<ConstantSDNode>(Op.getOperand(3));
-  return Flags->getValue() & ISD::ParamFlags::StructReturn;
+
+  return cast<ARG_FLAGSSDNode>(Op.getOperand(3))->getArgFlags().isSRet();
 }
 
-/// IsCalleePop - Determines whether a CALL or FORMAL_ARGUMENTS node requires the
-/// callee to pop its own arguments. Callee pop is necessary to support tail
+/// IsCalleePop - Determines whether a CALL or FORMAL_ARGUMENTS node requires
+/// the callee to pop its own arguments. Callee pop is necessary to support tail
 /// calls.
 bool X86TargetLowering::IsCalleePop(SDOperand Op) {
   bool IsVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
@@ -1035,10 +1047,14 @@ CCAssignFn *X86TargetLowering::CCAssignFnForNode(SDOperand Op) const {
   unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
   
   if (Subtarget->is64Bit()) {
-    if (CC == CallingConv::Fast && PerformTailCallOpt)
-      return CC_X86_64_TailCall;
-    else
-      return CC_X86_64_C;
+    if (Subtarget->isTargetWin64())
+      return CC_X86_Win64_C;
+    else {
+      if (CC == CallingConv::Fast && PerformTailCallOpt)
+        return CC_X86_64_TailCall;
+      else
+        return CC_X86_64_C;
+    }
   }
 
   if (CC == CallingConv::X86_FastCall)
@@ -1061,27 +1077,6 @@ 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.
-static bool IsPossiblyOverwrittenArgumentOfTailCall(SDOperand Op, 
-                                                    MachineFrameInfo * MFI) {
-  RegisterSDNode * OpReg = NULL;
-  FrameIndexSDNode * FrameIdxNode = NULL;
-  int FrameIdx = 0;
-  if (Op.getOpcode() == ISD::FORMAL_ARGUMENTS ||
-      (Op.getOpcode()== ISD::CopyFromReg &&
-       (OpReg = dyn_cast<RegisterSDNode>(Op.getOperand(1))) &&
-       (OpReg->getReg() >= TargetRegisterInfo::FirstVirtualRegister)) ||
-      (Op.getOpcode() == ISD::LOAD &&
-       (FrameIdxNode = dyn_cast<FrameIndexSDNode>(Op.getOperand(1))) &&
-       (MFI->isFixedObjectIndex((FrameIdx = FrameIdxNode->getIndex()))) &&
-       (MFI->getObjectOffset(FrameIdx) >= 0)))
-    return true;
-  return false;
-}
 
 /// CallRequiresGOTInRegister - Check whether the call requires the GOT pointer
 /// in a register before calling.
@@ -1091,7 +1086,6 @@ bool X86TargetLowering::CallRequiresGOTPtrInReg(bool Is64Bit, bool IsTailCall) {
     Subtarget->isPICStyleGOT();
 }
 
-
 /// CallRequiresFnAddressInReg - Check whether the call requires the function
 /// address to be loaded in a register.
 bool 
@@ -1101,48 +1095,16 @@ X86TargetLowering::CallRequiresFnAddressInReg(bool Is64Bit, bool IsTailCall) {
     Subtarget->isPICStyleGOT();
 }
 
-/// CopyTailCallClobberedArgumentsToVRegs - Create virtual registers for all
-/// arguments to force loading and guarantee that arguments sourcing from
-/// incomming parameters are not overwriting each other.
-static SDOperand 
-CopyTailCallClobberedArgumentsToVRegs(SDOperand Chain,
-     SmallVector<std::pair<unsigned, SDOperand>, 8> &TailCallClobberedVRegs,
-                                      SelectionDAG &DAG,
-                                      MachineFunction &MF,
-                                      const TargetLowering * TL) {
-      
-  SDOperand InFlag;
-  for (unsigned i = 0, e = TailCallClobberedVRegs.size(); i != e; i++) {
-    SDOperand Arg = TailCallClobberedVRegs[i].second;
-    unsigned Idx = TailCallClobberedVRegs[i].first;
-    unsigned VReg = 
-      MF.getRegInfo().
-      createVirtualRegister(TL->getRegClassFor(Arg.getValueType()));
-    Chain = DAG.getCopyToReg(Chain, VReg, Arg, InFlag);
-    InFlag = Chain.getValue(1);
-    Arg = DAG.getCopyFromReg(Chain, VReg, Arg.getValueType(), InFlag);
-    TailCallClobberedVRegs[i] = std::make_pair(Idx, Arg);
-    Chain = Arg.getValue(1);
-    InFlag = Arg.getValue(2);
-  }
-  return Chain;
-} 
-
 /// 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.
+/// 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);
+                          ISD::ArgFlagsTy Flags, SelectionDAG &DAG) {
+  SDOperand SizeNode     = DAG.getConstant(Flags.getByValSize(), MVT::i32);
+  return DAG.getMemcpy(Chain, Dst, Src, SizeNode, Flags.getByValAlign(),
+                       /*AlwaysInline=*/true, NULL, 0, NULL, 0);
 }
 
 SDOperand X86TargetLowering::LowerMemArgument(SDOperand Op, SelectionDAG &DAG,
@@ -1151,19 +1113,19 @@ SDOperand X86TargetLowering::LowerMemArgument(SDOperand Op, SelectionDAG &DAG,
                                               unsigned CC,
                                               SDOperand Root, unsigned i) {
   // Create the nodes corresponding to a load from this parameter slot.
-  unsigned Flags = cast<ConstantSDNode>(Op.getOperand(3 + i))->getValue();
+  ISD::ArgFlagsTy Flags =
+    cast<ARG_FLAGSSDNode>(Op.getOperand(3 + i))->getArgFlags();
   bool AlwaysUseMutable = (CC==CallingConv::Fast) && PerformTailCallOpt;
-  bool isByVal = Flags & ISD::ParamFlags::ByVal;
-  bool isImmutable = !AlwaysUseMutable && !isByVal;
+  bool isImmutable = !AlwaysUseMutable && !Flags.isByVal();
 
   // FIXME: For now, all byval parameter objects are marked mutable. This can be
   // changed with more analysis.  
   // In case of tail call optimization mark all arguments mutable. Since they
   // could be overwritten by lowering of arguments in case of a tail call.
-  int FI = MFI->CreateFixedObject(MVT::getSizeInBits(VA.getValVT())/8,
+  int FI = MFI->CreateFixedObject(VA.getValVT().getSizeInBits()/8,
                                   VA.getLocMemOffset(), isImmutable);
   SDOperand FIN = DAG.getFrameIndex(FI, getPointerTy());
-  if (isByVal)
+  if (Flags.isByVal())
     return FIN;
   return DAG.getLoad(VA.getValVT(), Root, FIN,
                      PseudoSourceValue::getFixedStack(), FI);
@@ -1188,6 +1150,7 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
   bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
   unsigned CC = MF.getFunction()->getCallingConv();
   bool Is64Bit = Subtarget->is64Bit();
+  bool IsWin64 = Subtarget->isTargetWin64();
 
   assert(!(isVarArg && CC == CallingConv::Fast) &&
          "Var args not supported with calling convention fastcc");
@@ -1208,7 +1171,7 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
     LastVal = VA.getValNo();
     
     if (VA.isRegLoc()) {
-      MVT::ValueType RegVT = VA.getLocVT();
+      MVT RegVT = VA.getLocVT();
       TargetRegisterClass *RC;
       if (RegVT == MVT::i32)
         RC = X86::GR32RegisterClass;
@@ -1218,13 +1181,25 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
         RC = X86::FR32RegisterClass;
       else if (RegVT == MVT::f64)
         RC = X86::FR64RegisterClass;
-      else {
-        assert(MVT::isVector(RegVT));
-        if (Is64Bit && MVT::getSizeInBits(RegVT) == 64) {
-          RC = X86::GR64RegisterClass;       // MMX values are passed in GPRs.
-          RegVT = MVT::i64;
-        } else
-          RC = X86::VR128RegisterClass;
+      else if (RegVT.isVector() && RegVT.getSizeInBits() == 128)
+        RC = X86::VR128RegisterClass;
+      else if (RegVT.isVector()) {
+        assert(RegVT.getSizeInBits() == 64);
+        if (!Is64Bit)
+          RC = X86::VR64RegisterClass;     // MMX values are passed in MMXs.
+        else {
+          // Darwin calling convention passes MMX values in either GPRs or
+          // XMMs in x86-64. Other targets pass them in memory.
+          if (RegVT != MVT::v1i64 && Subtarget->hasSSE2()) {
+            RC = X86::VR128RegisterClass;  // MMX values are passed in XMMs.
+            RegVT = MVT::v2i64;
+          } else {
+            RC = X86::GR64RegisterClass;   // v1i64 values are passed in GPRs.
+            RegVT = MVT::i64;
+          }
+        }
+      } else {
+        assert(0 && "Unknown argument type!");
       }
 
       unsigned Reg = AddLiveIn(DAG.getMachineFunction(), VA.getLocReg(), RC);
@@ -1244,9 +1219,15 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
         ArgValue = DAG.getNode(ISD::TRUNCATE, VA.getValVT(), ArgValue);
       
       // Handle MMX values passed in GPRs.
-      if (Is64Bit && RegVT != VA.getLocVT() && RC == X86::GR64RegisterClass &&
-          MVT::getSizeInBits(RegVT) == 64)
-        ArgValue = DAG.getNode(ISD::BIT_CONVERT, VA.getLocVT(), ArgValue);
+      if (Is64Bit && RegVT != VA.getLocVT()) {
+        if (RegVT.getSizeInBits() == 64 && RC == X86::GR64RegisterClass)
+          ArgValue = DAG.getNode(ISD::BIT_CONVERT, VA.getLocVT(), ArgValue);
+        else if (RC == X86::VR128RegisterClass) {
+          ArgValue = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i64, ArgValue,
+                                 DAG.getConstant(0, MVT::i64));
+          ArgValue = DAG.getNode(ISD::BIT_CONVERT, VA.getLocVT(), ArgValue);
+        }
+      }
       
       ArgValues.push_back(ArgValue);
     } else {
@@ -1255,6 +1236,21 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
     }
   }
 
+  // The x86-64 ABI for returning structs by value requires that we copy
+  // the sret argument into %rax for the return. Save the argument into
+  // a virtual register so that we can access it from the return points.
+  if (Is64Bit && DAG.getMachineFunction().getFunction()->hasStructRetAttr()) {
+    MachineFunction &MF = DAG.getMachineFunction();
+    X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
+    unsigned Reg = FuncInfo->getSRetReturnReg();
+    if (!Reg) {
+      Reg = MF.getRegInfo().createVirtualRegister(getRegClassFor(MVT::i64));
+      FuncInfo->setSRetReturnReg(Reg);
+    }
+    SDOperand Copy = DAG.getCopyToReg(DAG.getEntryNode(), Reg, ArgValues[0]);
+    Root = DAG.getNode(ISD::TokenFactor, MVT::Other, Copy, Root);
+  }
+
   unsigned StackSize = CCInfo.getNextStackOffset();
   // align stack specially for tail calls
   if (CC == CallingConv::Fast)
@@ -1267,30 +1263,52 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
       VarArgsFrameIndex = MFI->CreateFixedObject(1, StackSize);
     }
     if (Is64Bit) {
-      static const unsigned GPR64ArgRegs[] = {
-        X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8,  X86::R9
+      unsigned TotalNumIntRegs = 0, TotalNumXMMRegs = 0;
+
+      // FIXME: We should really autogenerate these arrays
+      static const unsigned GPR64ArgRegsWin64[] = {
+        X86::RCX, X86::RDX, X86::R8,  X86::R9
       };
-      static const unsigned XMMArgRegs[] = {
+      static const unsigned XMMArgRegsWin64[] = {
+        X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3
+      };
+      static const unsigned GPR64ArgRegs64Bit[] = {
+        X86::RDI, X86::RSI, X86::RDX, X86::RCX, X86::R8, X86::R9
+      };
+      static const unsigned XMMArgRegs64Bit[] = {
         X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
         X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7
       };
-      
-      unsigned NumIntRegs = CCInfo.getFirstUnallocated(GPR64ArgRegs, 6);
-      unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs, 8);
-    
+      const unsigned *GPR64ArgRegs, *XMMArgRegs;
+
+      if (IsWin64) {
+        TotalNumIntRegs = 4; TotalNumXMMRegs = 4;
+        GPR64ArgRegs = GPR64ArgRegsWin64;
+        XMMArgRegs = XMMArgRegsWin64;
+      } else {
+        TotalNumIntRegs = 6; TotalNumXMMRegs = 8;
+        GPR64ArgRegs = GPR64ArgRegs64Bit;
+        XMMArgRegs = XMMArgRegs64Bit;
+      }
+      unsigned NumIntRegs = CCInfo.getFirstUnallocated(GPR64ArgRegs,
+                                                       TotalNumIntRegs);
+      unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs,
+                                                       TotalNumXMMRegs);
+
       // For X86-64, if there are vararg parameters that are passed via
       // registers, then we must store them to their spots on the stack so they
       // may be loaded by deferencing the result of va_next.
       VarArgsGPOffset = NumIntRegs * 8;
-      VarArgsFPOffset = 6 * 8 + NumXMMRegs * 16;
-      RegSaveFrameIndex = MFI->CreateStackObject(6 * 8 + 8 * 16, 16);
-      
+      VarArgsFPOffset = TotalNumIntRegs * 8 + NumXMMRegs * 16;
+      RegSaveFrameIndex = MFI->CreateStackObject(TotalNumIntRegs * 8 +
+                                                 TotalNumXMMRegs * 16, 16);
+
       // Store the integer parameter registers.
       SmallVector<SDOperand, 8> MemOps;
       SDOperand RSFIN = DAG.getFrameIndex(RegSaveFrameIndex, getPointerTy());
       SDOperand FIN = DAG.getNode(ISD::ADD, getPointerTy(), RSFIN,
                                   DAG.getIntPtrConstant(VarArgsGPOffset));
-      for (; NumIntRegs != 6; ++NumIntRegs) {
+      for (; NumIntRegs != TotalNumIntRegs; ++NumIntRegs) {
         unsigned VReg = AddLiveIn(MF, GPR64ArgRegs[NumIntRegs],
                                   X86::GR64RegisterClass);
         SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::i64);
@@ -1302,11 +1320,11 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
         FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
                           DAG.getIntPtrConstant(8));
       }
-      
+
       // Now store the XMM (fp + vector) parameter registers.
       FIN = DAG.getNode(ISD::ADD, getPointerTy(), RSFIN,
                         DAG.getIntPtrConstant(VarArgsFPOffset));
-      for (; NumXMMRegs != 8; ++NumXMMRegs) {
+      for (; NumXMMRegs != TotalNumXMMRegs; ++NumXMMRegs) {
         unsigned VReg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs],
                                   X86::VR128RegisterClass);
         SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::v4f32);
@@ -1368,76 +1386,55 @@ X86TargetLowering::LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG,
   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) {
+  ISD::ArgFlagsTy Flags =
+    cast<ARG_FLAGSSDNode>(Op.getOperand(6+2*VA.getValNo()))->getArgFlags();
+  if (Flags.isByVal()) {
     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;
-    }
-  }
+/// EmitTailCallLoadRetAddr - Emit a load of return adress if tail call
+/// optimization is performed and it is required.
+SDOperand 
+X86TargetLowering::EmitTailCallLoadRetAddr(SelectionDAG &DAG, 
+                                           SDOperand &OutRetAddr,
+                                           SDOperand Chain, 
+                                           bool IsTailCall, 
+                                           bool Is64Bit, 
+                                           int FPDiff) {
+  if (!IsTailCall || FPDiff==0) return Chain;
 
-  if (AllFP)
-    return X86::InSSE;
-  return X86::InGPR64;
+  // Adjust the Return address stack slot.
+  MVT VT = getPointerTy();
+  OutRetAddr = getReturnAddressFrameIndex(DAG);
+  // Load the "old" Return address.
+  OutRetAddr = DAG.getLoad(VT, Chain,OutRetAddr, NULL, 0);
+  return SDOperand(OutRetAddr.Val, 1);
 }
 
-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();
-    }
-  }
+/// EmitTailCallStoreRetAddr - Emit a store of the return adress if tail call
+/// optimization is performed and it is required (FPDiff!=0).
+static SDOperand 
+EmitTailCallStoreRetAddr(SelectionDAG & DAG, MachineFunction &MF, 
+                         SDOperand Chain, SDOperand RetAddrFrIdx,
+                         bool Is64Bit, int FPDiff) {
+  // Store the return address to the appropriate stack slot.
+  if (!FPDiff) return Chain;
+  // Calculate the new stack slot for the return address.
+  int SlotSize = Is64Bit ? 8 : 4;
+  int NewReturnAddrFI = 
+    MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff-SlotSize);
+  MVT VT = Is64Bit ? MVT::i64 : MVT::i32;
+  SDOperand NewRetAddrFrIdx = DAG.getFrameIndex(NewReturnAddrFI, VT);
+  Chain = DAG.getStore(Chain, RetAddrFrIdx, NewRetAddrFrIdx, 
+                       PseudoSourceValue::getFixedStack(), NewReturnAddrFI);
+  return Chain;
 }
 
 SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   MachineFunction &MF = DAG.getMachineFunction();
-  MachineFrameInfo * MFI = MF.getFrameInfo();
   SDOperand Chain     = Op.getOperand(0);
   unsigned CC         = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
   bool isVarArg       = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
@@ -1453,24 +1450,7 @@ 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);
-  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);
+  CCInfo.AnalyzeCallOperands(Op.Val, CCAssignFnForNode(Op));
   
   // Get a count of how many bytes are to be pushed on the stack.
   unsigned NumBytes = CCInfo.getNextStackOffset();
@@ -1500,30 +1480,22 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes));
 
   SDOperand RetAddrFrIdx;
-  if (IsTailCall) {
-    // Adjust the Return address stack slot.
-    if (FPDiff) {
-      MVT::ValueType VT = Is64Bit ? MVT::i64 : MVT::i32;
-      RetAddrFrIdx = getReturnAddressFrameIndex(DAG);
-      // Load the "old" Return address.
-      RetAddrFrIdx = 
-        DAG.getLoad(VT, Chain,RetAddrFrIdx, NULL, 0);
-      Chain = SDOperand(RetAddrFrIdx.Val, 1);
-    }
-  }
+  // Load return adress for tail calls.
+  Chain = EmitTailCallLoadRetAddr(DAG, RetAddrFrIdx, Chain, IsTailCall, Is64Bit,
+                                  FPDiff);
 
   SmallVector<std::pair<unsigned, SDOperand>, 8> RegsToPass;
-  SmallVector<std::pair<unsigned, SDOperand>, 8> TailCallClobberedVRegs;
   SmallVector<SDOperand, 8> MemOpChains;
-
   SDOperand StackPtr;
 
-  // Walk the register/memloc assignments, inserting copies/loads.  For tail
-  // calls, remember all arguments for later special lowering.
+  // Walk the register/memloc assignments, inserting copies/loads.  In the case
+  // of tail call optimization arguments are handle later.
   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
     CCValAssign &VA = ArgLocs[i];
     SDOperand Arg = Op.getOperand(5+2*VA.getValNo());
-    
+    bool isByVal = cast<ARG_FLAGSSDNode>(Op.getOperand(6+2*VA.getValNo()))->
+      getArgFlags().isByVal();
+  
     // Promote the value if needed.
     switch (VA.getLocInfo()) {
     default: assert(0 && "Unknown loc info!");
@@ -1540,17 +1512,39 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
     }
     
     if (VA.isRegLoc()) {
+      if (Is64Bit) {
+        MVT RegVT = VA.getLocVT();
+        if (RegVT.isVector() && RegVT.getSizeInBits() == 64)
+          switch (VA.getLocReg()) {
+          default:
+            break;
+          case X86::RDI: case X86::RSI: case X86::RDX: case X86::RCX:
+          case X86::R8: {
+            // Special case: passing MMX values in GPR registers.
+            Arg = DAG.getNode(ISD::BIT_CONVERT, MVT::i64, Arg);
+            break;
+          }
+          case X86::XMM0: case X86::XMM1: case X86::XMM2: case X86::XMM3:
+          case X86::XMM4: case X86::XMM5: case X86::XMM6: case X86::XMM7: {
+            // Special case: passing MMX values in XMM registers.
+            Arg = DAG.getNode(ISD::BIT_CONVERT, MVT::i64, Arg);
+            Arg = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v2i64, Arg);
+            Arg = DAG.getNode(ISD::VECTOR_SHUFFLE, MVT::v2i64,
+                              DAG.getNode(ISD::UNDEF, MVT::v2i64), Arg,
+                              getMOVLMask(2, DAG));
+            break;
+          }
+          }
+      }
       RegsToPass.push_back(std::make_pair(VA.getLocReg(), Arg));
     } else {
-      if (!IsTailCall) {
+      if (!IsTailCall || (IsTailCall && isByVal)) {
         assert(VA.isMemLoc());
         if (StackPtr.Val == 0)
           StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr, getPointerTy());
         
         MemOpChains.push_back(LowerMemOpCallTo(Op, DAG, StackPtr, VA, Chain,
                                                Arg));
-      } else if (IsPossiblyOverwrittenArgumentOfTailCall(Arg, MFI)) {
-        TailCallClobberedVRegs.push_back(std::make_pair(i,Arg));
       }
     }
   }
@@ -1562,11 +1556,14 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   // Build a sequence of copy-to-reg nodes chained together with token chain
   // and flag operands which copy the outgoing args into registers.
   SDOperand InFlag;
-  for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
-    Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
-                             InFlag);
-    InFlag = Chain.getValue(1);
-  }
+  // Tail call byval lowering might overwrite argument registers so in case of
+  // tail call optimization the copies to registers are lowered later.
+  if (!IsTailCall)
+    for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
+      Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
+                               InFlag);
+      InFlag = Chain.getValue(1);
+    }
 
   // ELF / PIC requires GOT in the EBX register before function calls via PLT
   // GOT pointer.  
@@ -1600,7 +1597,8 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
     // of SSE registers used. The contents of %al do not need to match exactly
     // the number of registers, but must be an ubound on the number of SSE
     // registers used and is in the range 0 - 8 inclusive.
-    
+
+    // FIXME: Verify this on Win64
     // Count the number of XMM registers allocated.
     static const unsigned XMMArgRegs[] = {
       X86::XMM0, X86::XMM1, X86::XMM2, X86::XMM3,
@@ -1621,37 +1619,28 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
     int FI = 0;
     // Do not flag preceeding copytoreg stuff together with the following stuff.
     InFlag = SDOperand();
-    
-    Chain = CopyTailCallClobberedArgumentsToVRegs(Chain, TailCallClobberedVRegs,
-                                                  DAG, MF, this);
     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();
+        ISD::ArgFlagsTy Flags =
+          cast<ARG_FLAGSSDNode>(FlagsOp)->getArgFlags();
         // Create frame index.
         int32_t Offset = VA.getLocMemOffset()+FPDiff;
-        uint32_t OpSize = (MVT::getSizeInBits(VA.getLocVT())+7)/8;
+        uint32_t OpSize = (VA.getLocVT().getSizeInBits()+7)/8;
         FI = MF.getFrameInfo()->CreateFixedObject(OpSize, Offset);
-        FIN = DAG.getFrameIndex(FI, MVT::i32);
-
-        // Find virtual register for this argument.
-        bool Found=false;
-        for (unsigned idx=0, e= TailCallClobberedVRegs.size(); idx < e; idx++)
-          if (TailCallClobberedVRegs[idx].first==i) {
-            Arg = TailCallClobberedVRegs[idx].second;
-            Found=true;
-            break;
-          }
-        assert(IsPossiblyOverwrittenArgumentOfTailCall(Arg, MFI)==false || 
-          (Found==true && "No corresponding Argument was found"));
-        
-        if (Flags & ISD::ParamFlags::ByVal) {
+        FIN = DAG.getFrameIndex(FI, getPointerTy());
+
+        if (Flags.isByVal()) {
           // Copy relative to framepointer.
-          MemOpChains2.push_back(CreateCopyOfByValArgument(Arg, FIN, Chain,
+          SDOperand Source = DAG.getIntPtrConstant(VA.getLocMemOffset());
+          if (StackPtr.Val == 0)
+            StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr, getPointerTy());
+          Source = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, Source);
+
+          MemOpChains2.push_back(CreateCopyOfByValArgument(Source, FIN, Chain,
                                                            Flags, DAG));
         } else {
           // Store relative to framepointer.
@@ -1666,17 +1655,17 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
       Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
                           &MemOpChains2[0], MemOpChains2.size());
 
-    // Store the return address to the appropriate stack slot.
-    if (FPDiff) {
-      // Calculate the new stack slot for the return address.
-      int SlotSize = Is64Bit ? 8 : 4;
-      int NewReturnAddrFI = 
-        MF.getFrameInfo()->CreateFixedObject(SlotSize, FPDiff-SlotSize);
-      MVT::ValueType VT = Is64Bit ? MVT::i64 : MVT::i32;
-      SDOperand NewRetAddrFrIdx = DAG.getFrameIndex(NewReturnAddrFI, VT);
-      Chain = DAG.getStore(Chain, RetAddrFrIdx, NewRetAddrFrIdx, 
-                           PseudoSourceValue::getFixedStack(), NewReturnAddrFI);
+    // Copy arguments to their registers.
+    for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) {
+      Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second,
+                               InFlag);
+      InFlag = Chain.getValue(1);
     }
+    InFlag =SDOperand();
+
+    // Store the return address to the appropriate stack slot.
+    Chain = EmitTailCallStoreRetAddr(DAG, MF, Chain, RetAddrFrIdx, Is64Bit,
+                                     FPDiff);
   }
 
   // If the callee is a GlobalAddress node (quite common, every direct call is)
@@ -1728,18 +1717,22 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   if (IsTailCall)
     Ops.push_back(DAG.getConstant(FPDiff, MVT::i32));
 
-  // Add an implicit use GOT pointer in EBX.
-  if (!IsTailCall && !Is64Bit &&
-      getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
-      Subtarget->isPICStyleGOT())
-    Ops.push_back(DAG.getRegister(X86::EBX, getPointerTy()));
-
   // Add argument registers to the end of the list so that they are known live
   // into the call.
   for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i)
     Ops.push_back(DAG.getRegister(RegsToPass[i].first,
                                   RegsToPass[i].second.getValueType()));
   
+  // Add an implicit use GOT pointer in EBX.
+  if (!IsTailCall && !Is64Bit &&
+      getTargetMachine().getRelocationModel() == Reloc::PIC_ &&
+      Subtarget->isPICStyleGOT())
+    Ops.push_back(DAG.getRegister(X86::EBX, getPointerTy()));
+
+  // Add an implicit use of AL for x86 vararg functions.
+  if (Is64Bit && isVarArg)
+    Ops.push_back(DAG.getRegister(X86::AL, MVT::i8));
+
   if (InFlag.Val)
     Ops.push_back(InFlag);
 
@@ -1776,21 +1769,7 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
 
   // Handle result values, copying them out of physregs into vregs that we
   // return.
-  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);
-  }
+  return SDOperand(LowerCallResult(Chain, InFlag, Op.Val, CC, DAG), Op.ResNo);
 }
 
 
@@ -1860,15 +1839,7 @@ bool X86TargetLowering::IsEligibleForTailCallOptimization(SDOperand Call,
   if (!PerformTailCallOpt)
     return false;
 
-  // Check whether CALL node immediatly preceeds the RET node and whether the
-  // return uses the result of the node or is a void return.
-  unsigned NumOps = Ret.getNumOperands();
-  if ((NumOps == 1 && 
-       (Ret.getOperand(0) == SDOperand(Call.Val,1) ||
-        Ret.getOperand(0) == SDOperand(Call.Val,0))) ||
-      (NumOps > 1 &&
-       Ret.getOperand(0) == SDOperand(Call.Val,Call.Val->getNumValues()-1) &&
-       Ret.getOperand(1) == SDOperand(Call.Val,0))) {
+  if (CheckTailCallReturnConstraints(Call, Ret)) {
     MachineFunction &MF = DAG.getMachineFunction();
     unsigned CallerCC = MF.getFunction()->getCallingConv();
     unsigned CalleeCC = cast<ConstantSDNode>(Call.getOperand(1))->getValue();
@@ -2101,7 +2072,7 @@ bool X86::isPSHUFLWMask(SDNode *N) {
 
 /// isSHUFPMask - Return true if the specified VECTOR_SHUFFLE operand
 /// specifies a shuffle of elements that is suitable for input to SHUFP*.
-static bool isSHUFPMask(const SDOperand *Elems, unsigned NumElems) {
+static bool isSHUFPMask(SDOperandPtr Elems, unsigned NumElems) {
   if (NumElems != 2 && NumElems != 4) return false;
 
   unsigned Half = NumElems / 2;
@@ -2124,7 +2095,7 @@ bool X86::isSHUFPMask(SDNode *N) {
 /// the reverse of what x86 shuffles want. x86 shuffles requires the lower
 /// half elements to come from vector 1 (which would equal the dest.) and
 /// the upper half to come from vector 2.
-static bool isCommutedSHUFP(const SDOperand *Ops, unsigned NumOps) {
+static bool isCommutedSHUFP(SDOperandPtr Ops, unsigned NumOps) {
   if (NumOps != 2 && NumOps != 4) return false;
 
   unsigned Half = NumOps / 2;
@@ -2218,7 +2189,7 @@ bool X86::isMOVHPMask(SDNode *N) {
 
 /// isUNPCKLMask - Return true if the specified VECTOR_SHUFFLE operand
 /// specifies a shuffle of elements that is suitable for input to UNPCKL.
-bool static isUNPCKLMask(const SDOperand *Elts, unsigned NumElts,
+bool static isUNPCKLMask(SDOperandPtr Elts, unsigned NumElts,
                          bool V2IsSplat = false) {
   if (NumElts != 2 && NumElts != 4 && NumElts != 8 && NumElts != 16)
     return false;
@@ -2247,7 +2218,7 @@ bool X86::isUNPCKLMask(SDNode *N, bool V2IsSplat) {
 
 /// isUNPCKHMask - Return true if the specified VECTOR_SHUFFLE operand
 /// specifies a shuffle of elements that is suitable for input to UNPCKH.
-bool static isUNPCKHMask(const SDOperand *Elts, unsigned NumElts,
+bool static isUNPCKHMask(SDOperandPtr Elts, unsigned NumElts,
                          bool V2IsSplat = false) {
   if (NumElts != 2 && NumElts != 4 && NumElts != 8 && NumElts != 16)
     return false;
@@ -2323,7 +2294,7 @@ bool X86::isUNPCKH_v_undef_Mask(SDNode *N) {
 /// isMOVLMask - Return true if the specified VECTOR_SHUFFLE operand
 /// specifies a shuffle of elements that is suitable for input to MOVSS,
 /// MOVSD, and MOVD, i.e. setting the lowest element.
-static bool isMOVLMask(const SDOperand *Elts, unsigned NumElts) {
+static bool isMOVLMask(SDOperandPtr Elts, unsigned NumElts) {
   if (NumElts != 2 && NumElts != 4)
     return false;
 
@@ -2346,7 +2317,7 @@ bool X86::isMOVLMask(SDNode *N) {
 /// isCommutedMOVL - Returns true if the shuffle mask is except the reverse
 /// of what x86 movss want. X86 movs requires the lowest  element to be lowest
 /// element of vector 2 and the other elements to come from vector 1 in order.
-static bool isCommutedMOVL(const SDOperand *Ops, unsigned NumOps,
+static bool isCommutedMOVL(SDOperandPtr Ops, unsigned NumOps,
                            bool V2IsSplat = false,
                            bool V2IsUndef = false) {
   if (NumOps != 2 && NumOps != 4 && NumOps != 8 && NumOps != 16)
@@ -2595,9 +2566,9 @@ static bool isPSHUFHW_PSHUFLWMask(SDNode *N) {
 static SDOperand CommuteVectorShuffle(SDOperand Op, SDOperand &V1,
                                       SDOperand &V2, SDOperand &Mask,
                                       SelectionDAG &DAG) {
-  MVT::ValueType VT = Op.getValueType();
-  MVT::ValueType MaskVT = Mask.getValueType();
-  MVT::ValueType EltVT = MVT::getVectorElementType(MaskVT);
+  MVT VT = Op.getValueType();
+  MVT MaskVT = Mask.getValueType();
+  MVT EltVT = MaskVT.getVectorElementType();
   unsigned NumElems = Mask.getNumOperands();
   SmallVector<SDOperand, 8> MaskVec;
 
@@ -2624,8 +2595,8 @@ static SDOperand CommuteVectorShuffle(SDOperand Op, SDOperand &V1,
 /// the two vector operands have swapped position.
 static
 SDOperand CommuteVectorShuffleMask(SDOperand Mask, SelectionDAG &DAG) {
-  MVT::ValueType MaskVT = Mask.getValueType();
-  MVT::ValueType EltVT = MVT::getVectorElementType(MaskVT);
+  MVT MaskVT = Mask.getValueType();
+  MVT EltVT = MaskVT.getVectorElementType();
   unsigned NumElems = Mask.getNumOperands();
   SmallVector<SDOperand, 8> MaskVec;
   for (unsigned i = 0; i != NumElems; ++i) {
@@ -2663,11 +2634,16 @@ static bool ShouldXformToMOVHLPS(SDNode *Mask) {
 }
 
 /// isScalarLoadToVector - Returns true if the node is a scalar load that
-/// is promoted to a vector.
-static inline bool isScalarLoadToVector(SDNode *N) {
+/// is promoted to a vector. It also returns the LoadSDNode by reference if
+/// required.
+static bool isScalarLoadToVector(SDNode *N, LoadSDNode **LD = NULL) {
   if (N->getOpcode() == ISD::SCALAR_TO_VECTOR) {
     N = N->getOperand(0).Val;
-    return ISD::isNON_EXTLoad(N);
+    if (ISD::isNON_EXTLoad(N)) {
+      if (LD)
+        *LD = cast<LoadSDNode>(N);
+      return true;
+    }
   }
   return false;
 }
@@ -2779,30 +2755,35 @@ static bool isZeroShuffle(SDNode *N) {
 
 /// getZeroVector - Returns a vector of specified type with all zero elements.
 ///
-static SDOperand getZeroVector(MVT::ValueType VT, SelectionDAG &DAG) {
-  assert(MVT::isVector(VT) && "Expected a vector type");
+static SDOperand getZeroVector(MVT VT, bool HasSSE2, SelectionDAG &DAG) {
+  assert(VT.isVector() && "Expected a vector type");
   
   // Always build zero vectors as <4 x i32> or <2 x i32> bitcasted to their dest
   // type.  This ensures they get CSE'd.
-  SDOperand Cst = DAG.getTargetConstant(0, MVT::i32);
   SDOperand Vec;
-  if (MVT::getSizeInBits(VT) == 64)  // MMX
+  if (VT.getSizeInBits() == 64) { // MMX
+    SDOperand Cst = DAG.getTargetConstant(0, MVT::i32);
     Vec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i32, Cst, Cst);
-  else                                              // SSE
+  } else if (HasSSE2) {  // SSE2
+    SDOperand Cst = DAG.getTargetConstant(0, MVT::i32);
     Vec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Cst, Cst, Cst, Cst);
+  } else { // SSE1
+    SDOperand Cst = DAG.getTargetConstantFP(+0.0, MVT::f32);
+    Vec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4f32, Cst, Cst, Cst, Cst);
+  }
   return DAG.getNode(ISD::BIT_CONVERT, VT, Vec);
 }
 
 /// getOnesVector - Returns a vector of specified type with all bits set.
 ///
-static SDOperand getOnesVector(MVT::ValueType VT, SelectionDAG &DAG) {
-  assert(MVT::isVector(VT) && "Expected a vector type");
+static SDOperand getOnesVector(MVT VT, SelectionDAG &DAG) {
+  assert(VT.isVector() && "Expected a vector type");
   
   // Always build ones vectors as <4 x i32> or <2 x i32> bitcasted to their dest
   // type.  This ensures they get CSE'd.
   SDOperand Cst = DAG.getTargetConstant(~0U, MVT::i32);
   SDOperand Vec;
-  if (MVT::getSizeInBits(VT) == 64)  // MMX
+  if (VT.getSizeInBits() == 64)  // MMX
     Vec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i32, Cst, Cst);
   else                                              // SSE
     Vec = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Cst, Cst, Cst, Cst);
@@ -2839,8 +2820,8 @@ static SDOperand NormalizeMask(SDOperand Mask, SelectionDAG &DAG) {
 /// getMOVLMask - Returns a vector_shuffle mask for an movs{s|d}, movd
 /// operation of specified width.
 static SDOperand getMOVLMask(unsigned NumElems, SelectionDAG &DAG) {
-  MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
-  MVT::ValueType BaseVT = MVT::getVectorElementType(MaskVT);
+  MVT MaskVT = MVT::getIntVectorWithNumElements(NumElems);
+  MVT BaseVT = MaskVT.getVectorElementType();
 
   SmallVector<SDOperand, 8> MaskVec;
   MaskVec.push_back(DAG.getConstant(NumElems, BaseVT));
@@ -2852,8 +2833,8 @@ static SDOperand getMOVLMask(unsigned NumElems, SelectionDAG &DAG) {
 /// getUnpacklMask - Returns a vector_shuffle mask for an unpackl operation
 /// of specified width.
 static SDOperand getUnpacklMask(unsigned NumElems, SelectionDAG &DAG) {
-  MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
-  MVT::ValueType BaseVT = MVT::getVectorElementType(MaskVT);
+  MVT MaskVT = MVT::getIntVectorWithNumElements(NumElems);
+  MVT BaseVT = MaskVT.getVectorElementType();
   SmallVector<SDOperand, 8> MaskVec;
   for (unsigned i = 0, e = NumElems/2; i != e; ++i) {
     MaskVec.push_back(DAG.getConstant(i,            BaseVT));
@@ -2865,8 +2846,8 @@ static SDOperand getUnpacklMask(unsigned NumElems, SelectionDAG &DAG) {
 /// getUnpackhMask - Returns a vector_shuffle mask for an unpackh operation
 /// of specified width.
 static SDOperand getUnpackhMask(unsigned NumElems, SelectionDAG &DAG) {
-  MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
-  MVT::ValueType BaseVT = MVT::getVectorElementType(MaskVT);
+  MVT MaskVT = MVT::getIntVectorWithNumElements(NumElems);
+  MVT BaseVT = MaskVT.getVectorElementType();
   unsigned Half = NumElems/2;
   SmallVector<SDOperand, 8> MaskVec;
   for (unsigned i = 0; i != Half; ++i) {
@@ -2876,23 +2857,43 @@ static SDOperand getUnpackhMask(unsigned NumElems, SelectionDAG &DAG) {
   return DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], MaskVec.size());
 }
 
-/// PromoteSplat - Promote a splat of v8i16 or v16i8 to v4i32.
-///
-static SDOperand PromoteSplat(SDOperand Op, SelectionDAG &DAG) {
+/// getSwapEltZeroMask - Returns a vector_shuffle mask for a shuffle that swaps
+/// element #0 of a vector with the specified index, leaving the rest of the
+/// elements in place.
+static SDOperand getSwapEltZeroMask(unsigned NumElems, unsigned DestElt,
+                                   SelectionDAG &DAG) {
+  MVT MaskVT = MVT::getIntVectorWithNumElements(NumElems);
+  MVT BaseVT = MaskVT.getVectorElementType();
+  SmallVector<SDOperand, 8> MaskVec;
+  // Element #0 of the result gets the elt we are replacing.
+  MaskVec.push_back(DAG.getConstant(DestElt, BaseVT));
+  for (unsigned i = 1; i != NumElems; ++i)
+    MaskVec.push_back(DAG.getConstant(i == DestElt ? 0 : i, BaseVT));
+  return DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], MaskVec.size());
+}
+
+/// PromoteSplat - Promote a splat of v4f32, v8i16 or v16i8 to v4i32.
+static SDOperand PromoteSplat(SDOperand Op, SelectionDAG &DAG, bool HasSSE2) {
+  MVT PVT = HasSSE2 ? MVT::v4i32 : MVT::v4f32;
+  MVT VT = Op.getValueType();
+  if (PVT == VT)
+    return Op;
   SDOperand V1 = Op.getOperand(0);
   SDOperand Mask = Op.getOperand(2);
-  MVT::ValueType VT = Op.getValueType();
   unsigned NumElems = Mask.getNumOperands();
-  Mask = getUnpacklMask(NumElems, DAG);
-  while (NumElems != 4) {
-    V1 = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V1, Mask);
-    NumElems >>= 1;
+  // Special handling of v4f32 -> v4i32.
+  if (VT != MVT::v4f32) {
+    Mask = getUnpacklMask(NumElems, DAG);
+    while (NumElems > 4) {
+      V1 = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V1, Mask);
+      NumElems >>= 1;
+    }
+    Mask = getZeroVector(MVT::v4i32, true, DAG);
   }
-  V1 = DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, V1);
 
-  Mask = getZeroVector(MVT::v4i32, DAG);
-  SDOperand Shuffle = DAG.getNode(ISD::VECTOR_SHUFFLE, MVT::v4i32, V1,
-                                  DAG.getNode(ISD::UNDEF, MVT::v4i32), Mask);
+  V1 = DAG.getNode(ISD::BIT_CONVERT, PVT, V1);
+  SDOperand Shuffle = DAG.getNode(ISD::VECTOR_SHUFFLE, PVT, V1,
+                                  DAG.getNode(ISD::UNDEF, PVT), Mask);
   return DAG.getNode(ISD::BIT_CONVERT, VT, Shuffle);
 }
 
@@ -2900,12 +2901,15 @@ static SDOperand PromoteSplat(SDOperand Op, SelectionDAG &DAG) {
 /// vector of zero or undef vector.  This produces a shuffle where the low
 /// element of V2 is swizzled into the zero/undef vector, landing at element
 /// Idx.  This produces a shuffle mask like 4,1,2,3 (idx=0) or  0,1,2,4 (idx=3).
-static SDOperand getShuffleVectorZeroOrUndef(SDOperand V2, MVT::ValueType VT,
-                                             unsigned NumElems, unsigned Idx,
-                                             bool isZero, SelectionDAG &DAG) {
-  SDOperand V1 = isZero ? getZeroVector(VT, DAG) : DAG.getNode(ISD::UNDEF, VT);
-  MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
-  MVT::ValueType EVT = MVT::getVectorElementType(MaskVT);
+static SDOperand getShuffleVectorZeroOrUndef(SDOperand V2, unsigned Idx,
+                                             bool isZero, bool HasSSE2,
+                                             SelectionDAG &DAG) {
+  MVT VT = V2.getValueType();
+  SDOperand V1 = isZero
+    ? getZeroVector(VT, HasSSE2, DAG) : DAG.getNode(ISD::UNDEF, VT);
+  unsigned NumElems = V2.getValueType().getVectorNumElements();
+  MVT MaskVT = MVT::getIntVectorWithNumElements(NumElems);
+  MVT EVT = MaskVT.getVectorElementType();
   SmallVector<SDOperand, 16> MaskVec;
   for (unsigned i = 0; i != NumElems; ++i)
     if (i == Idx)  // If this is the insertion idx, put the low elt of V2 here.
@@ -2917,6 +2921,70 @@ static SDOperand getShuffleVectorZeroOrUndef(SDOperand V2, MVT::ValueType VT,
   return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1, V2, Mask);
 }
 
+/// getNumOfConsecutiveZeros - Return the number of elements in a result of
+/// a shuffle that is zero.
+static
+unsigned getNumOfConsecutiveZeros(SDOperand Op, SDOperand Mask,
+                                  unsigned NumElems, bool Low,
+                                  SelectionDAG &DAG) {
+  unsigned NumZeros = 0;
+  for (unsigned i = 0; i < NumElems; ++i) {
+    SDOperand Idx = Mask.getOperand(Low ? i : NumElems-i-1);
+    if (Idx.getOpcode() == ISD::UNDEF) {
+      ++NumZeros;
+      continue;
+    }
+    unsigned Index = cast<ConstantSDNode>(Idx)->getValue();
+    SDOperand Elt = DAG.getShuffleScalarElt(Op.Val, Index);
+    if (Elt.Val && isZeroNode(Elt))
+      ++NumZeros;
+    else
+      break;
+  }
+  return NumZeros;
+}
+
+/// isVectorShift - Returns true if the shuffle can be implemented as a
+/// logical left or right shift of a vector.
+static bool isVectorShift(SDOperand Op, SDOperand Mask, SelectionDAG &DAG,
+                          bool &isLeft, SDOperand &ShVal, unsigned &ShAmt) {
+  unsigned NumElems = Mask.getNumOperands();
+
+  isLeft = true;
+  unsigned NumZeros= getNumOfConsecutiveZeros(Op, Mask, NumElems, true, DAG);
+  if (!NumZeros) {
+    isLeft = false;
+    NumZeros = getNumOfConsecutiveZeros(Op, Mask, NumElems, false, DAG);
+    if (!NumZeros)
+      return false;
+  }
+
+  bool SeenV1 = false;
+  bool SeenV2 = false;
+  for (unsigned i = NumZeros; i < NumElems; ++i) {
+    unsigned Val = isLeft ? (i - NumZeros) : i;
+    SDOperand Idx = Mask.getOperand(isLeft ? i : (i - NumZeros));
+    if (Idx.getOpcode() == ISD::UNDEF)
+      continue;
+    unsigned Index = cast<ConstantSDNode>(Idx)->getValue();
+    if (Index < NumElems)
+      SeenV1 = true;
+    else {
+      Index -= NumElems;
+      SeenV2 = true;
+    }
+    if (Index != Val)
+      return false;
+  }
+  if (SeenV1 && SeenV2)
+    return false;
+
+  ShVal = SeenV1 ? Op.getOperand(0) : Op.getOperand(1);
+  ShAmt = NumZeros;
+  return true;
+}
+
+
 /// LowerBuildVectorv16i8 - Custom lower build_vector of v16i8.
 ///
 static SDOperand LowerBuildVectorv16i8(SDOperand Op, unsigned NonZeros,
@@ -2931,7 +2999,7 @@ static SDOperand LowerBuildVectorv16i8(SDOperand Op, unsigned NonZeros,
     bool ThisIsNonZero = (NonZeros & (1 << i)) != 0;
     if (ThisIsNonZero && First) {
       if (NumZero)
-        V = getZeroVector(MVT::v8i16, DAG);
+        V = getZeroVector(MVT::v8i16, true, DAG);
       else
         V = DAG.getNode(ISD::UNDEF, MVT::v8i16);
       First = false;
@@ -2976,7 +3044,7 @@ static SDOperand LowerBuildVectorv8i16(SDOperand Op, unsigned NonZeros,
     if (isNonZero) {
       if (First) {
         if (NumZero)
-          V = getZeroVector(MVT::v8i16, DAG);
+          V = getZeroVector(MVT::v8i16, true, DAG);
         else
           V = DAG.getNode(ISD::UNDEF, MVT::v8i16);
         First = false;
@@ -2989,6 +3057,20 @@ static SDOperand LowerBuildVectorv8i16(SDOperand Op, unsigned NonZeros,
   return V;
 }
 
+/// getVShift - Return a vector logical shift node.
+///
+static SDOperand getVShift(bool isLeft, MVT VT, SDOperand SrcOp,
+                           unsigned NumBits, SelectionDAG &DAG,
+                           const TargetLowering &TLI) {
+  bool isMMX = VT.getSizeInBits() == 64;
+  MVT ShVT = isMMX ? MVT::v1i64 : MVT::v2i64;
+  unsigned Opc = isLeft ? X86ISD::VSHL : X86ISD::VSRL;
+  SrcOp = DAG.getNode(ISD::BIT_CONVERT, ShVT, SrcOp);
+  return DAG.getNode(ISD::BIT_CONVERT, VT,
+                     DAG.getNode(Opc, ShVT, SrcOp,
+                              DAG.getConstant(NumBits, TLI.getShiftAmountTy())));
+}
+
 SDOperand
 X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
   // All zero's are handled with pxor, all one's are handled with pcmpeqd.
@@ -3001,18 +3083,18 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
 
     if (ISD::isBuildVectorAllOnes(Op.Val))
       return getOnesVector(Op.getValueType(), DAG);
-    return getZeroVector(Op.getValueType(), DAG);
+    return getZeroVector(Op.getValueType(), Subtarget->hasSSE2(), DAG);
   }
 
-  MVT::ValueType VT = Op.getValueType();
-  MVT::ValueType EVT = MVT::getVectorElementType(VT);
-  unsigned EVTBits = MVT::getSizeInBits(EVT);
+  MVT VT = Op.getValueType();
+  MVT EVT = VT.getVectorElementType();
+  unsigned EVTBits = EVT.getSizeInBits();
 
   unsigned NumElems = Op.getNumOperands();
   unsigned NumZero  = 0;
   unsigned NumNonZero = 0;
   unsigned NonZeros = 0;
-  bool HasNonImms = false;
+  bool IsAllConstants = true;
   SmallSet<SDOperand, 8> Values;
   for (unsigned i = 0; i < NumElems; ++i) {
     SDOperand Elt = Op.getOperand(i);
@@ -3021,7 +3103,7 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
     Values.insert(Elt);
     if (Elt.getOpcode() != ISD::Constant &&
         Elt.getOpcode() != ISD::ConstantFP)
-      HasNonImms = true;
+      IsAllConstants = false;
     if (isZeroNode(Elt))
       NumZero++;
     else {
@@ -3035,28 +3117,82 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
     return DAG.getNode(ISD::UNDEF, VT);
   }
 
-  // Splat is obviously ok. Let legalizer expand it to a shuffle.
-  if (Values.size() == 1)
-    return SDOperand();
-
-  // Special case for single non-zero element.
+  // Special case for single non-zero, non-undef, element.
   if (NumNonZero == 1 && NumElems <= 4) {
     unsigned Idx = CountTrailingZeros_32(NonZeros);
     SDOperand Item = Op.getOperand(Idx);
-    Item = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Item);
-    if (Idx == 0)
+    
+    // If this is an insertion of an i64 value on x86-32, and if the top bits of
+    // the value are obviously zero, truncate the value to i32 and do the
+    // insertion that way.  Only do this if the value is non-constant or if the
+    // value is a constant being inserted into element 0.  It is cheaper to do
+    // a constant pool load than it is to do a movd + shuffle.
+    if (EVT == MVT::i64 && !Subtarget->is64Bit() &&
+        (!IsAllConstants || Idx == 0)) {
+      if (DAG.MaskedValueIsZero(Item, APInt::getBitsSet(64, 32, 64))) {
+        // Handle MMX and SSE both.
+        MVT VecVT = VT == MVT::v2i64 ? MVT::v4i32 : MVT::v2i32;
+        unsigned VecElts = VT == MVT::v2i64 ? 4 : 2;
+        
+        // Truncate the value (which may itself be a constant) to i32, and
+        // convert it to a vector with movd (S2V+shuffle to zero extend).
+        Item = DAG.getNode(ISD::TRUNCATE, MVT::i32, Item);
+        Item = DAG.getNode(ISD::SCALAR_TO_VECTOR, VecVT, Item);
+        Item = getShuffleVectorZeroOrUndef(Item, 0, true,
+                                           Subtarget->hasSSE2(), DAG);
+        
+        // Now we have our 32-bit value zero extended in the low element of
+        // a vector.  If Idx != 0, swizzle it into place.
+        if (Idx != 0) {
+          SDOperand Ops[] = { 
+            Item, DAG.getNode(ISD::UNDEF, Item.getValueType()),
+            getSwapEltZeroMask(VecElts, Idx, DAG)
+          };
+          Item = DAG.getNode(ISD::VECTOR_SHUFFLE, VecVT, Ops, 3);
+        }
+        return DAG.getNode(ISD::BIT_CONVERT, Op.getValueType(), Item);
+      }
+    }
+    
+    // If we have a constant or non-constant insertion into the low element of
+    // a vector, we can do this with SCALAR_TO_VECTOR + shuffle of zero into
+    // the rest of the elements.  This will be matched as movd/movq/movss/movsd
+    // depending on what the source datatype is.  Because we can only get here
+    // when NumElems <= 4, this only needs to handle i32/f32/i64/f64.
+    if (Idx == 0 &&
+        // Don't do this for i64 values on x86-32.
+        (EVT != MVT::i64 || Subtarget->is64Bit())) {
+      Item = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Item);
       // Turn it into a MOVL (i.e. movss, movsd, or movd) to a zero vector.
-      return getShuffleVectorZeroOrUndef(Item, VT, NumElems, Idx,
-                                         NumZero > 0, DAG);
-    else if (!HasNonImms) // Otherwise, it's better to do a constpool load.
+      return getShuffleVectorZeroOrUndef(Item, 0, NumZero > 0,
+                                         Subtarget->hasSSE2(), DAG);
+    }
+
+    // Is it a vector logical left shift?
+    if (NumElems == 2 && Idx == 1 &&
+        isZeroNode(Op.getOperand(0)) && !isZeroNode(Op.getOperand(1))) {
+      unsigned NumBits = VT.getSizeInBits();
+      return getVShift(true, VT,
+                       DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Op.getOperand(1)),
+                       NumBits/2, DAG, *this);
+    }
+    
+    if (IsAllConstants) // Otherwise, it's better to do a constpool load.
       return SDOperand();
 
+    // Otherwise, if this is a vector with i32 or f32 elements, and the element
+    // is a non-constant being inserted into an element other than the low one,
+    // we can't use a constant pool load.  Instead, use SCALAR_TO_VECTOR (aka
+    // movd/movss) to move this into the low element, then shuffle it into
+    // place.
     if (EVTBits == 32) {
+      Item = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Item);
+      
       // Turn it into a shuffle of zero and zero-extended scalar to vector.
-      Item = getShuffleVectorZeroOrUndef(Item, VT, NumElems, 0, NumZero > 0,
-                                         DAG);
-      MVT::ValueType MaskVT  = MVT::getIntVectorWithNumElements(NumElems);
-      MVT::ValueType MaskEVT = MVT::getVectorElementType(MaskVT);
+      Item = getShuffleVectorZeroOrUndef(Item, 0, NumZero > 0,
+                                         Subtarget->hasSSE2(), DAG);
+      MVT MaskVT  = MVT::getIntVectorWithNumElements(NumElems);
+      MVT MaskEVT = MaskVT.getVectorElementType();
       SmallVector<SDOperand, 8> MaskVec;
       for (unsigned i = 0; i < NumElems; i++)
         MaskVec.push_back(DAG.getConstant((i == Idx) ? 0 : 1, MaskEVT));
@@ -3067,14 +3203,27 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
     }
   }
 
+  // Splat is obviously ok. Let legalizer expand it to a shuffle.
+  if (Values.size() == 1)
+    return SDOperand();
+  
   // A vector full of immediates; various special cases are already
   // handled, so this is best done with a single constant-pool load.
-  if (!HasNonImms)
+  if (IsAllConstants)
     return SDOperand();
 
   // Let legalizer expand 2-wide build_vectors.
-  if (EVTBits == 64)
+  if (EVTBits == 64) {
+    if (NumNonZero == 1) {
+      // One half is zero or undef.
+      unsigned Idx = CountTrailingZeros_32(NonZeros);
+      SDOperand V2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT,
+                                 Op.getOperand(Idx));
+      return getShuffleVectorZeroOrUndef(V2, Idx, true,
+                                         Subtarget->hasSSE2(), DAG);
+    }
     return SDOperand();
+  }
 
   // If element VT is < 32 bits, convert it to inserts into a zero vector.
   if (EVTBits == 8 && NumElems == 16) {
@@ -3096,7 +3245,7 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
     for (unsigned i = 0; i < 4; ++i) {
       bool isZero = !(NonZeros & (1 << i));
       if (isZero)
-        V[i] = getZeroVector(VT, DAG);
+        V[i] = getZeroVector(VT, Subtarget->hasSSE2(), DAG);
       else
         V[i] = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Op.getOperand(i));
     }
@@ -3122,15 +3271,8 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
       }
     }
 
-    // Take advantage of the fact GR32 to VR128 scalar_to_vector (i.e. movd)
-    // clears the upper bits.
-    // FIXME: we can do the same for v4f32 case when we know both parts of
-    // the lower half come from scalar_to_vector (loadf32). We should do
-    // that in post legalizer dag combiner with target specific hooks.
-    if (MVT::isInteger(EVT) && (NonZeros & (0x3 << 2)) == 0)
-      return V[0];
-    MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
-    MVT::ValueType EVT = MVT::getVectorElementType(MaskVT);
+    MVT MaskVT = MVT::getIntVectorWithNumElements(NumElems);
+    MVT EVT = MaskVT.getVectorElementType();
     SmallVector<SDOperand, 8> MaskVec;
     bool Reverse = (NonZeros & 0x3) == 2;
     for (unsigned i = 0; i < 2; ++i)
@@ -3176,9 +3318,9 @@ SDOperand LowerVECTOR_SHUFFLEv8i16(SDOperand V1, SDOperand V2,
                                    SDOperand PermMask, SelectionDAG &DAG,
                                    TargetLowering &TLI) {
   SDOperand NewV;
-  MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(8);
-  MVT::ValueType MaskEVT = MVT::getVectorElementType(MaskVT);
-  MVT::ValueType PtrVT = TLI.getPointerTy();
+  MVT MaskVT = MVT::getIntVectorWithNumElements(8);
+  MVT MaskEVT = MaskVT.getVectorElementType();
+  MVT PtrVT = TLI.getPointerTy();
   SmallVector<SDOperand, 8> MaskElts(PermMask.Val->op_begin(),
                                      PermMask.Val->op_end());
 
@@ -3302,8 +3444,6 @@ SDOperand LowerVECTOR_SHUFFLEv8i16(SDOperand V1, SDOperand V2,
         continue;
       SDOperand Elt = MaskElts[i];
       unsigned EltIdx = cast<ConstantSDNode>(Elt)->getValue();
-      if (EltIdx == i)
-        continue;
       SDOperand ExtOp = (EltIdx < 8)
         ? DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, V1,
                       DAG.getConstant(EltIdx, PtrVT))
@@ -3418,23 +3558,23 @@ SDOperand LowerVECTOR_SHUFFLEv8i16(SDOperand V1, SDOperand V2,
 /// vector_shuffle <>, <>, < 3, 4, | 10, 11, | 0, 1, | 14, 15>
 static
 SDOperand RewriteAsNarrowerShuffle(SDOperand V1, SDOperand V2,
-                                MVT::ValueType VT,
+                                MVT VT,
                                 SDOperand PermMask, SelectionDAG &DAG,
                                 TargetLowering &TLI) {
   unsigned NumElems = PermMask.getNumOperands();
   unsigned NewWidth = (NumElems == 4) ? 2 : 4;
-  MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NewWidth);
-  MVT::ValueType NewVT = MaskVT;
-  switch (VT) {
+  MVT MaskVT = MVT::getIntVectorWithNumElements(NewWidth);
+  MVT NewVT = MaskVT;
+  switch (VT.getSimpleVT()) {
+  default: assert(false && "Unexpected!");
   case MVT::v4f32: NewVT = MVT::v2f64; break;
   case MVT::v4i32: NewVT = MVT::v2i64; break;
   case MVT::v8i16: NewVT = MVT::v4i32; break;
   case MVT::v16i8: NewVT = MVT::v4i32; break;
-  default: assert(false && "Unexpected!");
   }
 
   if (NewWidth == 2) {
-    if (MVT::isInteger(VT))
+    if (VT.isInteger())
       NewVT = MVT::v2i64;
     else
       NewVT = MVT::v2f64;
@@ -3466,13 +3606,46 @@ SDOperand RewriteAsNarrowerShuffle(SDOperand V1, SDOperand V2,
                                  &MaskVec[0], MaskVec.size()));
 }
 
+/// getVZextMovL - Return a zero-extending vector move low node.
+///
+static SDOperand getVZextMovL(MVT VT, MVT OpVT,
+                              SDOperand SrcOp, SelectionDAG &DAG,
+                              const X86Subtarget *Subtarget) {
+  if (VT == MVT::v2f64 || VT == MVT::v4f32) {
+    LoadSDNode *LD = NULL;
+    if (!isScalarLoadToVector(SrcOp.Val, &LD))
+      LD = dyn_cast<LoadSDNode>(SrcOp);
+    if (!LD) {
+      // movssrr and movsdrr do not clear top bits. Try to use movd, movq
+      // instead.
+      MVT EVT = (OpVT == MVT::v2f64) ? MVT::i64 : MVT::i32;
+      if ((EVT != MVT::i64 || Subtarget->is64Bit()) &&
+          SrcOp.getOpcode() == ISD::SCALAR_TO_VECTOR &&
+          SrcOp.getOperand(0).getOpcode() == ISD::BIT_CONVERT &&
+          SrcOp.getOperand(0).getOperand(0).getValueType() == EVT) {
+        // PR2108
+        OpVT = (OpVT == MVT::v2f64) ? MVT::v2i64 : MVT::v4i32;
+        return DAG.getNode(ISD::BIT_CONVERT, VT,
+                           DAG.getNode(X86ISD::VZEXT_MOVL, OpVT,
+                                       DAG.getNode(ISD::SCALAR_TO_VECTOR, OpVT,
+                                                   SrcOp.getOperand(0).getOperand(0))));
+      }
+    }
+  }
+
+  return DAG.getNode(ISD::BIT_CONVERT, VT,
+                     DAG.getNode(X86ISD::VZEXT_MOVL, OpVT,
+                                 DAG.getNode(ISD::BIT_CONVERT, OpVT, SrcOp)));
+}
+
 SDOperand
 X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
   SDOperand V1 = Op.getOperand(0);
   SDOperand V2 = Op.getOperand(1);
   SDOperand PermMask = Op.getOperand(2);
-  MVT::ValueType VT = Op.getValueType();
+  MVT VT = Op.getValueType();
   unsigned NumElems = PermMask.getNumOperands();
+  bool isMMX = VT.getSizeInBits() == 64;
   bool V1IsUndef = V1.getOpcode() == ISD::UNDEF;
   bool V2IsUndef = V2.getOpcode() == ISD::UNDEF;
   bool V1IsSplat = false;
@@ -3482,7 +3655,7 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
     return DAG.getNode(ISD::UNDEF, VT);
 
   if (isZeroShuffle(Op.Val))
-    return getZeroVector(VT, DAG);
+    return getZeroVector(VT, Subtarget->hasSSE2(), DAG);
 
   if (isIdentityMask(PermMask.Val))
     return V1;
@@ -3490,9 +3663,9 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
     return V2;
 
   if (isSplatMask(PermMask.Val)) {
-    if (NumElems <= 4) return Op;
-    // Promote it to a v4i32 splat.
-    return PromoteSplat(Op, DAG);
+    if (isMMX || NumElems < 4) return Op;
+    // Promote it to a v4{if}32 splat.
+    return PromoteSplat(Op, DAG, Subtarget->hasSSE2());
   }
 
   // If the shuffle can be profitably rewritten as a narrower shuffle, then
@@ -3505,27 +3678,46 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
     // FIXME: Figure out a cleaner way to do this.
     // Try to make use of movq to zero out the top part.
     if (ISD::isBuildVectorAllZeros(V2.Val)) {
-      SDOperand NewOp = RewriteAsNarrowerShuffle(V1, V2, VT, PermMask, DAG, *this);
+      SDOperand NewOp = RewriteAsNarrowerShuffle(V1, V2, VT, PermMask,
+                                                 DAG, *this);
       if (NewOp.Val) {
         SDOperand NewV1 = NewOp.getOperand(0);
         SDOperand NewV2 = NewOp.getOperand(1);
         SDOperand NewMask = NewOp.getOperand(2);
         if (isCommutedMOVL(NewMask.Val, true, false)) {
           NewOp = CommuteVectorShuffle(NewOp, NewV1, NewV2, NewMask, DAG);
-          NewOp = DAG.getNode(ISD::VECTOR_SHUFFLE, NewOp.getValueType(),
-                              NewV1, NewV2, getMOVLMask(2, DAG));
-          return DAG.getNode(ISD::BIT_CONVERT, VT, LowerVECTOR_SHUFFLE(NewOp, DAG));
+          return getVZextMovL(VT, NewOp.getValueType(), NewV2, DAG, Subtarget);
         }
       }
     } else if (ISD::isBuildVectorAllZeros(V1.Val)) {
-      SDOperand NewOp= RewriteAsNarrowerShuffle(V1, V2, VT, PermMask, DAG, *this);
+      SDOperand NewOp= RewriteAsNarrowerShuffle(V1, V2, VT, PermMask,
+                                                DAG, *this);
       if (NewOp.Val && X86::isMOVLMask(NewOp.getOperand(2).Val))
-        return DAG.getNode(ISD::BIT_CONVERT, VT, LowerVECTOR_SHUFFLE(NewOp, DAG));
+        return getVZextMovL(VT, NewOp.getValueType(), NewOp.getOperand(1),
+                             DAG, Subtarget);
     }
   }
 
-  if (X86::isMOVLMask(PermMask.Val))
-    return (V1IsUndef) ? V2 : Op;
+  // Check if this can be converted into a logical shift.
+  bool isLeft = false;
+  unsigned ShAmt = 0;
+  SDOperand ShVal;
+  bool isShift = isVectorShift(Op, PermMask, DAG, isLeft, ShVal, ShAmt);
+  if (isShift && ShVal.hasOneUse()) {
+    // If the shifted value has multiple uses, it may be cheaper to use 
+    // v_set0 + movlhps or movhlps, etc.
+    MVT EVT = VT.getVectorElementType();
+    ShAmt *= EVT.getSizeInBits();
+    return getVShift(isLeft, VT, ShVal, ShAmt, DAG, *this);
+  }
+
+  if (X86::isMOVLMask(PermMask.Val)) {
+    if (V1IsUndef)
+      return V2;
+    if (ISD::isBuildVectorAllZeros(V1.Val))
+      return getVZextMovL(VT, VT, V2, DAG, Subtarget);
+    return Op;
+  }
 
   if (X86::isMOVSHDUPMask(PermMask.Val) ||
       X86::isMOVSLDUPMask(PermMask.Val) ||
@@ -3538,6 +3730,13 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
       ShouldXformToMOVLP(V1.Val, V2.Val, PermMask.Val))
     return CommuteVectorShuffle(Op, V1, V2, PermMask, DAG);
 
+  if (isShift) {
+    // No better options. Use a vshl / vsrl.
+    MVT EVT = VT.getVectorElementType();
+    ShAmt *= EVT.getSizeInBits();
+    return getVShift(isLeft, VT, ShVal, ShAmt, DAG, *this);
+  }
+
   bool Commuted = false;
   // FIXME: This should also accept a bitcast of a splat?  Be careful, not
   // 1,1,1,1 -> v8i16 though.
@@ -3603,35 +3802,39 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
       return Op;
   }
 
-  // If VT is integer, try PSHUF* first, then SHUFP*.
-  if (MVT::isInteger(VT)) {
-    // MMX doesn't have PSHUFD; it does have PSHUFW. While it's theoretically
-    // possible to shuffle a v2i32 using PSHUFW, that's not yet implemented.
-    if (((MVT::getSizeInBits(VT) != 64 || NumElems == 4) &&
-         X86::isPSHUFDMask(PermMask.Val)) ||
-        X86::isPSHUFHWMask(PermMask.Val) ||
-        X86::isPSHUFLWMask(PermMask.Val)) {
-      if (V2.getOpcode() != ISD::UNDEF)
-        return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1,
-                           DAG.getNode(ISD::UNDEF, V1.getValueType()),PermMask);
+  // Try PSHUF* first, then SHUFP*.
+  // MMX doesn't have PSHUFD but it does have PSHUFW. While it's theoretically
+  // possible to shuffle a v2i32 using PSHUFW, that's not yet implemented.
+  if (isMMX && NumElems == 4 && X86::isPSHUFDMask(PermMask.Val)) {
+    if (V2.getOpcode() != ISD::UNDEF)
+      return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1,
+                         DAG.getNode(ISD::UNDEF, VT), PermMask);
+    return Op;
+  }
+
+  if (!isMMX) {
+    if (Subtarget->hasSSE2() &&
+        (X86::isPSHUFDMask(PermMask.Val) ||
+         X86::isPSHUFHWMask(PermMask.Val) ||
+         X86::isPSHUFLWMask(PermMask.Val))) {
+      MVT RVT = VT;
+      if (VT == MVT::v4f32) {
+        RVT = MVT::v4i32;
+        Op = DAG.getNode(ISD::VECTOR_SHUFFLE, RVT,
+                         DAG.getNode(ISD::BIT_CONVERT, RVT, V1),
+                         DAG.getNode(ISD::UNDEF, RVT), PermMask);
+      } else if (V2.getOpcode() != ISD::UNDEF)
+        Op = DAG.getNode(ISD::VECTOR_SHUFFLE, RVT, V1,
+                         DAG.getNode(ISD::UNDEF, RVT), PermMask);
+      if (RVT != VT)
+        Op = DAG.getNode(ISD::BIT_CONVERT, VT, Op);
       return Op;
     }
 
-    if (X86::isSHUFPMask(PermMask.Val) &&
-        MVT::getSizeInBits(VT) != 64)    // Don't do this for MMX.
+    // Binary or unary shufps.
+    if (X86::isSHUFPMask(PermMask.Val) ||
+        (V2.getOpcode() == ISD::UNDEF && X86::isPSHUFDMask(PermMask.Val)))
       return Op;
-  } else {
-    // Floating point cases in the other order.
-    if (X86::isSHUFPMask(PermMask.Val))
-      return Op;
-    if (X86::isPSHUFDMask(PermMask.Val) ||
-        X86::isPSHUFHWMask(PermMask.Val) ||
-        X86::isPSHUFLWMask(PermMask.Val)) {
-      if (V2.getOpcode() != ISD::UNDEF)
-        return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V1,
-                           DAG.getNode(ISD::UNDEF, V1.getValueType()),PermMask);
-      return Op;
-    }
   }
 
   // Handle v8i16 specifically since SSE can do byte extraction and insertion.
@@ -3642,10 +3845,10 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
   }
 
   // Handle all 4 wide cases with a number of shuffles.
-  if (NumElems == 4 && MVT::getSizeInBits(VT) != 64) {
+  if (NumElems == 4 && !isMMX) {
     // Don't do this for MMX.
-    MVT::ValueType MaskVT = PermMask.getValueType();
-    MVT::ValueType MaskEVT = MVT::getVectorElementType(MaskVT);
+    MVT MaskVT = PermMask.getValueType();
+    MVT MaskEVT = MaskVT.getVectorElementType();
     SmallVector<std::pair<int, int>, 8> Locs;
     Locs.reserve(NumElems);
     SmallVector<SDOperand, 8> Mask1(NumElems,
@@ -3752,19 +3955,34 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
 SDOperand
 X86TargetLowering::LowerEXTRACT_VECTOR_ELT_SSE4(SDOperand Op,
                                                 SelectionDAG &DAG) {
-  MVT::ValueType VT = Op.getValueType();
-  if (MVT::getSizeInBits(VT) == 8) {
+  MVT VT = Op.getValueType();
+  if (VT.getSizeInBits() == 8) {
     SDOperand Extract = DAG.getNode(X86ISD::PEXTRB, MVT::i32,
                                     Op.getOperand(0), Op.getOperand(1));
     SDOperand Assert  = DAG.getNode(ISD::AssertZext, MVT::i32, Extract,
                                     DAG.getValueType(VT));
     return DAG.getNode(ISD::TRUNCATE, VT, Assert);
-  } else if (MVT::getSizeInBits(VT) == 16) {
+  } else if (VT.getSizeInBits() == 16) {
     SDOperand Extract = DAG.getNode(X86ISD::PEXTRW, MVT::i32,
                                     Op.getOperand(0), Op.getOperand(1));
     SDOperand Assert  = DAG.getNode(ISD::AssertZext, MVT::i32, Extract,
                                     DAG.getValueType(VT));
     return DAG.getNode(ISD::TRUNCATE, VT, Assert);
+  } else if (VT == MVT::f32) {
+    // EXTRACTPS outputs to a GPR32 register which will require a movd to copy
+    // the result back to FR32 register. It's only worth matching if the
+    // result has a single use which is a store or a bitcast to i32.
+    if (!Op.hasOneUse())
+      return SDOperand();
+    SDNode *User = Op.Val->use_begin()->getUser();
+    if (User->getOpcode() != ISD::STORE &&
+        (User->getOpcode() != ISD::BIT_CONVERT ||
+         User->getValueType(0) != MVT::i32))
+      return SDOperand();
+    SDOperand Extract = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32,
+                    DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, Op.getOperand(0)),
+                                    Op.getOperand(1));
+    return DAG.getNode(ISD::BIT_CONVERT, MVT::f32, Extract);
   }
   return SDOperand();
 }
@@ -3775,12 +3993,15 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
   if (!isa<ConstantSDNode>(Op.getOperand(1)))
     return SDOperand();
 
-  if (Subtarget->hasSSE41())
-    return LowerEXTRACT_VECTOR_ELT_SSE4(Op, DAG);
+  if (Subtarget->hasSSE41()) {
+    SDOperand Res = LowerEXTRACT_VECTOR_ELT_SSE4(Op, DAG);
+    if (Res.Val)
+      return Res;
+  }
 
-  MVT::ValueType VT = Op.getValueType();
+  MVT VT = Op.getValueType();
   // TODO: handle v16i8.
-  if (MVT::getSizeInBits(VT) == 16) {
+  if (VT.getSizeInBits() == 16) {
     SDOperand Vec = Op.getOperand(0);
     unsigned Idx = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
     if (Idx == 0)
@@ -3789,27 +4010,27 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
                                  DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, Vec),
                                      Op.getOperand(1)));
     // Transform it so it match pextrw which produces a 32-bit result.
-    MVT::ValueType EVT = (MVT::ValueType)(VT+1);
+    MVT EVT = (MVT::SimpleValueType)(VT.getSimpleVT()+1);
     SDOperand Extract = DAG.getNode(X86ISD::PEXTRW, EVT,
                                     Op.getOperand(0), Op.getOperand(1));
     SDOperand Assert  = DAG.getNode(ISD::AssertZext, EVT, Extract,
                                     DAG.getValueType(VT));
     return DAG.getNode(ISD::TRUNCATE, VT, Assert);
-  } else if (MVT::getSizeInBits(VT) == 32) {
+  } else if (VT.getSizeInBits() == 32) {
     unsigned Idx = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
     if (Idx == 0)
       return Op;
     // SHUFPS the element to the lowest double word, then movss.
-    MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4);
+    MVT MaskVT = MVT::getIntVectorWithNumElements(4);
     SmallVector<SDOperand, 8> IdxVec;
     IdxVec.
-      push_back(DAG.getConstant(Idx, MVT::getVectorElementType(MaskVT)));
+      push_back(DAG.getConstant(Idx, MaskVT.getVectorElementType()));
     IdxVec.
-      push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT)));
+      push_back(DAG.getNode(ISD::UNDEF, MaskVT.getVectorElementType()));
     IdxVec.
-      push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT)));
+      push_back(DAG.getNode(ISD::UNDEF, MaskVT.getVectorElementType()));
     IdxVec.
-      push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT)));
+      push_back(DAG.getNode(ISD::UNDEF, MaskVT.getVectorElementType()));
     SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
                                  &IdxVec[0], IdxVec.size());
     SDOperand Vec = Op.getOperand(0);
@@ -3817,7 +4038,7 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
                       Vec, DAG.getNode(ISD::UNDEF, Vec.getValueType()), Mask);
     return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, VT, Vec,
                        DAG.getIntPtrConstant(0));
-  } else if (MVT::getSizeInBits(VT) == 64) {
+  } else if (VT.getSizeInBits() == 64) {
     // FIXME: .td only matches this for <2 x f64>, not <2 x i64> on 32b
     // FIXME: seems like this should be unnecessary if mov{h,l}pd were taught
     //        to match extract_elt for f64.
@@ -3828,11 +4049,11 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
     // UNPCKHPD the element to the lowest double word, then movsd.
     // Note if the lower 64 bits of the result of the UNPCKHPD is then stored
     // to a f64mem, the whole operation is folded into a single MOVHPDmr.
-    MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4);
+    MVT MaskVT = MVT::getIntVectorWithNumElements(4);
     SmallVector<SDOperand, 8> IdxVec;
-    IdxVec.push_back(DAG.getConstant(1, MVT::getVectorElementType(MaskVT)));
+    IdxVec.push_back(DAG.getConstant(1, MaskVT.getVectorElementType()));
     IdxVec.
-      push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT)));
+      push_back(DAG.getNode(ISD::UNDEF, MaskVT.getVectorElementType()));
     SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
                                  &IdxVec[0], IdxVec.size());
     SDOperand Vec = Op.getOperand(0);
@@ -3847,15 +4068,15 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
 
 SDOperand
 X86TargetLowering::LowerINSERT_VECTOR_ELT_SSE4(SDOperand Op, SelectionDAG &DAG){
-  MVT::ValueType VT = Op.getValueType();
-  MVT::ValueType EVT = MVT::getVectorElementType(VT);
+  MVT VT = Op.getValueType();
+  MVT EVT = VT.getVectorElementType();
 
   SDOperand N0 = Op.getOperand(0);
   SDOperand N1 = Op.getOperand(1);
   SDOperand N2 = Op.getOperand(2);
 
-  if ((MVT::getSizeInBits(EVT) == 8) || (MVT::getSizeInBits(EVT) == 16)) {
-    unsigned Opc = (MVT::getSizeInBits(EVT) == 8) ? X86ISD::PINSRB
+  if ((EVT.getSizeInBits() == 8) || (EVT.getSizeInBits() == 16)) {
+    unsigned Opc = (EVT.getSizeInBits() == 8) ? X86ISD::PINSRB
                                                   : X86ISD::PINSRW;
     // Transform it so it match pinsr{b,w} which expects a GR32 as its second
     // argument.
@@ -3881,8 +4102,8 @@ X86TargetLowering::LowerINSERT_VECTOR_ELT_SSE4(SDOperand Op, SelectionDAG &DAG){
 
 SDOperand
 X86TargetLowering::LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
-  MVT::ValueType VT = Op.getValueType();
-  MVT::ValueType EVT = MVT::getVectorElementType(VT);
+  MVT VT = Op.getValueType();
+  MVT EVT = VT.getVectorElementType();
 
   if (Subtarget->hasSSE41())
     return LowerINSERT_VECTOR_ELT_SSE4(Op, DAG);
@@ -3894,7 +4115,7 @@ X86TargetLowering::LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
   SDOperand N1 = Op.getOperand(1);
   SDOperand N2 = Op.getOperand(2);
 
-  if (MVT::getSizeInBits(EVT) == 16) {
+  if (EVT.getSizeInBits() == 16) {
     // Transform it so it match pinsrw which expects a 16-bit value in a GR32
     // as its second argument.
     if (N1.getValueType() != MVT::i32)
@@ -3909,8 +4130,8 @@ X86TargetLowering::LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
 SDOperand
 X86TargetLowering::LowerSCALAR_TO_VECTOR(SDOperand Op, SelectionDAG &DAG) {
   SDOperand AnyExt = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, Op.getOperand(0));
-  MVT::ValueType VT = MVT::v2i32;
-  switch (Op.getValueType()) {
+  MVT VT = MVT::v2i32;
+  switch (Op.getValueType().getSimpleVT()) {
   default: break;
   case MVT::v16i8:
   case MVT::v8i16:
@@ -3949,9 +4170,6 @@ 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_ &&
@@ -3973,10 +4191,10 @@ X86TargetLowering::LowerGlobalAddress(SDOperand Op, SelectionDAG &DAG) {
   return Result;
 }
 
-// Lower ISD::GlobalTLSAddress using the "general dynamic" model
+// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 32 bit
 static SDOperand
-LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
-                              const MVT::ValueType PtrVT) {
+LowerToTLSGeneralDynamicModel32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
+                                const MVT PtrVT) {
   SDOperand InFlag;
   SDOperand Chain = DAG.getCopyToReg(DAG.getEntryNode(), X86::EBX,
                                      DAG.getNode(X86ISD::GlobalBaseReg,
@@ -4011,11 +4229,43 @@ LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
   return DAG.getCopyFromReg(Chain, X86::EAX, PtrVT, InFlag);
 }
 
+// Lower ISD::GlobalTLSAddress using the "general dynamic" model, 64 bit
+static SDOperand
+LowerToTLSGeneralDynamicModel64(GlobalAddressSDNode *GA, SelectionDAG &DAG,
+                                const MVT PtrVT) {
+  SDOperand InFlag, Chain;
+
+  // emit leaq symbol@TLSGD(%rip), %rdi
+  SDVTList NodeTys = DAG.getVTList(PtrVT, MVT::Other, MVT::Flag);
+  SDOperand TGA = DAG.getTargetGlobalAddress(GA->getGlobal(),
+                                             GA->getValueType(0),
+                                             GA->getOffset());
+  SDOperand Ops[]  = { DAG.getEntryNode(), TGA};
+  SDOperand Result = DAG.getNode(X86ISD::TLSADDR, NodeTys, Ops, 2);
+  Chain  = Result.getValue(1);
+  InFlag = Result.getValue(2);
+
+  // call ___tls_get_addr. This function receives its argument in
+  // the register RDI.
+  Chain = DAG.getCopyToReg(Chain, X86::RDI, Result, InFlag);
+  InFlag = Chain.getValue(1);
+
+  NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
+  SDOperand Ops1[] = { Chain,
+                      DAG.getTargetExternalSymbol("___tls_get_addr",
+                                                  PtrVT),
+                      DAG.getRegister(X86::RDI, PtrVT),
+                      InFlag };
+  Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops1, 4);
+  InFlag = Chain.getValue(1);
+
+  return DAG.getCopyFromReg(Chain, X86::RAX, PtrVT, InFlag);
+}
+
 // Lower ISD::GlobalTLSAddress using the "initial exec" (for no-pic) or
 // "local exec" model.
-static SDOperand
-LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
-                         const MVT::ValueType PtrVT) {
+static SDOperand LowerToTLSExecModel(GlobalAddressSDNode *GA, SelectionDAG &DAG,
+                                     const MVT PtrVT) {
   // Get the Thread Pointer
   SDOperand ThreadPointer = DAG.getNode(X86ISD::THREAD_POINTER, PtrVT);
   // emit "addl x@ntpoff,%eax" (local exec) or "addl x@indntpoff,%eax" (initial
@@ -4038,15 +4288,19 @@ SDOperand
 X86TargetLowering::LowerGlobalTLSAddress(SDOperand Op, SelectionDAG &DAG) {
   // TODO: implement the "local dynamic" model
   // TODO: implement the "initial exec"model for pic executables
-  assert(!Subtarget->is64Bit() && Subtarget->isTargetELF() &&
-         "TLS not implemented for non-ELF and 64-bit targets");
+  assert(Subtarget->isTargetELF() &&
+         "TLS not implemented for non-ELF targets");
   GlobalAddressSDNode *GA = cast<GlobalAddressSDNode>(Op);
   // If the relocation model is PIC, use the "General Dynamic" TLS Model,
   // otherwise use the "Local Exec"TLS Model
-  if (getTargetMachine().getRelocationModel() == Reloc::PIC_)
-    return LowerToTLSGeneralDynamicModel(GA, DAG, getPointerTy());
-  else
-    return LowerToTLSExecModel(GA, DAG, getPointerTy());
+  if (Subtarget->is64Bit()) {
+    return LowerToTLSGeneralDynamicModel64(GA, DAG, getPointerTy());
+  } else {
+    if (getTargetMachine().getRelocationModel() == Reloc::PIC_)
+      return LowerToTLSGeneralDynamicModel32(GA, DAG, getPointerTy());
+    else
+      return LowerToTLSExecModel(GA, DAG, getPointerTy());
+  }
 }
 
 SDOperand
@@ -4083,64 +4337,65 @@ SDOperand X86TargetLowering::LowerJumpTable(SDOperand Op, SelectionDAG &DAG) {
 /// LowerShift - Lower SRA_PARTS and friends, which return two i32 values and
 /// take a 2 x i32 value to shift plus a shift amount. 
 SDOperand X86TargetLowering::LowerShift(SDOperand Op, SelectionDAG &DAG) {
-  assert(Op.getNumOperands() == 3 && Op.getValueType() == MVT::i32 &&
-         "Not an i64 shift!");
+  assert(Op.getNumOperands() == 3 && "Not a double-shift!");
+  MVT VT = Op.getValueType();
+  unsigned VTBits = VT.getSizeInBits();
   bool isSRA = Op.getOpcode() == ISD::SRA_PARTS;
   SDOperand ShOpLo = Op.getOperand(0);
   SDOperand ShOpHi = Op.getOperand(1);
   SDOperand ShAmt  = Op.getOperand(2);
   SDOperand Tmp1 = isSRA ?
-    DAG.getNode(ISD::SRA, MVT::i32, ShOpHi, DAG.getConstant(31, MVT::i8)) :
-    DAG.getConstant(0, MVT::i32);
+    DAG.getNode(ISD::SRA, VT, ShOpHi, DAG.getConstant(VTBits - 1, MVT::i8)) :
+    DAG.getConstant(0, VT);
 
   SDOperand Tmp2, Tmp3;
   if (Op.getOpcode() == ISD::SHL_PARTS) {
-    Tmp2 = DAG.getNode(X86ISD::SHLD, MVT::i32, ShOpHi, ShOpLo, ShAmt);
-    Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, ShOpLo, ShAmt);
+    Tmp2 = DAG.getNode(X86ISD::SHLD, VT, ShOpHi, ShOpLo, ShAmt);
+    Tmp3 = DAG.getNode(ISD::SHL, VT, ShOpLo, ShAmt);
   } else {
-    Tmp2 = DAG.getNode(X86ISD::SHRD, MVT::i32, ShOpLo, ShOpHi, ShAmt);
-    Tmp3 = DAG.getNode(isSRA ? ISD::SRA : ISD::SRL, MVT::i32, ShOpHi, ShAmt);
+    Tmp2 = DAG.getNode(X86ISD::SHRD, VT, ShOpLo, ShOpHi, ShAmt);
+    Tmp3 = DAG.getNode(isSRA ? ISD::SRA : ISD::SRL, VT, ShOpHi, ShAmt);
   }
 
-  const MVT::ValueType *VTs = DAG.getNodeValueTypes(MVT::Other, MVT::Flag);
+  const MVT *VTs = DAG.getNodeValueTypes(MVT::Other, MVT::Flag);
   SDOperand AndNode = DAG.getNode(ISD::AND, MVT::i8, ShAmt,
-                                  DAG.getConstant(32, MVT::i8));
-  SDOperand Cond = DAG.getNode(X86ISD::CMP, MVT::i32,
+                                  DAG.getConstant(VTBits, MVT::i8));
+  SDOperand Cond = DAG.getNode(X86ISD::CMP, VT,
                                AndNode, DAG.getConstant(0, MVT::i8));
 
   SDOperand Hi, Lo;
   SDOperand CC = DAG.getConstant(X86::COND_NE, MVT::i8);
-  VTs = DAG.getNodeValueTypes(MVT::i32, MVT::Flag);
+  VTs = DAG.getNodeValueTypes(VT, MVT::Flag);
   SmallVector<SDOperand, 4> Ops;
   if (Op.getOpcode() == ISD::SHL_PARTS) {
     Ops.push_back(Tmp2);
     Ops.push_back(Tmp3);
     Ops.push_back(CC);
     Ops.push_back(Cond);
-    Hi = DAG.getNode(X86ISD::CMOV, MVT::i32, &Ops[0], Ops.size());
+    Hi = DAG.getNode(X86ISD::CMOV, VT, &Ops[0], Ops.size());
 
     Ops.clear();
     Ops.push_back(Tmp3);
     Ops.push_back(Tmp1);
     Ops.push_back(CC);
     Ops.push_back(Cond);
-    Lo = DAG.getNode(X86ISD::CMOV, MVT::i32, &Ops[0], Ops.size());
+    Lo = DAG.getNode(X86ISD::CMOV, VT, &Ops[0], Ops.size());
   } else {
     Ops.push_back(Tmp2);
     Ops.push_back(Tmp3);
     Ops.push_back(CC);
     Ops.push_back(Cond);
-    Lo = DAG.getNode(X86ISD::CMOV, MVT::i32, &Ops[0], Ops.size());
+    Lo = DAG.getNode(X86ISD::CMOV, VT, &Ops[0], Ops.size());
 
     Ops.clear();
     Ops.push_back(Tmp3);
     Ops.push_back(Tmp1);
     Ops.push_back(CC);
     Ops.push_back(Cond);
-    Hi = DAG.getNode(X86ISD::CMOV, MVT::i32, &Ops[0], Ops.size());
+    Hi = DAG.getNode(X86ISD::CMOV, VT, &Ops[0], Ops.size());
   }
 
-  VTs = DAG.getNodeValueTypes(MVT::i32, MVT::i32);
+  VTs = DAG.getNodeValueTypes(VT, VT);
   Ops.clear();
   Ops.push_back(Lo);
   Ops.push_back(Hi);
@@ -4148,13 +4403,18 @@ SDOperand X86TargetLowering::LowerShift(SDOperand Op, SelectionDAG &DAG) {
 }
 
 SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
-  assert(Op.getOperand(0).getValueType() <= MVT::i64 &&
-         Op.getOperand(0).getValueType() >= MVT::i16 &&
+  MVT SrcVT = Op.getOperand(0).getValueType();
+  assert(SrcVT.getSimpleVT() <= MVT::i64 && SrcVT.getSimpleVT() >= MVT::i16 &&
          "Unknown SINT_TO_FP to lower!");
-
-  SDOperand Result;
-  MVT::ValueType SrcVT = Op.getOperand(0).getValueType();
-  unsigned Size = MVT::getSizeInBits(SrcVT)/8;
+  
+  // These are really Legal; caller falls through into that case.
+  if (SrcVT == MVT::i32 && isScalarFPTypeInSSEReg(Op.getValueType()))
+    return SDOperand();
+  if (SrcVT == MVT::i64 && Op.getValueType() != MVT::f80 && 
+      Subtarget->is64Bit())
+    return SDOperand();
+  
+  unsigned Size = SrcVT.getSizeInBits()/8;
   MachineFunction &MF = DAG.getMachineFunction();
   int SSFI = MF.getFrameInfo()->CreateStackObject(Size, Size);
   SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
@@ -4163,13 +4423,6 @@ SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
                                  PseudoSourceValue::getFixedStack(),
                                  SSFI);
 
-  // These are really Legal; caller falls through into that case.
-  if (SrcVT == MVT::i32 && isScalarFPTypeInSSEReg(Op.getValueType()))
-    return Result;
-  if (SrcVT == MVT::i64 && Op.getValueType() != MVT::f80 && 
-      Subtarget->is64Bit())
-    return Result;
-
   // Build the FILD
   SDVTList Tys;
   bool useSSE = isScalarFPTypeInSSEReg(Op.getValueType());
@@ -4181,8 +4434,8 @@ SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
   Ops.push_back(Chain);
   Ops.push_back(StackSlot);
   Ops.push_back(DAG.getValueType(SrcVT));
-  Result = DAG.getNode(useSSE ? X86ISD::FILD_FLAG :X86ISD::FILD,
-                       Tys, &Ops[0], Ops.size());
+  SDOperand Result = DAG.getNode(useSSE ? X86ISD::FILD_FLAG : X86ISD::FILD,
+                                 Tys, &Ops[0], Ops.size());
 
   if (useSSE) {
     Chain = Result.getValue(1);
@@ -4211,7 +4464,8 @@ SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
 
 std::pair<SDOperand,SDOperand> X86TargetLowering::
 FP_TO_SINTHelper(SDOperand Op, SelectionDAG &DAG) {
-  assert(Op.getValueType() <= MVT::i64 && Op.getValueType() >= MVT::i16 &&
+  assert(Op.getValueType().getSimpleVT() <= MVT::i64 &&
+         Op.getValueType().getSimpleVT() >= MVT::i16 &&
          "Unknown FP_TO_SINT to lower!");
 
   // These are really Legal.
@@ -4226,11 +4480,11 @@ FP_TO_SINTHelper(SDOperand Op, SelectionDAG &DAG) {
   // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary
   // stack slot.
   MachineFunction &MF = DAG.getMachineFunction();
-  unsigned MemSize = MVT::getSizeInBits(Op.getValueType())/8;
+  unsigned MemSize = Op.getValueType().getSizeInBits()/8;
   int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
   SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
   unsigned Opc;
-  switch (Op.getValueType()) {
+  switch (Op.getValueType().getSimpleVT()) {
   default: assert(0 && "Invalid FP_TO_SINT to lower!");
   case MVT::i16: Opc = X86ISD::FP_TO_INT16_IN_MEM; break;
   case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break;
@@ -4282,18 +4536,17 @@ SDNode *X86TargetLowering::ExpandFP_TO_SINT(SDNode *N, SelectionDAG &DAG) {
 }  
 
 SDOperand X86TargetLowering::LowerFABS(SDOperand Op, SelectionDAG &DAG) {
-  MVT::ValueType VT = Op.getValueType();
-  MVT::ValueType EltVT = VT;
-  if (MVT::isVector(VT))
-    EltVT = MVT::getVectorElementType(VT);
-  const Type *OpNTy =  MVT::getTypeForValueType(EltVT);
+  MVT VT = Op.getValueType();
+  MVT EltVT = VT;
+  if (VT.isVector())
+    EltVT = VT.getVectorElementType();
   std::vector<Constant*> CV;
   if (EltVT == MVT::f64) {
-    Constant *C = ConstantFP::get(OpNTy, APFloat(APInt(64, ~(1ULL << 63))));
+    Constant *C = ConstantFP::get(APFloat(APInt(64, ~(1ULL << 63))));
     CV.push_back(C);
     CV.push_back(C);
   } else {
-    Constant *C = ConstantFP::get(OpNTy, APFloat(APInt(32, ~(1U << 31))));
+    Constant *C = ConstantFP::get(APFloat(APInt(32, ~(1U << 31))));
     CV.push_back(C);
     CV.push_back(C);
     CV.push_back(C);
@@ -4308,21 +4561,20 @@ SDOperand X86TargetLowering::LowerFABS(SDOperand Op, SelectionDAG &DAG) {
 }
 
 SDOperand X86TargetLowering::LowerFNEG(SDOperand Op, SelectionDAG &DAG) {
-  MVT::ValueType VT = Op.getValueType();
-  MVT::ValueType EltVT = VT;
+  MVT VT = Op.getValueType();
+  MVT EltVT = VT;
   unsigned EltNum = 1;
-  if (MVT::isVector(VT)) {
-    EltVT = MVT::getVectorElementType(VT);
-    EltNum = MVT::getVectorNumElements(VT);
+  if (VT.isVector()) {
+    EltVT = VT.getVectorElementType();
+    EltNum = VT.getVectorNumElements();
   }
-  const Type *OpNTy =  MVT::getTypeForValueType(EltVT);
   std::vector<Constant*> CV;
   if (EltVT == MVT::f64) {
-    Constant *C = ConstantFP::get(OpNTy, APFloat(APInt(64, 1ULL << 63)));
+    Constant *C = ConstantFP::get(APFloat(APInt(64, 1ULL << 63)));
     CV.push_back(C);
     CV.push_back(C);
   } else {
-    Constant *C = ConstantFP::get(OpNTy, APFloat(APInt(32, 1U << 31)));
+    Constant *C = ConstantFP::get(APFloat(APInt(32, 1U << 31)));
     CV.push_back(C);
     CV.push_back(C);
     CV.push_back(C);
@@ -4333,7 +4585,7 @@ SDOperand X86TargetLowering::LowerFNEG(SDOperand Op, SelectionDAG &DAG) {
   SDOperand Mask = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
                                PseudoSourceValue::getConstantPool(), 0,
                                false, 16);
-  if (MVT::isVector(VT)) {
+  if (VT.isVector()) {
     return DAG.getNode(ISD::BIT_CONVERT, VT,
                        DAG.getNode(ISD::XOR, MVT::v2i64,
                     DAG.getNode(ISD::BIT_CONVERT, MVT::v2i64, Op.getOperand(0)),
@@ -4346,21 +4598,18 @@ SDOperand X86TargetLowering::LowerFNEG(SDOperand Op, SelectionDAG &DAG) {
 SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
   SDOperand Op0 = Op.getOperand(0);
   SDOperand Op1 = Op.getOperand(1);
-  MVT::ValueType VT = Op.getValueType();
-  MVT::ValueType SrcVT = Op1.getValueType();
-  const Type *SrcTy =  MVT::getTypeForValueType(SrcVT);
+  MVT VT = Op.getValueType();
+  MVT SrcVT = Op1.getValueType();
 
   // If second operand is smaller, extend it first.
-  if (MVT::getSizeInBits(SrcVT) < MVT::getSizeInBits(VT)) {
+  if (SrcVT.bitsLT(VT)) {
     Op1 = DAG.getNode(ISD::FP_EXTEND, VT, Op1);
     SrcVT = VT;
-    SrcTy = MVT::getTypeForValueType(SrcVT);
   }
   // And if it is bigger, shrink it first.
-  if (MVT::getSizeInBits(SrcVT) > MVT::getSizeInBits(VT)) {
+  if (SrcVT.bitsGT(VT)) {
     Op1 = DAG.getNode(ISD::FP_ROUND, VT, Op1, DAG.getIntPtrConstant(1));
     SrcVT = VT;
-    SrcTy = MVT::getTypeForValueType(SrcVT);
   }
 
   // At this point the operands and the result should have the same
@@ -4369,13 +4618,13 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
   // First get the sign bit of second operand.
   std::vector<Constant*> CV;
   if (SrcVT == MVT::f64) {
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(64, 1ULL << 63))));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(64, 0))));
+    CV.push_back(ConstantFP::get(APFloat(APInt(64, 1ULL << 63))));
+    CV.push_back(ConstantFP::get(APFloat(APInt(64, 0))));
   } else {
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, 1U << 31))));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, 0))));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, 0))));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, 0))));
+    CV.push_back(ConstantFP::get(APFloat(APInt(32, 1U << 31))));
+    CV.push_back(ConstantFP::get(APFloat(APInt(32, 0))));
+    CV.push_back(ConstantFP::get(APFloat(APInt(32, 0))));
+    CV.push_back(ConstantFP::get(APFloat(APInt(32, 0))));
   }
   Constant *C = ConstantVector::get(CV);
   SDOperand CPIdx = DAG.getConstantPool(C, getPointerTy(), 4);
@@ -4385,7 +4634,7 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
   SDOperand SignBit = DAG.getNode(X86ISD::FAND, SrcVT, Op1, Mask1);
 
   // Shift sign bit right or left if the two operands have different types.
-  if (MVT::getSizeInBits(SrcVT) > MVT::getSizeInBits(VT)) {
+  if (SrcVT.bitsGT(VT)) {
     // Op0 is MVT::f32, Op1 is MVT::f64.
     SignBit = DAG.getNode(ISD::SCALAR_TO_VECTOR, MVT::v2f64, SignBit);
     SignBit = DAG.getNode(X86ISD::FSRL, MVT::v2f64, SignBit,
@@ -4398,13 +4647,13 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
   // Clear first operand sign bit.
   CV.clear();
   if (VT == MVT::f64) {
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(64, ~(1ULL << 63)))));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(64, 0))));
+    CV.push_back(ConstantFP::get(APFloat(APInt(64, ~(1ULL << 63)))));
+    CV.push_back(ConstantFP::get(APFloat(APInt(64, 0))));
   } else {
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, ~(1U << 31)))));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, 0))));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, 0))));
-    CV.push_back(ConstantFP::get(SrcTy, APFloat(APInt(32, 0))));
+    CV.push_back(ConstantFP::get(APFloat(APInt(32, ~(1U << 31)))));
+    CV.push_back(ConstantFP::get(APFloat(APInt(32, 0))));
+    CV.push_back(ConstantFP::get(APFloat(APInt(32, 0))));
+    CV.push_back(ConstantFP::get(APFloat(APInt(32, 0))));
   }
   C = ConstantVector::get(CV);
   CPIdx = DAG.getConstantPool(C, getPointerTy(), 4);
@@ -4424,7 +4673,7 @@ SDOperand X86TargetLowering::LowerSETCC(SDOperand Op, SelectionDAG &DAG) {
   SDOperand Op1 = Op.getOperand(1);
   SDOperand CC = Op.getOperand(2);
   ISD::CondCode SetCCOpcode = cast<CondCodeSDNode>(CC)->get();
-  bool isFP = MVT::isFloatingPoint(Op.getOperand(1).getValueType());
+  bool isFP = Op.getOperand(1).getValueType().isFloatingPoint();
   unsigned X86CC;
 
   if (translateX86CC(cast<CondCodeSDNode>(CC)->get(), isFP, X86CC,
@@ -4472,10 +4721,10 @@ SDOperand X86TargetLowering::LowerSELECT(SDOperand Op, SelectionDAG &DAG) {
 
     SDOperand Cmp = Cond.getOperand(1);
     unsigned Opc = Cmp.getOpcode();
-    MVT::ValueType VT = Op.getValueType();
+    MVT VT = Op.getValueType();
     
     bool IllegalFPCMov = false;
-    if (MVT::isFloatingPoint(VT) && !MVT::isVector(VT) &&
+    if (VT.isFloatingPoint() && !VT.isVector() &&
         !isScalarFPTypeInSSEReg(VT))  // FPStack?
       IllegalFPCMov = !hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended());
     
@@ -4492,7 +4741,7 @@ SDOperand X86TargetLowering::LowerSELECT(SDOperand Op, SelectionDAG &DAG) {
     Cond= DAG.getNode(X86ISD::CMP, MVT::i32, Cond, DAG.getConstant(0, MVT::i8));
   }
 
-  const MVT::ValueType *VTs = DAG.getNodeValueTypes(Op.getValueType(),
+  const MVT *VTs = DAG.getNodeValueTypes(Op.getValueType(),
                                                     MVT::Flag);
   SmallVector<SDOperand, 4> Ops;
   // X86ISD::CMOV means set the result (which is operand 1) to the RHS if
@@ -4548,16 +4797,18 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDOperand Op,
                                            SelectionDAG &DAG) {
   assert(Subtarget->isTargetCygMing() &&
          "This should be used only on Cygwin/Mingw targets");
-  
+
   // Get the inputs.
   SDOperand Chain = Op.getOperand(0);
   SDOperand Size  = Op.getOperand(1);
   // FIXME: Ensure alignment here
 
   SDOperand Flag;
-  
-  MVT::ValueType IntPtr = getPointerTy();
-  MVT::ValueType SPTy = Subtarget->is64Bit() ? MVT::i64 : MVT::i32;
+
+  MVT IntPtr = getPointerTy();
+  MVT SPTy = Subtarget->is64Bit() ? MVT::i64 : MVT::i32;
+
+  Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(0));
 
   Chain = DAG.getCopyToReg(Chain, X86::EAX, Size, Flag);
   Flag = Chain.getValue(1);
@@ -4566,54 +4817,70 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDOperand Op,
   SDOperand Ops[] = { Chain,
                       DAG.getTargetExternalSymbol("_alloca", IntPtr),
                       DAG.getRegister(X86::EAX, IntPtr),
+                      DAG.getRegister(X86StackPtr, SPTy),
                       Flag };
-  Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops, 4);
+  Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops, 5);
   Flag = Chain.getValue(1);
 
+  Chain = DAG.getCALLSEQ_END(Chain,
+                             DAG.getIntPtrConstant(0),
+                             DAG.getIntPtrConstant(0),
+                             Flag);
+
   Chain = DAG.getCopyFromReg(Chain, X86StackPtr, SPTy).getValue(1);
-  
-  std::vector<MVT::ValueType> Tys;
+
+  std::vector<MVT> Tys;
   Tys.push_back(SPTy);
   Tys.push_back(MVT::Other);
   SDOperand Ops1[2] = { Chain.getValue(0), Chain };
   return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops1, 2);
 }
 
-SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
+SDOperand
+X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG,
+                                           SDOperand Chain,
+                                           SDOperand Dst, SDOperand Src,
+                                           SDOperand Size, unsigned Align,
+                                        const Value *DstSV, uint64_t DstSVOff) {
+  ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
+
+  /// If not DWORD aligned or size is more than the threshold, call the library.
+  /// The libc version is likely to be faster for these cases. It can use the
+  /// address value and run time information about the CPU.
+  if ((Align & 3) == 0 ||
+      !ConstantSize ||
+      ConstantSize->getValue() > getSubtarget()->getMaxInlineSizeThreshold()) {
+    SDOperand InFlag(0, 0);
+
+    // Check to see if there is a specialized entry-point for memory zeroing.
+    ConstantSDNode *V = dyn_cast<ConstantSDNode>(Src);
+    if (const char *bzeroEntry = 
+          V && V->isNullValue() ? Subtarget->getBZeroEntry() : 0) {
+      MVT IntPtr = getPointerTy();
+      const Type *IntPtrTy = getTargetData()->getIntPtrType();
+      TargetLowering::ArgListTy Args; 
+      TargetLowering::ArgListEntry Entry;
+      Entry.Node = Dst;
+      Entry.Ty = IntPtrTy;
+      Args.push_back(Entry);
+      Entry.Node = Size;
+      Args.push_back(Entry);
+      std::pair<SDOperand,SDOperand> CallResult =
+        LowerCallTo(Chain, Type::VoidTy, false, false, false, CallingConv::C,
+                    false, DAG.getExternalSymbol(bzeroEntry, IntPtr),
+                    Args, DAG);
+      return CallResult.second;
+    }
+
+    // Otherwise have the target-independent code call memset.
+    return SDOperand();
+  }
+
+  uint64_t SizeVal = ConstantSize->getValue();
   SDOperand InFlag(0, 0);
-  SDOperand Chain = Op.getOperand(0);
-  unsigned Align =
-    (unsigned)cast<ConstantSDNode>(Op.getOperand(4))->getValue();
-  if (Align == 0) Align = 1;
-
-  ConstantSDNode *I = dyn_cast<ConstantSDNode>(Op.getOperand(3));
-  // If not DWORD aligned or size is more than the threshold, call memset.
-  // The libc version is likely to be faster for these cases. It can use the
-  // address value and run time information about the CPU.
-  if ((Align & 3) != 0 ||
-      (I && I->getValue() > Subtarget->getMaxInlineSizeThreshold())) {
-    MVT::ValueType IntPtr = getPointerTy();
-    const Type *IntPtrTy = getTargetData()->getIntPtrType();
-    TargetLowering::ArgListTy Args; 
-    TargetLowering::ArgListEntry Entry;
-    Entry.Node = Op.getOperand(1);
-    Entry.Ty = IntPtrTy;
-    Args.push_back(Entry);
-    // Extend the unsigned i8 argument to be an int value for the call.
-    Entry.Node = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Op.getOperand(2));
-    Entry.Ty = IntPtrTy;
-    Args.push_back(Entry);
-    Entry.Node = Op.getOperand(3);
-    Args.push_back(Entry);
-    std::pair<SDOperand,SDOperand> CallResult =
-      LowerCallTo(Chain, Type::VoidTy, false, false, false, CallingConv::C,
-                  false, DAG.getExternalSymbol("memset", IntPtr), Args, DAG);
-    return CallResult.second;
-  }
-
-  MVT::ValueType AVT;
+  MVT AVT;
   SDOperand Count;
-  ConstantSDNode *ValC = dyn_cast<ConstantSDNode>(Op.getOperand(2));
+  ConstantSDNode *ValC = dyn_cast<ConstantSDNode>(Src);
   unsigned BytesLeft = 0;
   bool TwoRepStos = false;
   if (ValC) {
@@ -4632,7 +4899,7 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
         ValReg = X86::EAX;
         Val = (Val << 8)  | Val;
         Val = (Val << 16) | Val;
-        if (Subtarget->is64Bit() && ((Align & 0xF) == 0)) {  // QWORD aligned
+        if (Subtarget->is64Bit() && ((Align & 0x7) == 0)) {  // QWORD aligned
           AVT = MVT::i64;
           ValReg = X86::RAX;
           Val = (Val << 32) | Val;
@@ -4641,22 +4908,14 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
       default:  // Byte aligned
         AVT = MVT::i8;
         ValReg = X86::AL;
-        Count = Op.getOperand(3);
+        Count = DAG.getIntPtrConstant(SizeVal);
         break;
     }
 
-    if (AVT > MVT::i8) {
-      if (I) {
-        unsigned UBytes = MVT::getSizeInBits(AVT) / 8;
-        Count = DAG.getIntPtrConstant(I->getValue() / UBytes);
-        BytesLeft = I->getValue() % UBytes;
-      } else {
-        assert(AVT >= MVT::i32 &&
-               "Do not use rep;stos if not at least DWORD aligned");
-        Count = DAG.getNode(ISD::SRL, Op.getOperand(3).getValueType(),
-                            Op.getOperand(3), DAG.getConstant(2, MVT::i8));
-        TwoRepStos = true;
-      }
+    if (AVT.bitsGT(MVT::i8)) {
+      unsigned UBytes = AVT.getSizeInBits() / 8;
+      Count = DAG.getIntPtrConstant(SizeVal / UBytes);
+      BytesLeft = SizeVal % UBytes;
     }
 
     Chain  = DAG.getCopyToReg(Chain, ValReg, DAG.getConstant(Val, AVT),
@@ -4664,8 +4923,8 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
     InFlag = Chain.getValue(1);
   } else {
     AVT = MVT::i8;
-    Count  = Op.getOperand(3);
-    Chain  = DAG.getCopyToReg(Chain, X86::AL, Op.getOperand(2), InFlag);
+    Count  = DAG.getIntPtrConstant(SizeVal);
+    Chain  = DAG.getCopyToReg(Chain, X86::AL, Src, InFlag);
     InFlag = Chain.getValue(1);
   }
 
@@ -4673,7 +4932,7 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
                             Count, InFlag);
   InFlag = Chain.getValue(1);
   Chain  = DAG.getCopyToReg(Chain, Subtarget->is64Bit() ? X86::RDI : X86::EDI,
-                            Op.getOperand(1), InFlag);
+                            Dst, InFlag);
   InFlag = Chain.getValue(1);
 
   SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
@@ -4685,8 +4944,8 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
 
   if (TwoRepStos) {
     InFlag = Chain.getValue(1);
-    Count = Op.getOperand(3);
-    MVT::ValueType CVT = Count.getValueType();
+    Count  = Size;
+    MVT CVT = Count.getValueType();
     SDOperand Left = DAG.getNode(ISD::AND, CVT, Count,
                                DAG.getConstant((AVT == MVT::i64) ? 7 : 3, CVT));
     Chain  = DAG.getCopyToReg(Chain, (CVT == MVT::i64) ? X86::RCX : X86::ECX,
@@ -4699,79 +4958,66 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
     Ops.push_back(InFlag);
     Chain  = DAG.getNode(X86ISD::REP_STOS, Tys, &Ops[0], Ops.size());
   } else if (BytesLeft) {
-    // Issue stores for the last 1 - 7 bytes.
-    SDOperand Value;
-    unsigned Val = ValC->getValue() & 255;
-    unsigned Offset = I->getValue() - BytesLeft;
-    SDOperand DstAddr = Op.getOperand(1);
-    MVT::ValueType AddrVT = DstAddr.getValueType();
-    if (BytesLeft >= 4) {
-      Val = (Val << 8)  | Val;
-      Val = (Val << 16) | Val;
-      Value = DAG.getConstant(Val, MVT::i32);
-      Chain = DAG.getStore(Chain, Value,
-                           DAG.getNode(ISD::ADD, AddrVT, DstAddr,
-                                       DAG.getConstant(Offset, AddrVT)),
-                           NULL, 0);
-      BytesLeft -= 4;
-      Offset += 4;
-    }
-    if (BytesLeft >= 2) {
-      Value = DAG.getConstant((Val << 8) | Val, MVT::i16);
-      Chain = DAG.getStore(Chain, Value,
-                           DAG.getNode(ISD::ADD, AddrVT, DstAddr,
-                                       DAG.getConstant(Offset, AddrVT)),
-                           NULL, 0);
-      BytesLeft -= 2;
-      Offset += 2;
-    }
-    if (BytesLeft == 1) {
-      Value = DAG.getConstant(Val, MVT::i8);
-      Chain = DAG.getStore(Chain, Value,
-                           DAG.getNode(ISD::ADD, AddrVT, DstAddr,
-                                       DAG.getConstant(Offset, AddrVT)),
-                           NULL, 0);
-    }
+    // Handle the last 1 - 7 bytes.
+    unsigned Offset = SizeVal - BytesLeft;
+    MVT AddrVT = Dst.getValueType();
+    MVT SizeVT = Size.getValueType();
+
+    Chain = DAG.getMemset(Chain,
+                          DAG.getNode(ISD::ADD, AddrVT, Dst,
+                                      DAG.getConstant(Offset, AddrVT)),
+                          Src,
+                          DAG.getConstant(BytesLeft, SizeVT),
+                          Align, DstSV, DstSVOff + Offset);
   }
 
+  // TODO: Use a Tokenfactor, as in memcpy, instead of a single chain.
   return Chain;
 }
 
-SDOperand X86TargetLowering::LowerMEMCPYInline(SDOperand Chain,
-                                               SDOperand Dest,
-                                               SDOperand Source,
-                                               unsigned Size,
-                                               unsigned Align,
-                                               SelectionDAG &DAG) {
-  MVT::ValueType AVT;
+SDOperand
+X86TargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG,
+                                           SDOperand Chain,
+                                           SDOperand Dst, SDOperand Src,
+                                           SDOperand Size, unsigned Align,
+                                           bool AlwaysInline,
+                                           const Value *DstSV, uint64_t DstSVOff,
+                                           const Value *SrcSV, uint64_t SrcSVOff){
+  
+  // This requires the copy size to be a constant, preferrably
+  // within a subtarget-specific limit.
+  ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
+  if (!ConstantSize)
+    return SDOperand();
+  uint64_t SizeVal = ConstantSize->getValue();
+  if (!AlwaysInline && SizeVal > getSubtarget()->getMaxInlineSizeThreshold())
+    return SDOperand();
+
+  MVT AVT;
   unsigned BytesLeft = 0;
-  switch (Align & 3) {
-    case 2:   // WORD aligned
-      AVT = MVT::i16;
-      break;
-    case 0:  // DWORD aligned
-      AVT = MVT::i32;
-      if (Subtarget->is64Bit() && ((Align & 0xF) == 0))  // QWORD aligned
-        AVT = MVT::i64;
-      break;
-    default:  // Byte aligned
-      AVT = MVT::i8;
-      break;
-  }
+  if (Align >= 8 && Subtarget->is64Bit())
+    AVT = MVT::i64;
+  else if (Align >= 4)
+    AVT = MVT::i32;
+  else if (Align >= 2)
+    AVT = MVT::i16;
+  else
+    AVT = MVT::i8;
 
-  unsigned UBytes = MVT::getSizeInBits(AVT) / 8;
-  SDOperand Count = DAG.getIntPtrConstant(Size / UBytes);
-  BytesLeft = Size % UBytes;
+  unsigned UBytes = AVT.getSizeInBits() / 8;
+  unsigned CountVal = SizeVal / UBytes;
+  SDOperand Count = DAG.getIntPtrConstant(CountVal);
+  BytesLeft = SizeVal % UBytes;
 
   SDOperand InFlag(0, 0);
   Chain  = DAG.getCopyToReg(Chain, Subtarget->is64Bit() ? X86::RCX : X86::ECX,
                             Count, InFlag);
   InFlag = Chain.getValue(1);
   Chain  = DAG.getCopyToReg(Chain, Subtarget->is64Bit() ? X86::RDI : X86::EDI,
-                            Dest, InFlag);
+                            Dst, InFlag);
   InFlag = Chain.getValue(1);
   Chain  = DAG.getCopyToReg(Chain, Subtarget->is64Bit() ? X86::RSI : X86::ESI,
-                            Source, InFlag);
+                            Src, InFlag);
   InFlag = Chain.getValue(1);
 
   SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
@@ -4779,57 +5025,28 @@ SDOperand X86TargetLowering::LowerMEMCPYInline(SDOperand Chain,
   Ops.push_back(Chain);
   Ops.push_back(DAG.getValueType(AVT));
   Ops.push_back(InFlag);
-  Chain = DAG.getNode(X86ISD::REP_MOVS, Tys, &Ops[0], Ops.size());
+  SDOperand RepMovs = DAG.getNode(X86ISD::REP_MOVS, Tys, &Ops[0], Ops.size());
 
+  SmallVector<SDOperand, 4> Results;
+  Results.push_back(RepMovs);
   if (BytesLeft) {
-    // Issue loads and stores for the last 1 - 7 bytes.
-    unsigned Offset = Size - BytesLeft;
-    SDOperand DstAddr = Dest;
-    MVT::ValueType DstVT = DstAddr.getValueType();
-    SDOperand SrcAddr = Source;
-    MVT::ValueType SrcVT = SrcAddr.getValueType();
-    SDOperand Value;
-    if (BytesLeft >= 4) {
-      Value = DAG.getLoad(MVT::i32, Chain,
-                          DAG.getNode(ISD::ADD, SrcVT, SrcAddr,
-                                      DAG.getConstant(Offset, SrcVT)),
-                          NULL, 0);
-      Chain = Value.getValue(1);
-      Chain = DAG.getStore(Chain, Value,
-                           DAG.getNode(ISD::ADD, DstVT, DstAddr,
-                                       DAG.getConstant(Offset, DstVT)),
-                           NULL, 0);
-      BytesLeft -= 4;
-      Offset += 4;
-    }
-    if (BytesLeft >= 2) {
-      Value = DAG.getLoad(MVT::i16, Chain,
-                          DAG.getNode(ISD::ADD, SrcVT, SrcAddr,
-                                      DAG.getConstant(Offset, SrcVT)),
-                          NULL, 0);
-      Chain = Value.getValue(1);
-      Chain = DAG.getStore(Chain, Value,
-                           DAG.getNode(ISD::ADD, DstVT, DstAddr,
-                                       DAG.getConstant(Offset, DstVT)),
-                           NULL, 0);
-      BytesLeft -= 2;
-      Offset += 2;
-    }
-
-    if (BytesLeft == 1) {
-      Value = DAG.getLoad(MVT::i8, Chain,
-                          DAG.getNode(ISD::ADD, SrcVT, SrcAddr,
-                                      DAG.getConstant(Offset, SrcVT)),
-                          NULL, 0);
-      Chain = Value.getValue(1);
-      Chain = DAG.getStore(Chain, Value,
-                           DAG.getNode(ISD::ADD, DstVT, DstAddr,
-                                       DAG.getConstant(Offset, DstVT)),
-                           NULL, 0);
-    }
+    // Handle the last 1 - 7 bytes.
+    unsigned Offset = SizeVal - BytesLeft;
+    MVT DstVT = Dst.getValueType();
+    MVT SrcVT = Src.getValueType();
+    MVT SizeVT = Size.getValueType();
+    Results.push_back(DAG.getMemcpy(Chain,
+                                    DAG.getNode(ISD::ADD, DstVT, Dst,
+                                                DAG.getConstant(Offset, DstVT)),
+                                    DAG.getNode(ISD::ADD, SrcVT, Src,
+                                                DAG.getConstant(Offset, SrcVT)),
+                                    DAG.getConstant(BytesLeft, SizeVT),
+                                    Align, AlwaysInline,
+                                    DstSV, DstSVOff + Offset,
+                                    SrcSV, SrcSVOff + Offset));
   }
 
-  return Chain;
+  return DAG.getNode(ISD::TokenFactor, MVT::Other, &Results[0], Results.size());
 }
 
 /// Expand the result of: i64,outchain = READCYCLECOUNTER inchain
@@ -4908,28 +5125,30 @@ SDOperand X86TargetLowering::LowerVASTART(SDOperand Op, SelectionDAG &DAG) {
   return DAG.getNode(ISD::TokenFactor, MVT::Other, &MemOps[0], MemOps.size());
 }
 
+SDOperand X86TargetLowering::LowerVAARG(SDOperand Op, SelectionDAG &DAG) {
+  // X86-64 va_list is a struct { i32, i32, i8*, i8* }.
+  assert(Subtarget->is64Bit() && "This code only handles 64-bit va_arg!");
+  SDOperand Chain = Op.getOperand(0);
+  SDOperand SrcPtr = Op.getOperand(1);
+  SDOperand SrcSV = Op.getOperand(2);
+
+  assert(0 && "VAArgInst is not yet implemented for x86-64!");
+  abort();
+  return SDOperand();
+}
+
 SDOperand X86TargetLowering::LowerVACOPY(SDOperand Op, SelectionDAG &DAG) {
   // X86-64 va_list is a struct { i32, i32, i8*, i8* }.
+  assert(Subtarget->is64Bit() && "This code only handles 64-bit va_copy!");
   SDOperand Chain = Op.getOperand(0);
   SDOperand DstPtr = Op.getOperand(1);
   SDOperand SrcPtr = Op.getOperand(2);
   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, 0);
-  Chain = SrcPtr.getValue(1);
-  for (unsigned i = 0; i < 3; ++i) {
-    SDOperand Val = DAG.getLoad(MVT::i64, Chain, SrcPtr, SrcSV, 0);
-    Chain = Val.getValue(1);
-    Chain = DAG.getStore(Chain, Val, DstPtr, DstSV, 0);
-    if (i == 2)
-      break;
-    SrcPtr = DAG.getNode(ISD::ADD, getPointerTy(), SrcPtr, 
-                         DAG.getIntPtrConstant(8));
-    DstPtr = DAG.getNode(ISD::ADD, getPointerTy(), DstPtr, 
-                         DAG.getIntPtrConstant(8));
-  }
-  return Chain;
+  return DAG.getMemcpy(Chain, DstPtr, SrcPtr,
+                       DAG.getIntPtrConstant(24), 8, false,
+                       DstSV, 0, SrcSV, 0);
 }
 
 SDOperand
@@ -4937,7 +5156,7 @@ X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG) {
   unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getValue();
   switch (IntNo) {
   default: return SDOperand();    // Don't custom lower most intrinsics.
-    // Comparison intrinsics.
+  // Comparison intrinsics.
   case Intrinsic::x86_sse_comieq_ss:
   case Intrinsic::x86_sse_comilt_ss:
   case Intrinsic::x86_sse_comile_ss:
@@ -5038,6 +5257,95 @@ X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDOperand Op, SelectionDAG &DAG) {
                                   DAG.getConstant(X86CC, MVT::i8), Cond);
     return DAG.getNode(ISD::ANY_EXTEND, MVT::i32, SetCC);
   }
+
+  // Fix vector shift instructions where the last operand is a non-immediate
+  // i32 value.
+  case Intrinsic::x86_sse2_pslli_w:
+  case Intrinsic::x86_sse2_pslli_d:
+  case Intrinsic::x86_sse2_pslli_q:
+  case Intrinsic::x86_sse2_psrli_w:
+  case Intrinsic::x86_sse2_psrli_d:
+  case Intrinsic::x86_sse2_psrli_q:
+  case Intrinsic::x86_sse2_psrai_w:
+  case Intrinsic::x86_sse2_psrai_d:
+  case Intrinsic::x86_mmx_pslli_w:
+  case Intrinsic::x86_mmx_pslli_d:
+  case Intrinsic::x86_mmx_pslli_q:
+  case Intrinsic::x86_mmx_psrli_w:
+  case Intrinsic::x86_mmx_psrli_d:
+  case Intrinsic::x86_mmx_psrli_q:
+  case Intrinsic::x86_mmx_psrai_w:
+  case Intrinsic::x86_mmx_psrai_d: {
+    SDOperand ShAmt = Op.getOperand(2);
+    if (isa<ConstantSDNode>(ShAmt))
+      return SDOperand();
+
+    unsigned NewIntNo = 0;
+    MVT ShAmtVT = MVT::v4i32;
+    switch (IntNo) {
+    case Intrinsic::x86_sse2_pslli_w:
+      NewIntNo = Intrinsic::x86_sse2_psll_w;
+      break;
+    case Intrinsic::x86_sse2_pslli_d:
+      NewIntNo = Intrinsic::x86_sse2_psll_d;
+      break;
+    case Intrinsic::x86_sse2_pslli_q:
+      NewIntNo = Intrinsic::x86_sse2_psll_q;
+      break;
+    case Intrinsic::x86_sse2_psrli_w:
+      NewIntNo = Intrinsic::x86_sse2_psrl_w;
+      break;
+    case Intrinsic::x86_sse2_psrli_d:
+      NewIntNo = Intrinsic::x86_sse2_psrl_d;
+      break;
+    case Intrinsic::x86_sse2_psrli_q:
+      NewIntNo = Intrinsic::x86_sse2_psrl_q;
+      break;
+    case Intrinsic::x86_sse2_psrai_w:
+      NewIntNo = Intrinsic::x86_sse2_psra_w;
+      break;
+    case Intrinsic::x86_sse2_psrai_d:
+      NewIntNo = Intrinsic::x86_sse2_psra_d;
+      break;
+    default: {
+      ShAmtVT = MVT::v2i32;
+      switch (IntNo) {
+      case Intrinsic::x86_mmx_pslli_w:
+        NewIntNo = Intrinsic::x86_mmx_psll_w;
+        break;
+      case Intrinsic::x86_mmx_pslli_d:
+        NewIntNo = Intrinsic::x86_mmx_psll_d;
+        break;
+      case Intrinsic::x86_mmx_pslli_q:
+        NewIntNo = Intrinsic::x86_mmx_psll_q;
+        break;
+      case Intrinsic::x86_mmx_psrli_w:
+        NewIntNo = Intrinsic::x86_mmx_psrl_w;
+        break;
+      case Intrinsic::x86_mmx_psrli_d:
+        NewIntNo = Intrinsic::x86_mmx_psrl_d;
+        break;
+      case Intrinsic::x86_mmx_psrli_q:
+        NewIntNo = Intrinsic::x86_mmx_psrl_q;
+        break;
+      case Intrinsic::x86_mmx_psrai_w:
+        NewIntNo = Intrinsic::x86_mmx_psra_w;
+        break;
+      case Intrinsic::x86_mmx_psrai_d:
+        NewIntNo = Intrinsic::x86_mmx_psra_d;
+        break;
+      default: abort();  // Can't reach here.
+      }
+      break;
+    }
+    }
+    MVT VT = Op.getValueType();
+    ShAmt = DAG.getNode(ISD::BIT_CONVERT, VT,
+                        DAG.getNode(ISD::SCALAR_TO_VECTOR, ShAmtVT, ShAmt));
+    return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT,
+                       DAG.getConstant(NewIntNo, MVT::i32),
+                       Op.getOperand(1), ShAmt);
+  }
   }
 }
 
@@ -5114,10 +5422,8 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
     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 N86R10 = RegInfo->getX86RegNum(X86::R10);
+    const unsigned char N86R11 = RegInfo->getX86RegNum(X86::R11);
 
     const unsigned char REX_WB = 0x40 | 0x08 | 0x01; // REX prefix
 
@@ -5171,15 +5477,15 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
 
       // Check that ECX wasn't needed by an 'inreg' parameter.
       const FunctionType *FTy = Func->getFunctionType();
-      const ParamAttrsList *Attrs = Func->getParamAttrs();
+      const PAListPtr &Attrs = Func->getParamAttrs();
 
-      if (Attrs && !Func->isVarArg()) {
+      if (!Attrs.isEmpty() && !Func->isVarArg()) {
         unsigned InRegCount = 0;
         unsigned Idx = 1;
 
         for (FunctionType::param_iterator I = FTy->param_begin(),
              E = FTy->param_end(); I != E; ++I, ++Idx)
-          if (Attrs->paramHasAttr(Idx, ParamAttr::InReg))
+          if (Attrs.paramHasAttr(Idx, ParamAttr::InReg))
             // FIXME: should only count parameters that are lowered to integers.
             InRegCount += (getTargetData()->getTypeSizeInBits(*I) + 31) / 32;
 
@@ -5204,8 +5510,7 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
     Disp = DAG.getNode(ISD::SUB, MVT::i32, FPtr, Addr);
 
     const unsigned char MOV32ri = TII->getBaseOpcodeFor(X86::MOV32ri);
-    const unsigned char N86Reg =
-      ((const X86RegisterInfo*)RegInfo)->getX86RegNum(NestReg);
+    const unsigned char N86Reg = RegInfo->getX86RegNum(NestReg);
     OutChains[0] = DAG.getStore(Root, DAG.getConstant(MOV32ri|N86Reg, MVT::i8),
                                 Trmp, TrmpAddr, 0);
 
@@ -5250,7 +5555,7 @@ SDOperand X86TargetLowering::LowerFLT_ROUNDS_(SDOperand Op, SelectionDAG &DAG) {
   const TargetMachine &TM = MF.getTarget();
   const TargetFrameInfo &TFI = *TM.getFrameInfo();
   unsigned StackAlignment = TFI.getStackAlignment();
-  MVT::ValueType VT = Op.getValueType();
+  MVT VT = Op.getValueType();
 
   // Save FP Control Word to stack slot
   int SSFI = MF.getFrameInfo()->CreateStackObject(2, StackAlignment);
@@ -5282,14 +5587,14 @@ SDOperand X86TargetLowering::LowerFLT_ROUNDS_(SDOperand Op, SelectionDAG &DAG) {
                 DAG.getConstant(3, MVT::i16));
 
 
-  return DAG.getNode((MVT::getSizeInBits(VT) < 16 ?
+  return DAG.getNode((VT.getSizeInBits() < 16 ?
                       ISD::TRUNCATE : ISD::ZERO_EXTEND), VT, RetVal);
 }
 
 SDOperand X86TargetLowering::LowerCTLZ(SDOperand Op, SelectionDAG &DAG) {
-  MVT::ValueType VT = Op.getValueType();
-  MVT::ValueType OpVT = VT;
-  unsigned NumBits = MVT::getSizeInBits(VT);
+  MVT VT = Op.getValueType();
+  MVT OpVT = VT;
+  unsigned NumBits = VT.getSizeInBits();
 
   Op = Op.getOperand(0);
   if (VT == MVT::i8) {
@@ -5319,9 +5624,9 @@ SDOperand X86TargetLowering::LowerCTLZ(SDOperand Op, SelectionDAG &DAG) {
 }
 
 SDOperand X86TargetLowering::LowerCTTZ(SDOperand Op, SelectionDAG &DAG) {
-  MVT::ValueType VT = Op.getValueType();
-  MVT::ValueType OpVT = VT;
-  unsigned NumBits = MVT::getSizeInBits(VT);
+  MVT VT = Op.getValueType();
+  MVT OpVT = VT;
+  unsigned NumBits = VT.getSizeInBits();
 
   Op = Op.getOperand(0);
   if (VT == MVT::i8) {
@@ -5346,11 +5651,88 @@ SDOperand X86TargetLowering::LowerCTTZ(SDOperand Op, SelectionDAG &DAG) {
   return Op;
 }
 
+SDOperand X86TargetLowering::LowerLCS(SDOperand Op, SelectionDAG &DAG) {
+  MVT T = cast<AtomicSDNode>(Op.Val)->getVT();
+  unsigned Reg = 0;
+  unsigned size = 0;
+  switch(T.getSimpleVT()) {
+  default:
+    assert(false && "Invalid value type!");
+  case MVT::i8:  Reg = X86::AL;  size = 1; break;
+  case MVT::i16: Reg = X86::AX;  size = 2; break;
+  case MVT::i32: Reg = X86::EAX; size = 4; break;
+  case MVT::i64: 
+    if (Subtarget->is64Bit()) {
+      Reg = X86::RAX; size = 8;
+    } else //Should go away when LowerType stuff lands
+      return SDOperand(ExpandATOMIC_LCS(Op.Val, DAG), 0);
+    break;
+  };
+  SDOperand cpIn = DAG.getCopyToReg(Op.getOperand(0), Reg,
+                                    Op.getOperand(3), SDOperand());
+  SDOperand Ops[] = { cpIn.getValue(0),
+                      Op.getOperand(1),
+                      Op.getOperand(2),
+                      DAG.getTargetConstant(size, MVT::i8),
+                      cpIn.getValue(1) };
+  SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
+  SDOperand Result = DAG.getNode(X86ISD::LCMPXCHG_DAG, Tys, Ops, 5);
+  SDOperand cpOut = 
+    DAG.getCopyFromReg(Result.getValue(0), Reg, T, Result.getValue(1));
+  return cpOut;
+}
+
+SDNode* X86TargetLowering::ExpandATOMIC_LCS(SDNode* Op, SelectionDAG &DAG) {
+  MVT T = cast<AtomicSDNode>(Op)->getVT();
+  assert (T == MVT::i64 && "Only know how to expand i64 CAS");
+  SDOperand cpInL, cpInH;
+  cpInL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(3),
+                      DAG.getConstant(0, MVT::i32));
+  cpInH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(3),
+                      DAG.getConstant(1, MVT::i32));
+  cpInL = DAG.getCopyToReg(Op->getOperand(0), X86::EAX,
+                           cpInL, SDOperand());
+  cpInH = DAG.getCopyToReg(cpInL.getValue(0), X86::EDX,
+                           cpInH, cpInL.getValue(1));
+  SDOperand swapInL, swapInH;
+  swapInL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(2),
+                        DAG.getConstant(0, MVT::i32));
+  swapInH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(2),
+                        DAG.getConstant(1, MVT::i32));
+  swapInL = DAG.getCopyToReg(cpInH.getValue(0), X86::EBX,
+                             swapInL, cpInH.getValue(1));
+  swapInH = DAG.getCopyToReg(swapInL.getValue(0), X86::ECX,
+                             swapInH, swapInL.getValue(1));
+  SDOperand Ops[] = { swapInH.getValue(0),
+                      Op->getOperand(1),
+                      swapInH.getValue(1)};
+  SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
+  SDOperand Result = DAG.getNode(X86ISD::LCMPXCHG8_DAG, Tys, Ops, 3);
+  SDOperand cpOutL = DAG.getCopyFromReg(Result.getValue(0), X86::EAX, MVT::i32, 
+                                        Result.getValue(1));
+  SDOperand cpOutH = DAG.getCopyFromReg(cpOutL.getValue(1), X86::EDX, MVT::i32, 
+                                        cpOutL.getValue(2));
+  SDOperand OpsF[] = { cpOutL.getValue(0), cpOutH.getValue(0)};
+  SDOperand ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OpsF, 2);
+  Tys = DAG.getVTList(MVT::i64, MVT::Other);
+  return DAG.getNode(ISD::MERGE_VALUES, Tys, ResultVal, cpOutH.getValue(1)).Val;
+}
+
+SDNode* X86TargetLowering::ExpandATOMIC_LSS(SDNode* Op, SelectionDAG &DAG) {
+  MVT T = cast<AtomicSDNode>(Op)->getVT();
+  assert (T == MVT::i32 && "Only know how to expand i32 LSS");
+  SDOperand negOp = DAG.getNode(ISD::SUB, T,
+                                DAG.getConstant(0, T), Op->getOperand(2));
+  return DAG.getAtomic(ISD::ATOMIC_LAS, Op->getOperand(0),
+                       Op->getOperand(1), negOp, T).Val;
+}
+
 /// LowerOperation - Provide custom lowering hooks for some operations.
 ///
 SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   switch (Op.getOpcode()) {
   default: assert(0 && "Should not custom lower this!");
+  case ISD::ATOMIC_LCS:         return LowerLCS(Op,DAG);
   case ISD::BUILD_VECTOR:       return LowerBUILD_VECTOR(Op, DAG);
   case ISD::VECTOR_SHUFFLE:     return LowerVECTOR_SHUFFLE(Op, DAG);
   case ISD::EXTRACT_VECTOR_ELT: return LowerEXTRACT_VECTOR_ELT(Op, DAG);
@@ -5375,9 +5757,8 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   case ISD::CALL:               return LowerCALL(Op, DAG);
   case ISD::RET:                return LowerRET(Op, DAG);
   case ISD::FORMAL_ARGUMENTS:   return LowerFORMAL_ARGUMENTS(Op, DAG);
-  case ISD::MEMSET:             return LowerMEMSET(Op, DAG);
-  case ISD::MEMCPY:             return LowerMEMCPY(Op, DAG);
   case ISD::VASTART:            return LowerVASTART(Op, DAG);
+  case ISD::VAARG:              return LowerVAARG(Op, DAG);
   case ISD::VACOPY:             return LowerVACOPY(Op, DAG);
   case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
   case ISD::RETURNADDR:         return LowerRETURNADDR(Op, DAG);
@@ -5403,6 +5784,8 @@ SDNode *X86TargetLowering::ExpandOperationResult(SDNode *N, SelectionDAG &DAG) {
   default: assert(0 && "Should not custom lower this!");
   case ISD::FP_TO_SINT:         return ExpandFP_TO_SINT(N, DAG);
   case ISD::READCYCLECOUNTER:   return ExpandREADCYCLECOUNTER(N, DAG);
+  case ISD::ATOMIC_LCS:         return ExpandATOMIC_LCS(N, DAG);
+  case ISD::ATOMIC_LSS:         return ExpandATOMIC_LSS(N,DAG);
   }
 }
 
@@ -5424,9 +5807,6 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
   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_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";
   case X86ISD::RDTSC_DAG:          return "X86ISD::RDTSC_DAG";
@@ -5455,6 +5835,12 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
   case X86ISD::EH_RETURN:          return "X86ISD::EH_RETURN";
   case X86ISD::TC_RETURN:          return "X86ISD::TC_RETURN";
   case X86ISD::FNSTCW16m:          return "X86ISD::FNSTCW16m";
+  case X86ISD::LCMPXCHG_DAG:       return "X86ISD::LCMPXCHG_DAG";
+  case X86ISD::LCMPXCHG8_DAG:      return "X86ISD::LCMPXCHG8_DAG";
+  case X86ISD::VZEXT_MOVL:         return "X86ISD::VZEXT_MOVL";
+  case X86ISD::VZEXT_LOAD:         return "X86ISD::VZEXT_LOAD";
+  case X86ISD::VSHL:               return "X86ISD::VSHL";
+  case X86ISD::VSRL:               return "X86ISD::VSRL";
   }
 }
 
@@ -5517,12 +5903,11 @@ bool X86TargetLowering::isTruncateFree(const Type *Ty1, const Type *Ty2) const {
   return Subtarget->is64Bit() || NumBits1 < 64;
 }
 
-bool X86TargetLowering::isTruncateFree(MVT::ValueType VT1,
-                                       MVT::ValueType VT2) const {
-  if (!MVT::isInteger(VT1) || !MVT::isInteger(VT2))
+bool X86TargetLowering::isTruncateFree(MVT VT1, MVT VT2) const {
+  if (!VT1.isInteger() || !VT2.isInteger())
     return false;
-  unsigned NumBits1 = MVT::getSizeInBits(VT1);
-  unsigned NumBits2 = MVT::getSizeInBits(VT2);
+  unsigned NumBits1 = VT1.getSizeInBits();
+  unsigned NumBits2 = VT2.getSizeInBits();
   if (NumBits1 <= NumBits2)
     return false;
   return Subtarget->is64Bit() || NumBits1 < 64;
@@ -5533,9 +5918,9 @@ bool X86TargetLowering::isTruncateFree(MVT::ValueType VT1,
 /// By default, if a target supports the VECTOR_SHUFFLE node, all mask values
 /// are assumed to be legal.
 bool
-X86TargetLowering::isShuffleMaskLegal(SDOperand Mask, MVT::ValueType VT) const {
+X86TargetLowering::isShuffleMaskLegal(SDOperand Mask, MVT VT) const {
   // Only do shuffles on 128-bit vector types for now.
-  if (MVT::getSizeInBits(VT) == 64) return false;
+  if (VT.getSizeInBits() == 64) return false;
   return (Mask.Val->getNumOperands() <= 4 ||
           isIdentityMask(Mask.Val) ||
           isIdentityMask(Mask.Val, true) ||
@@ -5547,12 +5932,12 @@ X86TargetLowering::isShuffleMaskLegal(SDOperand Mask, MVT::ValueType VT) const {
           X86::isUNPCKH_v_undef_Mask(Mask.Val));
 }
 
-bool X86TargetLowering::isVectorClearMaskLegal(std::vector<SDOperand> &BVOps,
-                                               MVT::ValueType EVT,
-                                               SelectionDAG &DAG) const {
+bool
+X86TargetLowering::isVectorClearMaskLegal(const std::vector<SDOperand> &BVOps,
+                                          MVT EVT, SelectionDAG &DAG) const {
   unsigned NumElts = BVOps.size();
   // Only do shuffles on 128-bit vector types for now.
-  if (MVT::getSizeInBits(EVT) * NumElts == 64) return false;
+  if (EVT.getSizeInBits() * NumElts == 64) return false;
   if (NumElts == 2) return true;
   if (NumElts == 4) {
     return (isMOVLMask(&BVOps[0], 4)  ||
@@ -5567,6 +5952,195 @@ bool X86TargetLowering::isVectorClearMaskLegal(std::vector<SDOperand> &BVOps,
 //                           X86 Scheduler Hooks
 //===----------------------------------------------------------------------===//
 
+// private utility function
+MachineBasicBlock *
+X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr,
+                                                       MachineBasicBlock *MBB,
+                                                       unsigned regOpc,
+                                                       unsigned immOpc,
+                                                       bool invSrc) {
+  // For the atomic bitwise operator, we generate
+  //   thisMBB:
+  //   newMBB:
+  //     ld  t1 = [bitinstr.addr]
+  //     op  t2 = t1, [bitinstr.val]
+  //     mov EAX = t1
+  //     lcs dest = [bitinstr.addr], t2  [EAX is implicit]
+  //     bz  newMBB
+  //     fallthrough -->nextMBB
+  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
+  const BasicBlock *LLVM_BB = MBB->getBasicBlock();
+  ilist<MachineBasicBlock>::iterator MBBIter = MBB;
+  ++MBBIter;
+  
+  /// First build the CFG
+  MachineFunction *F = MBB->getParent();
+  MachineBasicBlock *thisMBB = MBB;
+  MachineBasicBlock *newMBB = new MachineBasicBlock(LLVM_BB);
+  MachineBasicBlock *nextMBB = new MachineBasicBlock(LLVM_BB);
+  F->getBasicBlockList().insert(MBBIter, newMBB);
+  F->getBasicBlockList().insert(MBBIter, nextMBB);
+  
+  // Move all successors to thisMBB to nextMBB
+  nextMBB->transferSuccessors(thisMBB);
+    
+  // Update thisMBB to fall through to newMBB
+  thisMBB->addSuccessor(newMBB);
+  
+  // newMBB jumps to itself and fall through to nextMBB
+  newMBB->addSuccessor(nextMBB);
+  newMBB->addSuccessor(newMBB);
+  
+  // Insert instructions into newMBB based on incoming instruction
+  assert(bInstr->getNumOperands() < 8 && "unexpected number of operands");
+  MachineOperand& destOper = bInstr->getOperand(0);
+  MachineOperand* argOpers[6];
+  int numArgs = bInstr->getNumOperands() - 1;
+  for (int i=0; i < numArgs; ++i)
+    argOpers[i] = &bInstr->getOperand(i+1);
+
+  // x86 address has 4 operands: base, index, scale, and displacement
+  int lastAddrIndx = 3; // [0,3]
+  int valArgIndx = 4;
+  
+  unsigned t1 = F->getRegInfo().createVirtualRegister(X86::GR32RegisterClass);
+  MachineInstrBuilder MIB = BuildMI(newMBB, TII->get(X86::MOV32rm), t1);
+  for (int i=0; i <= lastAddrIndx; ++i)
+    (*MIB).addOperand(*argOpers[i]);
+
+  unsigned tt = F->getRegInfo().createVirtualRegister(X86::GR32RegisterClass);
+  if (invSrc) {
+    MIB = BuildMI(newMBB, TII->get(X86::NOT32r), tt).addReg(t1);
+  }
+  else 
+    tt = t1;
+
+  unsigned t2 = F->getRegInfo().createVirtualRegister(X86::GR32RegisterClass);
+  assert(   (argOpers[valArgIndx]->isReg() || argOpers[valArgIndx]->isImm())
+         && "invalid operand");
+  if (argOpers[valArgIndx]->isReg())
+    MIB = BuildMI(newMBB, TII->get(regOpc), t2);
+  else
+    MIB = BuildMI(newMBB, TII->get(immOpc), t2);
+  MIB.addReg(tt);
+  (*MIB).addOperand(*argOpers[valArgIndx]);
+
+  MIB = BuildMI(newMBB, TII->get(X86::MOV32rr), X86::EAX);
+  MIB.addReg(t1);
+  
+  MIB = BuildMI(newMBB, TII->get(X86::LCMPXCHG32));
+  for (int i=0; i <= lastAddrIndx; ++i)
+    (*MIB).addOperand(*argOpers[i]);
+  MIB.addReg(t2);
+  
+  MIB = BuildMI(newMBB, TII->get(X86::MOV32rr), destOper.getReg());
+  MIB.addReg(X86::EAX);
+  
+  // insert branch
+  BuildMI(newMBB, TII->get(X86::JNE)).addMBB(newMBB);
+
+  delete bInstr;   // The pseudo instruction is gone now.
+  return nextMBB;
+}
+
+// private utility function
+MachineBasicBlock *
+X86TargetLowering::EmitAtomicMinMaxWithCustomInserter(MachineInstr *mInstr,
+                                                      MachineBasicBlock *MBB,
+                                                      unsigned cmovOpc) {
+  // For the atomic min/max operator, we generate
+  //   thisMBB:
+  //   newMBB:
+  //     ld t1 = [min/max.addr]
+  //     mov t2 = [min/max.val] 
+  //     cmp  t1, t2
+  //     cmov[cond] t2 = t1
+  //     mov EAX = t1
+  //     lcs dest = [bitinstr.addr], t2  [EAX is implicit]
+  //     bz   newMBB
+  //     fallthrough -->nextMBB
+  //
+  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
+  const BasicBlock *LLVM_BB = MBB->getBasicBlock();
+  ilist<MachineBasicBlock>::iterator MBBIter = MBB;
+  ++MBBIter;
+  
+  /// First build the CFG
+  MachineFunction *F = MBB->getParent();
+  MachineBasicBlock *thisMBB = MBB;
+  MachineBasicBlock *newMBB = new MachineBasicBlock(LLVM_BB);
+  MachineBasicBlock *nextMBB = new MachineBasicBlock(LLVM_BB);
+  F->getBasicBlockList().insert(MBBIter, newMBB);
+  F->getBasicBlockList().insert(MBBIter, nextMBB);
+  
+  // Move all successors to thisMBB to nextMBB
+  nextMBB->transferSuccessors(thisMBB);
+  
+  // Update thisMBB to fall through to newMBB
+  thisMBB->addSuccessor(newMBB);
+  
+  // newMBB jumps to newMBB and fall through to nextMBB
+  newMBB->addSuccessor(nextMBB);
+  newMBB->addSuccessor(newMBB);
+  
+  // Insert instructions into newMBB based on incoming instruction
+  assert(mInstr->getNumOperands() < 8 && "unexpected number of operands");
+  MachineOperand& destOper = mInstr->getOperand(0);
+  MachineOperand* argOpers[6];
+  int numArgs = mInstr->getNumOperands() - 1;
+  for (int i=0; i < numArgs; ++i)
+    argOpers[i] = &mInstr->getOperand(i+1);
+  
+  // x86 address has 4 operands: base, index, scale, and displacement
+  int lastAddrIndx = 3; // [0,3]
+  int valArgIndx = 4;
+  
+  unsigned t1 = F->getRegInfo().createVirtualRegister(X86::GR32RegisterClass);
+  MachineInstrBuilder MIB = BuildMI(newMBB, TII->get(X86::MOV32rm), t1);
+  for (int i=0; i <= lastAddrIndx; ++i)
+    (*MIB).addOperand(*argOpers[i]);
+
+  // We only support register and immediate values
+  assert(   (argOpers[valArgIndx]->isReg() || argOpers[valArgIndx]->isImm())
+         && "invalid operand");
+  
+  unsigned t2 = F->getRegInfo().createVirtualRegister(X86::GR32RegisterClass);  
+  if (argOpers[valArgIndx]->isReg())
+    MIB = BuildMI(newMBB, TII->get(X86::MOV32rr), t2);
+  else 
+    MIB = BuildMI(newMBB, TII->get(X86::MOV32rr), t2);
+  (*MIB).addOperand(*argOpers[valArgIndx]);
+
+  MIB = BuildMI(newMBB, TII->get(X86::MOV32rr), X86::EAX);
+  MIB.addReg(t1);
+
+  MIB = BuildMI(newMBB, TII->get(X86::CMP32rr));
+  MIB.addReg(t1);
+  MIB.addReg(t2);
+
+  // Generate movc
+  unsigned t3 = F->getRegInfo().createVirtualRegister(X86::GR32RegisterClass);
+  MIB = BuildMI(newMBB, TII->get(cmovOpc),t3);
+  MIB.addReg(t2);
+  MIB.addReg(t1);
+
+  // Cmp and exchange if none has modified the memory location
+  MIB = BuildMI(newMBB, TII->get(X86::LCMPXCHG32));
+  for (int i=0; i <= lastAddrIndx; ++i)
+    (*MIB).addOperand(*argOpers[i]);
+  MIB.addReg(t3);
+  
+  MIB = BuildMI(newMBB, TII->get(X86::MOV32rr), destOper.getReg());
+  MIB.addReg(X86::EAX);
+  
+  // insert branch
+  BuildMI(newMBB, TII->get(X86::JNE)).addMBB(newMBB);
+
+  delete mInstr;   // The pseudo instruction is gone now.
+  return nextMBB;
+}
+
+
 MachineBasicBlock *
 X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
                                                MachineBasicBlock *BB) {
@@ -5601,15 +6175,11 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
     MachineFunction *F = BB->getParent();
     F->getBasicBlockList().insert(It, copy0MBB);
     F->getBasicBlockList().insert(It, sinkMBB);
-    // Update machine-CFG edges by first adding all successors of the current
+    // Update machine-CFG edges by transferring all successors of the current
     // block to the new block which will contain the Phi node for the select.
-    for(MachineBasicBlock::succ_iterator i = BB->succ_begin(),
-        e = BB->succ_end(); i != e; ++i)
-      sinkMBB->addSuccessor(*i);
-    // Next, remove all successors of the current block, and add the true
-    // and fallthrough blocks as its successors.
-    while(!BB->succ_empty())
-      BB->removeSuccessor(BB->succ_begin());
+    sinkMBB->transferSuccessors(BB);
+
+    // Add the true and fallthrough blocks as its successors.
     BB->addSuccessor(copy0MBB);
     BB->addSuccessor(sinkMBB);
 
@@ -5709,6 +6279,26 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
     delete MI;   // The pseudo instruction is gone now.
     return BB;
   }
+  case X86::ATOMAND32:
+    return EmitAtomicBitwiseWithCustomInserter(MI, BB, X86::AND32rr,
+                                                       X86::AND32ri);
+  case X86::ATOMOR32:
+    return EmitAtomicBitwiseWithCustomInserter(MI, BB, X86::OR32rr, 
+                                                       X86::OR32ri);
+  case X86::ATOMXOR32:
+    return EmitAtomicBitwiseWithCustomInserter(MI, BB, X86::XOR32rr,
+                                                       X86::XOR32ri);
+  case X86::ATOMNAND32:
+    return EmitAtomicBitwiseWithCustomInserter(MI, BB, X86::AND32rr,
+                                               X86::AND32ri, true);
+  case X86::ATOMMIN32:
+    return EmitAtomicMinMaxWithCustomInserter(MI, BB, X86::CMOVL32rr);
+  case X86::ATOMMAX32:
+    return EmitAtomicMinMaxWithCustomInserter(MI, BB, X86::CMOVG32rr);
+  case X86::ATOMUMIN32:
+    return EmitAtomicMinMaxWithCustomInserter(MI, BB, X86::CMOVB32rr);
+  case X86::ATOMUMAX32:
+    return EmitAtomicMinMaxWithCustomInserter(MI, BB, X86::CMOVA32rr);
   }
 }
 
@@ -5740,140 +6330,131 @@ void X86TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
   }
 }
 
-/// getShuffleScalarElt - Returns the scalar element that will make up the ith
-/// element of the result of the vector shuffle.
-static SDOperand getShuffleScalarElt(SDNode *N, unsigned i, SelectionDAG &DAG) {
-  MVT::ValueType VT = N->getValueType(0);
-  SDOperand PermMask = N->getOperand(2);
-  unsigned NumElems = PermMask.getNumOperands();
-  SDOperand V = (i < NumElems) ? N->getOperand(0) : N->getOperand(1);
-  i %= NumElems;
-  if (V.getOpcode() == ISD::SCALAR_TO_VECTOR) {
-    return (i == 0)
-     ? V.getOperand(0) : DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(VT));
-  } else if (V.getOpcode() == ISD::VECTOR_SHUFFLE) {
-    SDOperand Idx = PermMask.getOperand(i);
-    if (Idx.getOpcode() == ISD::UNDEF)
-      return DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(VT));
-    return getShuffleScalarElt(V.Val,cast<ConstantSDNode>(Idx)->getValue(),DAG);
-  }
-  return SDOperand();
-}
-
 /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
-/// node is a GlobalAddress + an offset.
-static bool isGAPlusOffset(SDNode *N, GlobalValue* &GA, int64_t &Offset) {
-  unsigned Opc = N->getOpcode();
-  if (Opc == X86ISD::Wrapper) {
-    if (dyn_cast<GlobalAddressSDNode>(N->getOperand(0))) {
+/// node is a GlobalAddress + offset.
+bool X86TargetLowering::isGAPlusOffset(SDNode *N,
+                                       GlobalValue* &GA, int64_t &Offset) const{
+  if (N->getOpcode() == X86ISD::Wrapper) {
+    if (isa<GlobalAddressSDNode>(N->getOperand(0))) {
       GA = cast<GlobalAddressSDNode>(N->getOperand(0))->getGlobal();
       return true;
     }
-  } else if (Opc == ISD::ADD) {
-    SDOperand N1 = N->getOperand(0);
-    SDOperand N2 = N->getOperand(1);
-    if (isGAPlusOffset(N1.Val, GA, Offset)) {
-      ConstantSDNode *V = dyn_cast<ConstantSDNode>(N2);
-      if (V) {
-        Offset += V->getSignExtended();
-        return true;
-      }
-    } else if (isGAPlusOffset(N2.Val, GA, Offset)) {
-      ConstantSDNode *V = dyn_cast<ConstantSDNode>(N1);
-      if (V) {
-        Offset += V->getSignExtended();
-        return true;
-      }
-    }
-  }
-  return false;
-}
-
-/// isConsecutiveLoad - Returns true if N is loading from an address of Base
-/// + Dist * Size.
-static bool isConsecutiveLoad(SDNode *N, SDNode *Base, int Dist, int Size,
-                              MachineFrameInfo *MFI) {
-  if (N->getOperand(0).Val != Base->getOperand(0).Val)
-    return false;
-
-  SDOperand Loc = N->getOperand(1);
-  SDOperand BaseLoc = Base->getOperand(1);
-  if (Loc.getOpcode() == ISD::FrameIndex) {
-    if (BaseLoc.getOpcode() != ISD::FrameIndex)
-      return false;
-    int FI  = cast<FrameIndexSDNode>(Loc)->getIndex();
-    int BFI = cast<FrameIndexSDNode>(BaseLoc)->getIndex();
-    int FS  = MFI->getObjectSize(FI);
-    int BFS = MFI->getObjectSize(BFI);
-    if (FS != BFS || FS != Size) return false;
-    return MFI->getObjectOffset(FI) == (MFI->getObjectOffset(BFI) + Dist*Size);
-  } else {
-    GlobalValue *GV1 = NULL;
-    GlobalValue *GV2 = NULL;
-    int64_t Offset1 = 0;
-    int64_t Offset2 = 0;
-    bool isGA1 = isGAPlusOffset(Loc.Val, GV1, Offset1);
-    bool isGA2 = isGAPlusOffset(BaseLoc.Val, GV2, Offset2);
-    if (isGA1 && isGA2 && GV1 == GV2)
-      return Offset1 == (Offset2 + Dist*Size);
   }
-
-  return false;
+  return TargetLowering::isGAPlusOffset(N, GA, Offset);
 }
 
-static bool isBaseAlignment16(SDNode *Base, MachineFrameInfo *MFI,
-                              const X86Subtarget *Subtarget) {
+static bool isBaseAlignmentOfN(unsigned N, SDNode *Base,
+                               const TargetLowering &TLI) {
   GlobalValue *GV;
   int64_t Offset = 0;
-  if (isGAPlusOffset(Base, GV, Offset))
-    return (GV->getAlignment() >= 16 && (Offset % 16) == 0);
+  if (TLI.isGAPlusOffset(Base, GV, Offset))
+    return (GV->getAlignment() >= N && (Offset % N) == 0);
   // DAG combine handles the stack object case.
   return false;
 }
 
+static bool EltsFromConsecutiveLoads(SDNode *N, SDOperand PermMask,
+                                     unsigned NumElems, MVT EVT,
+                                     SDNode *&Base,
+                                     SelectionDAG &DAG, MachineFrameInfo *MFI,
+                                     const TargetLowering &TLI) {
+  Base = NULL;
+  for (unsigned i = 0; i < NumElems; ++i) {
+    SDOperand Idx = PermMask.getOperand(i);
+    if (Idx.getOpcode() == ISD::UNDEF) {
+      if (!Base)
+        return false;
+      continue;
+    }
+
+    unsigned Index = cast<ConstantSDNode>(Idx)->getValue();
+    SDOperand Elt = DAG.getShuffleScalarElt(N, Index);
+    if (!Elt.Val ||
+        (Elt.getOpcode() != ISD::UNDEF && !ISD::isNON_EXTLoad(Elt.Val)))
+      return false;
+    if (!Base) {
+      Base = Elt.Val;
+      if (Base->getOpcode() == ISD::UNDEF)
+        return false;
+      continue;
+    }
+    if (Elt.getOpcode() == ISD::UNDEF)
+      continue;
+
+    if (!TLI.isConsecutiveLoad(Elt.Val, Base,
+                               EVT.getSizeInBits()/8, i, MFI))
+      return false;
+  }
+  return true;
+}
 
 /// PerformShuffleCombine - Combine a vector_shuffle that is equal to
 /// build_vector load1, load2, load3, load4, <0, 1, 2, 3> into a 128-bit load
 /// if the load addresses are consecutive, non-overlapping, and in the right
 /// order.
 static SDOperand PerformShuffleCombine(SDNode *N, SelectionDAG &DAG,
-                                       const X86Subtarget *Subtarget) {
-  MachineFunction &MF = DAG.getMachineFunction();
-  MachineFrameInfo *MFI = MF.getFrameInfo();
-  MVT::ValueType VT = N->getValueType(0);
-  MVT::ValueType EVT = MVT::getVectorElementType(VT);
+                                       const TargetLowering &TLI) {
+  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
+  MVT VT = N->getValueType(0);
+  MVT EVT = VT.getVectorElementType();
   SDOperand PermMask = N->getOperand(2);
-  int NumElems = (int)PermMask.getNumOperands();
+  unsigned NumElems = PermMask.getNumOperands();
   SDNode *Base = NULL;
-  for (int i = 0; i < NumElems; ++i) {
-    SDOperand Idx = PermMask.getOperand(i);
-    if (Idx.getOpcode() == ISD::UNDEF) {
-      if (!Base) return SDOperand();
-    } else {
-      SDOperand Arg =
-        getShuffleScalarElt(N, cast<ConstantSDNode>(Idx)->getValue(), DAG);
-      if (!Arg.Val || !ISD::isNON_EXTLoad(Arg.Val))
-        return SDOperand();
-      if (!Base)
-        Base = Arg.Val;
-      else if (!isConsecutiveLoad(Arg.Val, Base,
-                                  i, MVT::getSizeInBits(EVT)/8,MFI))
-        return SDOperand();
-    }
-  }
+  if (!EltsFromConsecutiveLoads(N, PermMask, NumElems, EVT, Base,
+                                DAG, MFI, TLI))
+    return SDOperand();
 
-  bool isAlign16 = isBaseAlignment16(Base->getOperand(1).Val, MFI, Subtarget);
   LoadSDNode *LD = cast<LoadSDNode>(Base);
-  if (isAlign16) {
+  if (isBaseAlignmentOfN(16, Base->getOperand(1).Val, TLI))
     return DAG.getLoad(VT, LD->getChain(), LD->getBasePtr(), LD->getSrcValue(),
                        LD->getSrcValueOffset(), LD->isVolatile());
-  } else {
-    return DAG.getLoad(VT, LD->getChain(), LD->getBasePtr(), LD->getSrcValue(),
-                       LD->getSrcValueOffset(), LD->isVolatile(),
-                       LD->getAlignment());
-  }
+  return DAG.getLoad(VT, LD->getChain(), LD->getBasePtr(), LD->getSrcValue(),
+                     LD->getSrcValueOffset(), LD->isVolatile(),
+                     LD->getAlignment());
 }
 
+/// PerformBuildVectorCombine - build_vector 0,(load i64 / f64) -> movq / movsd.
+static SDOperand PerformBuildVectorCombine(SDNode *N, SelectionDAG &DAG,
+                                           const X86Subtarget *Subtarget,
+                                           const TargetLowering &TLI) {
+  unsigned NumOps = N->getNumOperands();
+
+  // Ignore single operand BUILD_VECTOR.
+  if (NumOps == 1)
+    return SDOperand();
+
+  MVT VT = N->getValueType(0);
+  MVT EVT = VT.getVectorElementType();
+  if ((EVT != MVT::i64 && EVT != MVT::f64) || Subtarget->is64Bit())
+    // We are looking for load i64 and zero extend. We want to transform
+    // it before legalizer has a chance to expand it. Also look for i64
+    // BUILD_PAIR bit casted to f64.
+    return SDOperand();
+  // This must be an insertion into a zero vector.
+  SDOperand HighElt = N->getOperand(1);
+  if (!isZeroNode(HighElt))
+    return SDOperand();
+
+  // Value must be a load.
+  SDNode *Base = N->getOperand(0).Val;
+  if (!isa<LoadSDNode>(Base)) {
+    if (Base->getOpcode() != ISD::BIT_CONVERT)
+      return SDOperand();
+    Base = Base->getOperand(0).Val;
+    if (!isa<LoadSDNode>(Base))
+      return SDOperand();
+  }
+
+  // Transform it into VZEXT_LOAD addr.
+  LoadSDNode *LD = cast<LoadSDNode>(Base);
+  
+  // Load must not be an extload.
+  if (LD->getExtensionType() != ISD::NON_EXTLOAD)
+    return SDOperand();
+  
+  return DAG.getNode(X86ISD::VZEXT_LOAD, VT, LD->getChain(), LD->getBasePtr());
+}                                           
+
 /// PerformSELECTCombine - Do target-specific dag combines on SELECT nodes.
 static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
                                       const X86Subtarget *Subtarget) {
@@ -5947,14 +6528,15 @@ static SDOperand PerformSELECTCombine(SDNode *N, SelectionDAG &DAG,
 }
 
 /// PerformSTORECombine - Do target-specific dag combines on STORE nodes.
-static SDOperand PerformSTORECombine(StoreSDNode *St, SelectionDAG &DAG,
+static SDOperand PerformSTORECombine(SDNode *N, SelectionDAG &DAG,
                                      const X86Subtarget *Subtarget) {
   // Turn load->store of MMX types into GPR load/stores.  This avoids clobbering
   // the FP state in cases where an emms may be missing.
   // A preferable solution to the general problem is to figure out the right
   // places to insert EMMS.  This qualifies as a quick hack.
-  if (MVT::isVector(St->getValue().getValueType()) && 
-      MVT::getSizeInBits(St->getValue().getValueType()) == 64 &&
+  StoreSDNode *St = cast<StoreSDNode>(N);
+  if (St->getValue().getValueType().isVector() &&
+      St->getValue().getValueType().getSizeInBits() == 64 &&
       isa<LoadSDNode>(St->getValue()) &&
       !cast<LoadSDNode>(St->getValue())->isVolatile() &&
       St->getChain().hasOneUse() && !St->isVolatile()) {
@@ -5987,7 +6569,7 @@ static SDOperand PerformSTORECombine(StoreSDNode *St, SelectionDAG &DAG,
                                       Ld->getAlignment());
         SDOperand NewChain = NewLd.getValue(1);
         if (TokenFactorIndex != -1) {
-          Ops.push_back(NewLd);
+          Ops.push_back(NewChain);
           NewChain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Ops[0], 
                                  Ops.size());
         }
@@ -5999,7 +6581,7 @@ static SDOperand PerformSTORECombine(StoreSDNode *St, SelectionDAG &DAG,
       // Otherwise, lower to two 32-bit copies.
       SDOperand LoAddr = Ld->getBasePtr();
       SDOperand HiAddr = DAG.getNode(ISD::ADD, MVT::i32, LoAddr,
-                                     DAG.getConstant(MVT::i32, 4));
+                                     DAG.getConstant(4, MVT::i32));
 
       SDOperand LoLd = DAG.getLoad(MVT::i32, Ld->getChain(), LoAddr,
                                    Ld->getSrcValue(), Ld->getSrcValueOffset(),
@@ -6019,7 +6601,7 @@ static SDOperand PerformSTORECombine(StoreSDNode *St, SelectionDAG &DAG,
 
       LoAddr = St->getBasePtr();
       HiAddr = DAG.getNode(ISD::ADD, MVT::i32, LoAddr,
-                           DAG.getConstant(MVT::i32, 4));
+                           DAG.getConstant(4, MVT::i32));
 
       SDOperand LoSt = DAG.getStore(NewChain, LoLd, LoAddr,
                           St->getSrcValue(), St->getSrcValueOffset(),
@@ -6068,10 +6650,11 @@ SDOperand X86TargetLowering::PerformDAGCombine(SDNode *N,
   SelectionDAG &DAG = DCI.DAG;
   switch (N->getOpcode()) {
   default: break;
-  case ISD::VECTOR_SHUFFLE: return PerformShuffleCombine(N, DAG, Subtarget);
+  case ISD::VECTOR_SHUFFLE: return PerformShuffleCombine(N, DAG, *this);
+  case ISD::BUILD_VECTOR:
+    return PerformBuildVectorCombine(N, DAG, Subtarget, *this);
   case ISD::SELECT:         return PerformSELECTCombine(N, DAG, Subtarget);
-  case ISD::STORE:          
-      return PerformSTORECombine(cast<StoreSDNode>(N), DAG, Subtarget);
+  case ISD::STORE:          return PerformSTORECombine(N, DAG, Subtarget);
   case X86ISD::FXOR:
   case X86ISD::FOR:         return PerformFORCombine(N, DAG);
   case X86ISD::FAND:        return PerformFANDCombine(N, DAG);
@@ -6091,12 +6674,14 @@ X86TargetLowering::getConstraintType(const std::string &Constraint) const {
   if (Constraint.size() == 1) {
     switch (Constraint[0]) {
     case 'A':
+    case 'f':
     case 'r':
     case 'R':
     case 'l':
     case 'q':
     case 'Q':
     case 'x':
+    case 'y':
     case 'Y':
       return C_RegisterClass;
     default:
@@ -6109,17 +6694,18 @@ X86TargetLowering::getConstraintType(const std::string &Constraint) const {
 /// 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)) {
+const char *X86TargetLowering::
+LowerXConstraint(MVT ConstraintVT) const {
+  // FP X constraints get lowered to SSE1/2 registers if available, otherwise
+  // 'f' like normal targets.
+  if (ConstraintVT.isFloatingPoint()) {
     if (Subtarget->hasSSE2())
-      s = "Y";
-    else if (Subtarget->hasSSE1())
-      s = "x";
-    else
-      s = "f";
-  } else
-    return TargetLowering::lowerXConstraint(ConstraintVT, s);
+      return "Y";
+    if (Subtarget->hasSSE1())
+      return "x";
+  }
+  
+  return TargetLowering::LowerXConstraint(ConstraintVT);
 }
 
 /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
@@ -6127,7 +6713,7 @@ void X86TargetLowering::lowerXConstraint(MVT::ValueType ConstraintVT,
 void X86TargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
                                                      char Constraint,
                                                      std::vector<SDOperand>&Ops,
-                                                     SelectionDAG &DAG) {
+                                                     SelectionDAG &DAG) const {
   SDOperand Result(0, 0);
   
   switch (Constraint) {
@@ -6205,7 +6791,7 @@ void X86TargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
 
 std::vector<unsigned> X86TargetLowering::
 getRegClassForInlineAsmConstraint(const std::string &Constraint,
-                                  MVT::ValueType VT) const {
+                                  MVT VT) const {
   if (Constraint.size() == 1) {
     // FIXME: not handling fp-stack yet!
     switch (Constraint[0]) {      // GCC X86 Constraint Letters
@@ -6233,7 +6819,7 @@ getRegClassForInlineAsmConstraint(const std::string &Constraint,
 
 std::pair<unsigned, const TargetRegisterClass*>
 X86TargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
-                                                MVT::ValueType VT) const {
+                                                MVT VT) const {
   // First, see if this is a constraint that directly corresponds to an LLVM
   // register class.
   if (Constraint.size() == 1) {
@@ -6252,6 +6838,14 @@ X86TargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
       else if (VT == MVT::i8)
         return std::make_pair(0U, X86::GR8RegisterClass);
       break;
+    case 'f':  // FP Stack registers.
+      // If SSE is enabled for this VT, use f80 to ensure the isel moves the
+      // value to the correct fpstack register class.
+      if (VT == MVT::f32 && !isScalarFPTypeInSSEReg(VT))
+        return std::make_pair(0U, X86::RFP32RegisterClass);
+      if (VT == MVT::f64 && !isScalarFPTypeInSSEReg(VT))
+        return std::make_pair(0U, X86::RFP64RegisterClass);
+      return std::make_pair(0U, X86::RFP80RegisterClass);
     case 'y':   // MMX_REGS if MMX allowed.
       if (!Subtarget->hasMMX()) break;
       return std::make_pair(0U, X86::VR64RegisterClass);
@@ -6261,8 +6855,8 @@ X86TargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
       // FALL THROUGH.
     case 'x':   // SSE_REGS if SSE1 allowed
       if (!Subtarget->hasSSE1()) break;
-      
-      switch (VT) {
+
+      switch (VT.getSimpleVT()) {
       default: break;
       // Scalar SSE types.
       case MVT::f32: