Use movaps to load a v4f32 build_vector of all-constant values into a
[oota-llvm.git] / lib / Target / X86 / X86ISelLowering.cpp
index 6de6b21c78e427f0b197d8626fbd926fa10345c6..23f9e9500c2dde606a1cc11adde7835c8aaf3e29 100644 (file)
@@ -42,6 +42,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   X86ScalarSSE = Subtarget->hasSSE2();
   X86StackPtr = Subtarget->is64Bit() ? X86::RSP : X86::ESP;
 
+  RegInfo = TM.getRegisterInfo();
+
   // Set up the TargetLowering object.
 
   // X86 is weird, it always uses i8 for shift amounts and setcc results.
@@ -197,6 +199,9 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
   }
   // X86 ret instruction may pop stack.
   setOperationAction(ISD::RET             , MVT::Other, Custom);
+  if (!Subtarget->is64Bit())
+    setOperationAction(ISD::EH_RETURN       , MVT::Other, Custom);
+
   // Darwin ABI issue.
   setOperationAction(ISD::ConstantPool    , MVT::i32  , Custom);
   setOperationAction(ISD::JumpTable       , MVT::i32  , Custom);
@@ -289,11 +294,14 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     addLegalFPImmediate(+0.0); // xorps / xorpd
   } else {
     // Set up the FP register classes.
-    addRegisterClass(MVT::f64, X86::RFPRegisterClass);
+    addRegisterClass(MVT::f64, X86::RFP64RegisterClass);
+    addRegisterClass(MVT::f32, X86::RFP32RegisterClass);
 
     setOperationAction(ISD::UNDEF,     MVT::f64, Expand);
+    setOperationAction(ISD::UNDEF,     MVT::f32, Expand);
     setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand);
     setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand);
+    setOperationAction(ISD::FP_ROUND,  MVT::f32, Expand);
 
     if (!UnsafeFPMath) {
       setOperationAction(ISD::FSIN           , MVT::f64  , Expand);
@@ -301,6 +309,7 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     }
 
     setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
+    setOperationAction(ISD::ConstantFP, MVT::f32, Expand);
     addLegalFPImmediate(+0.0); // FLD0
     addLegalFPImmediate(+1.0); // FLD1
     addLegalFPImmediate(-0.0); // FLD0/FCHS
@@ -309,11 +318,12 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
 
   // First set operation action for all vector types to expand. Then we
   // will selectively turn on ones that can be effectively codegen'd.
-  for (unsigned VT = (unsigned)MVT::Vector + 1;
-       VT != (unsigned)MVT::LAST_VALUETYPE; VT++) {
+  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);
@@ -326,6 +336,13 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     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);
   }
 
   if (Subtarget->hasMMX()) {
@@ -403,6 +420,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     setOperationAction(ISD::FSUB,               MVT::v4f32, Legal);
     setOperationAction(ISD::FMUL,               MVT::v4f32, Legal);
     setOperationAction(ISD::FDIV,               MVT::v4f32, Legal);
+    setOperationAction(ISD::FSQRT,              MVT::v4f32, Legal);
+    setOperationAction(ISD::FNEG,               MVT::v4f32, Custom);
     setOperationAction(ISD::LOAD,               MVT::v4f32, Legal);
     setOperationAction(ISD::BUILD_VECTOR,       MVT::v4f32, Custom);
     setOperationAction(ISD::VECTOR_SHUFFLE,     MVT::v4f32, Custom);
@@ -430,6 +449,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
     setOperationAction(ISD::FSUB,               MVT::v2f64, Legal);
     setOperationAction(ISD::FMUL,               MVT::v2f64, Legal);
     setOperationAction(ISD::FDIV,               MVT::v2f64, Legal);
+    setOperationAction(ISD::FSQRT,              MVT::v2f64, Legal);
+    setOperationAction(ISD::FNEG,               MVT::v2f64, Custom);
 
     setOperationAction(ISD::SCALAR_TO_VECTOR,   MVT::v16i8, Custom);
     setOperationAction(ISD::SCALAR_TO_VECTOR,   MVT::v8i16, Custom);
@@ -502,7 +523,8 @@ SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) {
   
   SmallVector<CCValAssign, 16> RVLocs;
   unsigned CC = DAG.getMachineFunction().getFunction()->getCallingConv();
-  CCState CCInfo(CC, getTargetMachine(), RVLocs);
+  bool isVarArg = DAG.getMachineFunction().getFunction()->isVarArg();
+  CCState CCInfo(CC, isVarArg, getTargetMachine(), RVLocs);
   CCInfo.AnalyzeReturn(Op.Val, RetCC_X86);
   
   
@@ -551,7 +573,7 @@ SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) {
         MemLoc = DAG.getFrameIndex(SSFI, getPointerTy());
         Chain = DAG.getStore(Op.getOperand(0), Value, MemLoc, NULL, 0);
       }
-      SDVTList Tys = DAG.getVTList(MVT::f64, MVT::Other);
+      SDVTList Tys = DAG.getVTList(RVLocs[0].getValVT(), MVT::Other);
       SDOperand Ops[] = {Chain, MemLoc, DAG.getValueType(RVLocs[0].getValVT())};
       Value = DAG.getNode(X86ISD::FLD, Tys, Ops, 3);
       Chain = Value.getValue(1);
@@ -582,7 +604,8 @@ LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode *TheCall,
   
   // Assign locations to each value returned by this call.
   SmallVector<CCValAssign, 16> RVLocs;
-  CCState CCInfo(CallingConv, getTargetMachine(), RVLocs);
+  bool isVarArg = cast<ConstantSDNode>(TheCall->getOperand(2))->getValue() != 0;
+  CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs);
   CCInfo.AnalyzeCallResult(TheCall, RetCC_X86);
 
   
@@ -601,7 +624,7 @@ LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode *TheCall,
     // before the fp stackifier runs.
     
     // Copy ST0 into an RFP register with FP_GET_RESULT.
-    SDVTList Tys = DAG.getVTList(MVT::f64, MVT::Other, MVT::Flag);
+    SDVTList Tys = DAG.getVTList(RVLocs[0].getValVT(), MVT::Other, MVT::Flag);
     SDOperand GROps[] = { Chain, InFlag };
     SDOperand RetVal = DAG.getNode(X86ISD::FP_GET_RESULT, Tys, GROps, 2);
     Chain  = RetVal.getValue(1);
@@ -623,11 +646,6 @@ LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode *TheCall,
       RetVal = DAG.getLoad(RVLocs[0].getValVT(), Chain, StackSlot, NULL, 0);
       Chain = RetVal.getValue(1);
     }
-    
-    if (RVLocs[0].getValVT() == MVT::f32 && !X86ScalarSSE)
-      // FIXME: we would really like to remember that this FP_ROUND
-      // operation is okay to eliminate if we allow excess FP precision.
-      RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal);
     ResultVals.push_back(RetVal);
   }
   
@@ -667,8 +685,8 @@ SDOperand X86TargetLowering::LowerCCCArguments(SDOperand Op, SelectionDAG &DAG,
 
   // Assign locations to all of the incoming arguments.
   SmallVector<CCValAssign, 16> ArgLocs;
-  CCState CCInfo(MF.getFunction()->getCallingConv(), getTargetMachine(),
-                 ArgLocs);
+  CCState CCInfo(MF.getFunction()->getCallingConv(), isVarArg,
+                 getTargetMachine(), ArgLocs);
   CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_32_C);
    
   SmallVector<SDOperand, 8> ArgValues;
@@ -764,7 +782,7 @@ SDOperand X86TargetLowering::LowerCCCCallTo(SDOperand Op, SelectionDAG &DAG,
 
   // Analyze operands of the call, assigning locations to each operand.
   SmallVector<CCValAssign, 16> ArgLocs;
-  CCState CCInfo(CC, getTargetMachine(), ArgLocs);
+  CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
   CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_32_C);
   
   // Get a count of how many bytes are to be pushed on the stack.
@@ -919,11 +937,12 @@ X86TargetLowering::LowerFastCCArguments(SDOperand Op, SelectionDAG &DAG) {
   MachineFunction &MF = DAG.getMachineFunction();
   MachineFrameInfo *MFI = MF.getFrameInfo();
   SDOperand Root = Op.getOperand(0);
+  bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
 
   // Assign locations to all of the incoming arguments.
   SmallVector<CCValAssign, 16> ArgLocs;
-  CCState CCInfo(MF.getFunction()->getCallingConv(), getTargetMachine(),
-                 ArgLocs);
+  CCState CCInfo(MF.getFunction()->getCallingConv(), isVarArg,
+                 getTargetMachine(), ArgLocs);
   CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_32_FastCall);
   
   SmallVector<SDOperand, 8> ArgValues;
@@ -1003,11 +1022,12 @@ SDOperand X86TargetLowering::LowerFastCCCallTo(SDOperand Op, SelectionDAG &DAG,
                                                unsigned CC) {
   SDOperand Chain     = Op.getOperand(0);
   bool isTailCall     = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0;
+  bool isVarArg       = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
   SDOperand Callee    = Op.getOperand(4);
 
   // Analyze operands of the call, assigning locations to each operand.
   SmallVector<CCValAssign, 16> ArgLocs;
-  CCState CCInfo(CC, getTargetMachine(), ArgLocs);
+  CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
   CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_32_FastCall);
   
   // Get a count of how many bytes are to be pushed on the stack.
@@ -1156,8 +1176,8 @@ X86TargetLowering::LowerX86_64CCCArguments(SDOperand Op, SelectionDAG &DAG) {
   
   // Assign locations to all of the incoming arguments.
   SmallVector<CCValAssign, 16> ArgLocs;
-  CCState CCInfo(MF.getFunction()->getCallingConv(), getTargetMachine(),
-                 ArgLocs);
+  CCState CCInfo(MF.getFunction()->getCallingConv(), isVarArg,
+                 getTargetMachine(), ArgLocs);
   CCInfo.AnalyzeFormalArguments(Op.Val, CC_X86_64_C);
   
   SmallVector<SDOperand, 8> ArgValues;
@@ -1183,7 +1203,11 @@ X86TargetLowering::LowerX86_64CCCArguments(SDOperand Op, SelectionDAG &DAG) {
         RC = X86::FR64RegisterClass;
       else {
         assert(MVT::isVector(RegVT));
-        RC = X86::VR128RegisterClass;
+        if (MVT::getSizeInBits(RegVT) == 64) {
+          RC = X86::GR64RegisterClass;       // MMX values are passed in GPRs.
+          RegVT = MVT::i64;
+        } else
+          RC = X86::VR128RegisterClass;
       }
 
       unsigned Reg = AddLiveIn(DAG.getMachineFunction(), VA.getLocReg(), RC);
@@ -1202,6 +1226,11 @@ X86TargetLowering::LowerX86_64CCCArguments(SDOperand Op, SelectionDAG &DAG) {
       if (VA.getLocInfo() != CCValAssign::Full)
         ArgValue = DAG.getNode(ISD::TRUNCATE, VA.getValVT(), ArgValue);
       
+      // Handle MMX values passed in GPRs.
+      if (RegVT != VA.getLocVT() && RC == X86::GR64RegisterClass &&
+          MVT::getSizeInBits(RegVT) == 64)
+        ArgValue = DAG.getNode(ISD::BIT_CONVERT, VA.getLocVT(), ArgValue);
+      
       ArgValues.push_back(ArgValue);
     } else {
       assert(VA.isMemLoc());
@@ -1283,7 +1312,7 @@ X86TargetLowering::LowerX86_64CCCCallTo(SDOperand Op, SelectionDAG &DAG,
   
   // Analyze operands of the call, assigning locations to each operand.
   SmallVector<CCValAssign, 16> ArgLocs;
-  CCState CCInfo(CC, getTargetMachine(), ArgLocs);
+  CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
   CCInfo.AnalyzeCallOperands(Op.Val, CC_X86_64_C);
     
   // Get a count of how many bytes are to be pushed on the stack.
@@ -1630,7 +1659,7 @@ bool X86::isSHUFPMask(SDNode *N) {
   return ::isSHUFPMask(N->op_begin(), N->getNumOperands());
 }
 
-/// isCommutedSHUFP - Returns true if the shuffle mask is except
+/// isCommutedSHUFP - Returns true if the shuffle mask is exactly
 /// 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.
@@ -1945,6 +1974,16 @@ bool X86::isMOVSLDUPMask(SDNode *N) {
   return HasHi;
 }
 
+/// isIdentityMask - Return true if the specified VECTOR_SHUFFLE operand
+/// specifies a identity operation on the LHS or RHS.
+static bool isIdentityMask(SDNode *N, bool RHS = false) {
+  unsigned NumElems = N->getNumOperands();
+  for (unsigned i = 0; i < NumElems; ++i)
+    if (!isUndefOrEqual(N->getOperand(i), i + (RHS ? NumElems : 0)))
+      return false;
+  return true;
+}
+
 /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand specifies
 /// a splat of a single element.
 static bool isSplatMask(SDNode *N) {
@@ -2097,7 +2136,7 @@ static SDOperand CommuteVectorShuffle(SDOperand Op, SDOperand &V1,
                                       SelectionDAG &DAG) {
   MVT::ValueType VT = Op.getValueType();
   MVT::ValueType MaskVT = Mask.getValueType();
-  MVT::ValueType EltVT = MVT::getVectorBaseType(MaskVT);
+  MVT::ValueType EltVT = MVT::getVectorElementType(MaskVT);
   unsigned NumElems = Mask.getNumOperands();
   SmallVector<SDOperand, 8> MaskVec;
 
@@ -2188,7 +2227,7 @@ static bool isSplatVector(SDNode *N) {
 /// isUndefShuffle - Returns true if N is a VECTOR_SHUFFLE that can be resolved
 /// to an undef.
 static bool isUndefShuffle(SDNode *N) {
-  if (N->getOpcode() != ISD::BUILD_VECTOR)
+  if (N->getOpcode() != ISD::VECTOR_SHUFFLE)
     return false;
 
   SDOperand V1 = N->getOperand(0);
@@ -2208,6 +2247,61 @@ static bool isUndefShuffle(SDNode *N) {
   return true;
 }
 
+/// isZeroNode - Returns true if Elt is a constant zero or a floating point
+/// constant +0.0.
+static inline bool isZeroNode(SDOperand Elt) {
+  return ((isa<ConstantSDNode>(Elt) &&
+           cast<ConstantSDNode>(Elt)->getValue() == 0) ||
+          (isa<ConstantFPSDNode>(Elt) &&
+           cast<ConstantFPSDNode>(Elt)->isExactlyValue(0.0)));
+}
+
+/// isZeroShuffle - Returns true if N is a VECTOR_SHUFFLE that can be resolved
+/// to an zero vector.
+static bool isZeroShuffle(SDNode *N) {
+  if (N->getOpcode() != ISD::VECTOR_SHUFFLE)
+    return false;
+
+  SDOperand V1 = N->getOperand(0);
+  SDOperand V2 = N->getOperand(1);
+  SDOperand Mask = N->getOperand(2);
+  unsigned NumElems = Mask.getNumOperands();
+  for (unsigned i = 0; i != NumElems; ++i) {
+    SDOperand Arg = Mask.getOperand(i);
+    if (Arg.getOpcode() != ISD::UNDEF) {
+      unsigned Idx = cast<ConstantSDNode>(Arg)->getValue();
+      if (Idx < NumElems) {
+        unsigned Opc = V1.Val->getOpcode();
+        if (Opc == ISD::UNDEF)
+          continue;
+        if (Opc != ISD::BUILD_VECTOR ||
+            !isZeroNode(V1.Val->getOperand(Idx)))
+          return false;
+      } else if (Idx >= NumElems) {
+        unsigned Opc = V2.Val->getOpcode();
+        if (Opc == ISD::UNDEF)
+          continue;
+        if (Opc != ISD::BUILD_VECTOR ||
+            !isZeroNode(V2.Val->getOperand(Idx - NumElems)))
+          return false;
+      }
+    }
+  }
+  return true;
+}
+
+/// 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");
+  unsigned NumElems = MVT::getVectorNumElements(VT);
+  MVT::ValueType EVT = MVT::getVectorElementType(VT);
+  bool isFP = MVT::isFloatingPoint(EVT);
+  SDOperand Zero = isFP ? DAG.getConstantFP(0.0, EVT) : DAG.getConstant(0, EVT);
+  SmallVector<SDOperand, 8> ZeroVec(NumElems, Zero);
+  return DAG.getNode(ISD::BUILD_VECTOR, VT, &ZeroVec[0], ZeroVec.size());
+}
+
 /// NormalizeMask - V2 is a splat, modify the mask (if needed) so all elements
 /// that point to V2 points to its first element.
 static SDOperand NormalizeMask(SDOperand Mask, SelectionDAG &DAG) {
@@ -2238,7 +2332,7 @@ static SDOperand NormalizeMask(SDOperand Mask, SelectionDAG &DAG) {
 /// operation of specified width.
 static SDOperand getMOVLMask(unsigned NumElems, SelectionDAG &DAG) {
   MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
-  MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT);
+  MVT::ValueType BaseVT = MVT::getVectorElementType(MaskVT);
 
   SmallVector<SDOperand, 8> MaskVec;
   MaskVec.push_back(DAG.getConstant(NumElems, BaseVT));
@@ -2251,7 +2345,7 @@ static SDOperand getMOVLMask(unsigned NumElems, SelectionDAG &DAG) {
 /// of specified width.
 static SDOperand getUnpacklMask(unsigned NumElems, SelectionDAG &DAG) {
   MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
-  MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT);
+  MVT::ValueType BaseVT = MVT::getVectorElementType(MaskVT);
   SmallVector<SDOperand, 8> MaskVec;
   for (unsigned i = 0, e = NumElems/2; i != e; ++i) {
     MaskVec.push_back(DAG.getConstant(i,            BaseVT));
@@ -2264,7 +2358,7 @@ static SDOperand getUnpacklMask(unsigned NumElems, SelectionDAG &DAG) {
 /// of specified width.
 static SDOperand getUnpackhMask(unsigned NumElems, SelectionDAG &DAG) {
   MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
-  MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT);
+  MVT::ValueType BaseVT = MVT::getVectorElementType(MaskVT);
   unsigned Half = NumElems/2;
   SmallVector<SDOperand, 8> MaskVec;
   for (unsigned i = 0; i != Half; ++i) {
@@ -2274,18 +2368,6 @@ static SDOperand getUnpackhMask(unsigned NumElems, SelectionDAG &DAG) {
   return DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &MaskVec[0], MaskVec.size());
 }
 
-/// 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");
-  unsigned NumElems = getVectorNumElements(VT);
-  MVT::ValueType EVT = MVT::getVectorBaseType(VT);
-  bool isFP = MVT::isFloatingPoint(EVT);
-  SDOperand Zero = isFP ? DAG.getConstantFP(0.0, EVT) : DAG.getConstant(0, EVT);
-  SmallVector<SDOperand, 8> ZeroVec(NumElems, Zero);
-  return DAG.getNode(ISD::BUILD_VECTOR, VT, &ZeroVec[0], ZeroVec.size());
-}
-
 /// PromoteSplat - Promote a splat of v8i16 or v16i8 to v4i32.
 ///
 static SDOperand PromoteSplat(SDOperand Op, SelectionDAG &DAG) {
@@ -2307,23 +2389,14 @@ static SDOperand PromoteSplat(SDOperand Op, SelectionDAG &DAG) {
   return DAG.getNode(ISD::BIT_CONVERT, VT, Shuffle);
 }
 
-/// isZeroNode - Returns true if Elt is a constant zero or a floating point
-/// constant +0.0.
-static inline bool isZeroNode(SDOperand Elt) {
-  return ((isa<ConstantSDNode>(Elt) &&
-           cast<ConstantSDNode>(Elt)->getValue() == 0) ||
-          (isa<ConstantFPSDNode>(Elt) &&
-           cast<ConstantFPSDNode>(Elt)->isExactlyValue(0.0)));
-}
-
 /// getShuffleVectorZeroOrUndef - Return a vector_shuffle of the specified
-/// vector and zero or undef vector.
+/// vector of zero or undef vector.
 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::getVectorBaseType(MaskVT);
+  MVT::ValueType EVT = MVT::getVectorElementType(MaskVT);
   SDOperand Zero = DAG.getConstant(0, EVT);
   SmallVector<SDOperand, 8> MaskVec(NumElems, Zero);
   MaskVec[Idx] = DAG.getConstant(NumElems, EVT);
@@ -2415,13 +2488,14 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
     return Op;
 
   MVT::ValueType VT = Op.getValueType();
-  MVT::ValueType EVT = MVT::getVectorBaseType(VT);
+  MVT::ValueType EVT = MVT::getVectorElementType(VT);
   unsigned EVTBits = MVT::getSizeInBits(EVT);
 
   unsigned NumElems = Op.getNumOperands();
   unsigned NumZero  = 0;
   unsigned NumNonZero = 0;
   unsigned NonZeros = 0;
+  unsigned NumNonZeroImms = 0;
   std::set<SDOperand> Values;
   for (unsigned i = 0; i < NumElems; ++i) {
     SDOperand Elt = Op.getOperand(i);
@@ -2432,13 +2506,21 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
       else {
         NonZeros |= (1 << i);
         NumNonZero++;
+        if (Elt.getOpcode() == ISD::Constant ||
+            Elt.getOpcode() == ISD::ConstantFP)
+          NumNonZeroImms++;
       }
     }
   }
 
-  if (NumNonZero == 0)
-    // Must be a mix of zero and undef. Return a zero vector.
-    return getZeroVector(VT, DAG);
+  if (NumNonZero == 0) {
+    if (NumZero == 0)
+      // All undef vector. Return an UNDEF.
+      return DAG.getNode(ISD::UNDEF, VT);
+    else
+      // A mix of zero and undef. Return a zero vector.
+      return getZeroVector(VT, DAG);
+  }
 
   // Splat is obviously ok. Let legalizer expand it to a shuffle.
   if (Values.size() == 1)
@@ -2459,7 +2541,7 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
       Item = getShuffleVectorZeroOrUndef(Item, VT, NumElems, 0, NumZero > 0,
                                          DAG);
       MVT::ValueType MaskVT  = MVT::getIntVectorWithNumElements(NumElems);
-      MVT::ValueType MaskEVT = MVT::getVectorBaseType(MaskVT);
+      MVT::ValueType MaskEVT = MVT::getVectorElementType(MaskVT);
       SmallVector<SDOperand, 8> MaskVec;
       for (unsigned i = 0; i < NumElems; i++)
         MaskVec.push_back(DAG.getConstant((i == Idx) ? 0 : 1, MaskEVT));
@@ -2470,6 +2552,11 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
     }
   }
 
+  // A vector full of immediates; various special cases are already
+  // handled, so this is best done with a single constant-pool load.
+  if (NumNonZero == NumNonZeroImms)
+    return SDOperand();
+
   // Let legalizer expand 2-wide build_vectors.
   if (EVTBits == 64)
     return SDOperand();
@@ -2528,7 +2615,7 @@ X86TargetLowering::LowerBUILD_VECTOR(SDOperand Op, SelectionDAG &DAG) {
     if (MVT::isInteger(EVT) && (NonZeros & (0x3 << 2)) == 0)
       return V[0];
     MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
-    MVT::ValueType EVT = MVT::getVectorBaseType(MaskVT);
+    MVT::ValueType EVT = MVT::getVectorElementType(MaskVT);
     SmallVector<SDOperand, 8> MaskVec;
     bool Reverse = (NonZeros & 0x3) == 2;
     for (unsigned i = 0; i < 2; ++i)
@@ -2584,6 +2671,14 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
   if (isUndefShuffle(Op.Val))
     return DAG.getNode(ISD::UNDEF, VT);
 
+  if (isZeroShuffle(Op.Val))
+    return getZeroVector(VT, DAG);
+
+  if (isIdentityMask(PermMask.Val))
+    return V1;
+  else if (isIdentityMask(PermMask.Val, true))
+    return V2;
+
   if (isSplatMask(PermMask.Val)) {
     if (NumElems <= 4) return Op;
     // Promote it to a v4i32 splat.
@@ -2675,13 +2770,14 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
       return Op;
     }
 
-    if (X86::isSHUFPMask(PermMask.Val))
+    if (X86::isSHUFPMask(PermMask.Val) &&
+        MVT::getSizeInBits(VT) != 64)    // Don't do this for MMX.
       return Op;
 
     // Handle v8i16 shuffle high / low shuffle node pair.
     if (VT == MVT::v8i16 && isPSHUFHW_PSHUFLWMask(PermMask.Val)) {
       MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(NumElems);
-      MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT);
+      MVT::ValueType BaseVT = MVT::getVectorElementType(MaskVT);
       SmallVector<SDOperand, 8> MaskVec;
       for (unsigned i = 0; i != 4; ++i)
         MaskVec.push_back(PermMask.getOperand(i));
@@ -2712,9 +2808,11 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDOperand Op, SelectionDAG &DAG) {
     }
   }
 
-  if (NumElems == 4) {
+  if (NumElems == 4 && 
+      // Don't do this for MMX.
+      MVT::getSizeInBits(VT) != 64) {
     MVT::ValueType MaskVT = PermMask.getValueType();
-    MVT::ValueType MaskEVT = MVT::getVectorBaseType(MaskVT);
+    MVT::ValueType MaskEVT = MVT::getVectorElementType(MaskVT);
     SmallVector<std::pair<int, int>, 8> Locs;
     Locs.reserve(NumElems);
     SmallVector<SDOperand, 8> Mask1(NumElems, DAG.getNode(ISD::UNDEF, MaskEVT));
@@ -2839,10 +2937,10 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
     // SHUFPS the element to the lowest double word, then movss.
     MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4);
     SmallVector<SDOperand, 8> IdxVec;
-    IdxVec.push_back(DAG.getConstant(Idx, MVT::getVectorBaseType(MaskVT)));
-    IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(MaskVT)));
-    IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(MaskVT)));
-    IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(MaskVT)));
+    IdxVec.push_back(DAG.getConstant(Idx, MVT::getVectorElementType(MaskVT)));
+    IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT)));
+    IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT)));
+    IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT)));
     SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
                                  &IdxVec[0], IdxVec.size());
     Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(),
@@ -2860,8 +2958,8 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
     // to a f64mem, the whole operation is folded into a single MOVHPDmr.
     MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4);
     SmallVector<SDOperand, 8> IdxVec;
-    IdxVec.push_back(DAG.getConstant(1, MVT::getVectorBaseType(MaskVT)));
-    IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(MaskVT)));
+    IdxVec.push_back(DAG.getConstant(1, MVT::getVectorElementType(MaskVT)));
+    IdxVec.push_back(DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(MaskVT)));
     SDOperand Mask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT,
                                  &IdxVec[0], IdxVec.size());
     Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(),
@@ -2878,7 +2976,7 @@ X86TargetLowering::LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
   // Transform it so it match pinsrw which expects a 16-bit value in a GR32
   // as its second argument.
   MVT::ValueType VT = Op.getValueType();
-  MVT::ValueType BaseVT = MVT::getVectorBaseType(VT);
+  MVT::ValueType BaseVT = MVT::getVectorElementType(VT);
   SDOperand N0 = Op.getOperand(0);
   SDOperand N1 = Op.getOperand(1);
   SDOperand N2 = Op.getOperand(2);
@@ -2886,7 +2984,7 @@ X86TargetLowering::LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
     if (N1.getValueType() != MVT::i32)
       N1 = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, N1);
     if (N2.getValueType() != MVT::i32)
-      N2 = DAG.getConstant(cast<ConstantSDNode>(N2)->getValue(), MVT::i32);
+      N2 = DAG.getConstant(cast<ConstantSDNode>(N2)->getValue(),getPointerTy());
     return DAG.getNode(X86ISD::PINSRW, VT, N0, N1, N2);
   } else if (MVT::getSizeInBits(BaseVT) == 32) {
     unsigned Idx = cast<ConstantSDNode>(N2)->getValue();
@@ -2894,7 +2992,7 @@ X86TargetLowering::LowerINSERT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
       // Use a movss.
       N1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, N1);
       MVT::ValueType MaskVT = MVT::getIntVectorWithNumElements(4);
-      MVT::ValueType BaseVT = MVT::getVectorBaseType(MaskVT);
+      MVT::ValueType BaseVT = MVT::getVectorElementType(MaskVT);
       SmallVector<SDOperand, 8> MaskVec;
       MaskVec.push_back(DAG.getConstant(4, BaseVT));
       for (unsigned i = 1; i <= 3; ++i)
@@ -3178,7 +3276,7 @@ SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
   if (X86ScalarSSE)
     Tys = DAG.getVTList(MVT::f64, MVT::Other, MVT::Flag);
   else
-    Tys = DAG.getVTList(MVT::f64, MVT::Other);
+    Tys = DAG.getVTList(Op.getValueType(), MVT::Other);
   SmallVector<SDOperand, 8> Ops;
   Ops.push_back(Chain);
   Ops.push_back(StackSlot);
@@ -3233,7 +3331,7 @@ SDOperand X86TargetLowering::LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) {
   if (X86ScalarSSE) {
     assert(Op.getValueType() == MVT::i64 && "Invalid FP_TO_SINT to lower!");
     Chain = DAG.getStore(Chain, Value, StackSlot, NULL, 0);
-    SDVTList Tys = DAG.getVTList(MVT::f64, MVT::Other);
+    SDVTList Tys = DAG.getVTList(Op.getOperand(0).getValueType(), MVT::Other);
     SDOperand Ops[] = {
       Chain, StackSlot, DAG.getValueType(Op.getOperand(0).getValueType())
     };
@@ -3253,16 +3351,21 @@ SDOperand X86TargetLowering::LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) {
 
 SDOperand X86TargetLowering::LowerFABS(SDOperand Op, SelectionDAG &DAG) {
   MVT::ValueType VT = Op.getValueType();
-  const Type *OpNTy =  MVT::getTypeForValueType(VT);
+  MVT::ValueType EltVT = VT;
+  if (MVT::isVector(VT))
+    EltVT = MVT::getVectorElementType(VT);
+  const Type *OpNTy =  MVT::getTypeForValueType(EltVT);
   std::vector<Constant*> CV;
-  if (VT == MVT::f64) {
-    CV.push_back(ConstantFP::get(OpNTy, BitsToDouble(~(1ULL << 63))));
-    CV.push_back(ConstantFP::get(OpNTy, 0.0));
+  if (EltVT == MVT::f64) {
+    Constant *C = ConstantFP::get(OpNTy, BitsToDouble(~(1ULL << 63)));
+    CV.push_back(C);
+    CV.push_back(C);
   } else {
-    CV.push_back(ConstantFP::get(OpNTy, BitsToFloat(~(1U << 31))));
-    CV.push_back(ConstantFP::get(OpNTy, 0.0));
-    CV.push_back(ConstantFP::get(OpNTy, 0.0));
-    CV.push_back(ConstantFP::get(OpNTy, 0.0));
+    Constant *C = ConstantFP::get(OpNTy, BitsToFloat(~(1U << 31)));
+    CV.push_back(C);
+    CV.push_back(C);
+    CV.push_back(C);
+    CV.push_back(C);
   }
   Constant *CS = ConstantStruct::get(CV);
   SDOperand CPIdx = DAG.getConstantPool(CS, getPointerTy(), 4);
@@ -3277,26 +3380,42 @@ SDOperand X86TargetLowering::LowerFABS(SDOperand Op, SelectionDAG &DAG) {
 
 SDOperand X86TargetLowering::LowerFNEG(SDOperand Op, SelectionDAG &DAG) {
   MVT::ValueType VT = Op.getValueType();
-  const Type *OpNTy =  MVT::getTypeForValueType(VT);
+  MVT::ValueType EltVT = VT;
+  unsigned EltNum = 1;
+  if (MVT::isVector(VT)) {
+    EltVT = MVT::getVectorElementType(VT);
+    EltNum = MVT::getVectorNumElements(VT);
+  }
+  const Type *OpNTy =  MVT::getTypeForValueType(EltVT);
   std::vector<Constant*> CV;
-  if (VT == MVT::f64) {
-    CV.push_back(ConstantFP::get(OpNTy, BitsToDouble(1ULL << 63)));
-    CV.push_back(ConstantFP::get(OpNTy, 0.0));
+  if (EltVT == MVT::f64) {
+    Constant *C = ConstantFP::get(OpNTy, BitsToDouble(1ULL << 63));
+    CV.push_back(C);
+    CV.push_back(C);
   } else {
-    CV.push_back(ConstantFP::get(OpNTy, BitsToFloat(1U << 31)));
-    CV.push_back(ConstantFP::get(OpNTy, 0.0));
-    CV.push_back(ConstantFP::get(OpNTy, 0.0));
-    CV.push_back(ConstantFP::get(OpNTy, 0.0));
+    Constant *C = ConstantFP::get(OpNTy, BitsToFloat(1U << 31));
+    CV.push_back(C);
+    CV.push_back(C);
+    CV.push_back(C);
+    CV.push_back(C);
   }
   Constant *CS = ConstantStruct::get(CV);
   SDOperand CPIdx = DAG.getConstantPool(CS, getPointerTy(), 4);
-  SDVTList Tys = DAG.getVTList(VT, MVT::Other);
-  SmallVector<SDOperand, 3> Ops;
-  Ops.push_back(DAG.getEntryNode());
-  Ops.push_back(CPIdx);
-  Ops.push_back(DAG.getSrcValue(NULL));
-  SDOperand Mask = DAG.getNode(X86ISD::LOAD_PACK, Tys, &Ops[0], Ops.size());
-  return DAG.getNode(X86ISD::FXOR, VT, Op.getOperand(0), Mask);
+  if (MVT::isVector(VT)) {
+    SDOperand Mask = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, NULL, 0);
+    return DAG.getNode(ISD::BIT_CONVERT, VT,
+                       DAG.getNode(ISD::XOR, MVT::v2i64,
+                    DAG.getNode(ISD::BIT_CONVERT, MVT::v2i64, Op.getOperand(0)),
+                    DAG.getNode(ISD::BIT_CONVERT, MVT::v2i64, Mask)));
+  } else {
+    SDVTList Tys = DAG.getVTList(VT, MVT::Other);
+    SmallVector<SDOperand, 3> Ops;
+    Ops.push_back(DAG.getEntryNode());
+    Ops.push_back(CPIdx);
+    Ops.push_back(DAG.getSrcValue(NULL));
+    SDOperand Mask = DAG.getNode(X86ISD::LOAD_PACK, Tys, &Ops[0], Ops.size());
+    return DAG.getNode(X86ISD::FXOR, VT, Op.getOperand(0), Mask);
+  }
 }
 
 SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
@@ -3529,8 +3648,9 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
 // bytes in one go. Touching the stack at 4K increments is necessary to ensure
 // that the guard pages used by the OS virtual memory manager are allocated in
 // correct sequence.
-SDOperand X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDOperand Op,
-                                                     SelectionDAG &DAG) {
+SDOperand
+X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDOperand Op,
+                                           SelectionDAG &DAG) {
   assert(Subtarget->isTargetCygMing() &&
          "This should be used only on Cygwin/Mingw targets");
   
@@ -3539,27 +3659,29 @@ SDOperand X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDOperand Op,
   SDOperand Size  = Op.getOperand(1);
   // FIXME: Ensure alignment here
 
-  TargetLowering::ArgListTy Args; 
-  TargetLowering::ArgListEntry Entry;
+  SDOperand Flag;
+  
   MVT::ValueType IntPtr = getPointerTy();
   MVT::ValueType SPTy = (Subtarget->is64Bit() ? MVT::i64 : MVT::i32);
-  const Type *IntPtrTy = getTargetData()->getIntPtrType();
-  
-  Entry.Node    = Size;
-  Entry.Ty      = IntPtrTy;
-  Entry.isInReg = true; // Should pass in EAX
-  Args.push_back(Entry);
-  std::pair<SDOperand, SDOperand> CallResult =
-    LowerCallTo(Chain, IntPtrTy, false, false, CallingConv::C, false,
-                DAG.getExternalSymbol("_alloca", IntPtr), Args, DAG);
-
-  SDOperand SP = DAG.getCopyFromReg(CallResult.second, X86StackPtr, SPTy);
+
+  Chain = DAG.getCopyToReg(Chain, X86::EAX, Size, Flag);
+  Flag = Chain.getValue(1);
+
+  SDVTList  NodeTys = DAG.getVTList(MVT::Other, MVT::Flag);
+  SDOperand Ops[] = { Chain,
+                      DAG.getTargetExternalSymbol("_alloca", IntPtr),
+                      DAG.getRegister(X86::EAX, IntPtr),
+                      Flag };
+  Chain = DAG.getNode(X86ISD::CALL, NodeTys, Ops, 4);
+  Flag = Chain.getValue(1);
+
+  Chain = DAG.getCopyFromReg(Chain, X86StackPtr, SPTy).getValue(1);
   
   std::vector<MVT::ValueType> Tys;
   Tys.push_back(SPTy);
   Tys.push_back(MVT::Other);
-  SDOperand Ops[2] = { SP, CallResult.second };
-  return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops, 2);
+  SDOperand Ops1[2] = { Chain.getValue(0), Chain };
+  return DAG.getNode(ISD::MERGE_VALUES, Tys, Ops1, 2);
 }
 
 SDOperand
@@ -4127,6 +4249,39 @@ SDOperand X86TargetLowering::LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG) {
                      DAG.getConstant(4, getPointerTy()));
 }
 
+SDOperand X86TargetLowering::LowerFRAME_TO_ARGS_OFFSET(SDOperand Op,
+                                                       SelectionDAG &DAG) {
+  // Is not yet supported on x86-64
+  if (Subtarget->is64Bit())
+    return SDOperand();
+  
+  return DAG.getConstant(8, getPointerTy());
+}
+
+SDOperand X86TargetLowering::LowerEH_RETURN(SDOperand Op, SelectionDAG &DAG)
+{
+  assert(!Subtarget->is64Bit() &&
+         "Lowering of eh_return builtin is not supported yet on x86-64");
+    
+  MachineFunction &MF = DAG.getMachineFunction();
+  SDOperand Chain     = Op.getOperand(0);
+  SDOperand Offset    = Op.getOperand(1);
+  SDOperand Handler   = Op.getOperand(2);
+
+  SDOperand Frame = DAG.getRegister(RegInfo->getFrameRegister(MF),
+                                    getPointerTy());
+
+  SDOperand StoreAddr = DAG.getNode(ISD::SUB, getPointerTy(), Frame,
+                                    DAG.getConstant(-4UL, getPointerTy()));
+  StoreAddr = DAG.getNode(ISD::ADD, getPointerTy(), StoreAddr, Offset);
+  Chain = DAG.getStore(Chain, Handler, StoreAddr, NULL, 0);
+  Chain = DAG.getCopyToReg(Chain, X86::ECX, StoreAddr);
+  MF.addLiveOut(X86::ECX);
+
+  return DAG.getNode(X86ISD::EH_RETURN, MVT::Other,
+                     Chain, DAG.getRegister(X86::ECX, getPointerTy()));
+}
+
 /// LowerOperation - Provide custom lowering hooks for some operations.
 ///
 SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
@@ -4164,7 +4319,10 @@ SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
   case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG);
   case ISD::RETURNADDR:         return LowerRETURNADDR(Op, DAG);
   case ISD::FRAMEADDR:          return LowerFRAMEADDR(Op, DAG);
+  case ISD::FRAME_TO_ARGS_OFFSET:
+                                return LowerFRAME_TO_ARGS_OFFSET(Op, DAG);
   case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG);
+  case ISD::EH_RETURN:          return LowerEH_RETURN(Op, DAG);
   }
   return SDOperand();
 }
@@ -4208,8 +4366,11 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
   case X86ISD::PINSRW:             return "X86ISD::PINSRW";
   case X86ISD::FMAX:               return "X86ISD::FMAX";
   case X86ISD::FMIN:               return "X86ISD::FMIN";
+  case X86ISD::FRSQRT:             return "X86ISD::FRSQRT";
+  case X86ISD::FRCP:               return "X86ISD::FRCP";
   case X86ISD::TLSADDR:            return "X86ISD::TLSADDR";
   case X86ISD::THREAD_POINTER:     return "X86ISD::THREAD_POINTER";
+  case X86ISD::EH_RETURN:          return "X86ISD::EH_RETURN";
   }
 }
 
@@ -4267,12 +4428,14 @@ X86TargetLowering::isShuffleMaskLegal(SDOperand Mask, MVT::ValueType VT) const {
   // Only do shuffles on 128-bit vector types for now.
   if (MVT::getSizeInBits(VT) == 64) return false;
   return (Mask.Val->getNumOperands() <= 4 ||
+          isIdentityMask(Mask.Val) ||
+          isIdentityMask(Mask.Val, true) ||
           isSplatMask(Mask.Val)  ||
           isPSHUFHW_PSHUFLWMask(Mask.Val) ||
           X86::isUNPCKLMask(Mask.Val) ||
+          X86::isUNPCKHMask(Mask.Val) ||
           X86::isUNPCKL_v_undef_Mask(Mask.Val) ||
-          X86::isUNPCKH_v_undef_Mask(Mask.Val) ||
-          X86::isUNPCKHMask(Mask.Val));
+          X86::isUNPCKH_v_undef_Mask(Mask.Val));
 }
 
 bool X86TargetLowering::isVectorClearMaskLegal(std::vector<SDOperand> &BVOps,
@@ -4361,9 +4524,12 @@ X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
     return BB;
   }
 
-  case X86::FP_TO_INT16_IN_MEM:
-  case X86::FP_TO_INT32_IN_MEM:
-  case X86::FP_TO_INT64_IN_MEM: {
+  case X86::FP32_TO_INT16_IN_MEM:
+  case X86::FP32_TO_INT32_IN_MEM:
+  case X86::FP32_TO_INT64_IN_MEM:
+  case X86::FP64_TO_INT16_IN_MEM:
+  case X86::FP64_TO_INT32_IN_MEM:
+  case X86::FP64_TO_INT64_IN_MEM: {
     // Change the floating point control register to use "round towards zero"
     // mode when truncating to an integer value.
     MachineFunction *F = BB->getParent();
@@ -4390,9 +4556,12 @@ X86TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
     unsigned Opc;
     switch (MI->getOpcode()) {
     default: assert(0 && "illegal opcode!");
-    case X86::FP_TO_INT16_IN_MEM: Opc = X86::FpIST16m; break;
-    case X86::FP_TO_INT32_IN_MEM: Opc = X86::FpIST32m; break;
-    case X86::FP_TO_INT64_IN_MEM: Opc = X86::FpIST64m; break;
+    case X86::FP32_TO_INT16_IN_MEM: Opc = X86::IST_Fp16m32; break;
+    case X86::FP32_TO_INT32_IN_MEM: Opc = X86::IST_Fp32m32; break;
+    case X86::FP32_TO_INT64_IN_MEM: Opc = X86::IST_Fp64m32; break;
+    case X86::FP64_TO_INT16_IN_MEM: Opc = X86::IST_Fp16m64; break;
+    case X86::FP64_TO_INT32_IN_MEM: Opc = X86::IST_Fp32m64; break;
+    case X86::FP64_TO_INT64_IN_MEM: Opc = X86::IST_Fp64m64; break;
     }
 
     X86AddressMode AM;
@@ -4436,6 +4605,7 @@ void X86TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
                                                        uint64_t Mask,
                                                        uint64_t &KnownZero,
                                                        uint64_t &KnownOne,
+                                                       const SelectionDAG &DAG,
                                                        unsigned Depth) const {
   unsigned Opc = Op.getOpcode();
   assert((Opc >= ISD::BUILTIN_OP_END ||
@@ -4464,11 +4634,11 @@ static SDOperand getShuffleScalarElt(SDNode *N, unsigned i, SelectionDAG &DAG) {
   i %= NumElems;
   if (V.getOpcode() == ISD::SCALAR_TO_VECTOR) {
     return (i == 0)
-      ? V.getOperand(0) : DAG.getNode(ISD::UNDEF, MVT::getVectorBaseType(VT));
+      ? 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::getVectorBaseType(VT));
+      return DAG.getNode(ISD::UNDEF, MVT::getVectorElementType(VT));
     return getShuffleScalarElt(V.Val,cast<ConstantSDNode>(Idx)->getValue(),DAG);
   }
   return SDOperand();
@@ -4515,8 +4685,8 @@ static bool isConsecutiveLoad(SDNode *N, SDNode *Base, int Dist, int Size,
   if (Loc.getOpcode() == ISD::FrameIndex) {
     if (BaseLoc.getOpcode() != ISD::FrameIndex)
       return false;
-    int FI  = dyn_cast<FrameIndexSDNode>(Loc)->getIndex();
-    int BFI = dyn_cast<FrameIndexSDNode>(BaseLoc)->getIndex();
+    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;
@@ -4543,7 +4713,7 @@ static bool isBaseAlignment16(SDNode *Base, MachineFrameInfo *MFI,
     return (GV->getAlignment() >= 16 && (Offset % 16) == 0);
   else {
     assert(Base->getOpcode() == ISD::FrameIndex && "Unexpected base node!");
-    int BFI = dyn_cast<FrameIndexSDNode>(Base)->getIndex();
+    int BFI = cast<FrameIndexSDNode>(Base)->getIndex();
     if (BFI < 0)
       // Fixed objects do not specify alignment, however the offsets are known.
       return ((Subtarget->getStackAlignment() % 16) == 0 &&
@@ -4564,7 +4734,7 @@ static SDOperand PerformShuffleCombine(SDNode *N, SelectionDAG &DAG,
   MachineFunction &MF = DAG.getMachineFunction();
   MachineFrameInfo *MFI = MF.getFrameInfo();
   MVT::ValueType VT = N->getValueType(0);
-  MVT::ValueType EVT = MVT::getVectorBaseType(VT);
+  MVT::ValueType EVT = MVT::getVectorElementType(VT);
   SDOperand PermMask = N->getOperand(2);
   int NumElems = (int)PermMask.getNumOperands();
   SDNode *Base = NULL;
@@ -4848,7 +5018,6 @@ X86TargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
       case MVT::i64:
         return std::make_pair(0U, X86::FR64RegisterClass);
       // Vector types.
-      case MVT::Vector:
       case MVT::v16i8:
       case MVT::v8i16:
       case MVT::v4i32: