Handle some 64-bit atomics on x86-32, some of the time.
[oota-llvm.git] / lib / Target / X86 / X86ISelLowering.cpp
index 8f7b668ca0b9bcadbc6a6d48842de0a8d752310e..f65167bd8877862f5c8834d42cf5e345be645b69 100644 (file)
@@ -17,7 +17,6 @@
 #include "X86ISelLowering.h"
 #include "X86MachineFunctionInfo.h"
 #include "X86TargetMachine.h"
-#include "X86FastISel.h"
 #include "llvm/CallingConv.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
@@ -50,10 +49,11 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
   X86ScalarSSEf64 = Subtarget->hasSSE2();
   X86ScalarSSEf32 = Subtarget->hasSSE1();
   X86StackPtr = Subtarget->is64Bit() ? X86::RSP : X86::ESP;
-  
+
   bool Fast = false;
 
   RegInfo = TM.getRegisterInfo();
+  TD = getTargetData();
 
   // Set up the TargetLowering object.
 
@@ -259,8 +259,7 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
   }
   // X86 ret instruction may pop stack.
   setOperationAction(ISD::RET             , MVT::Other, Custom);
-  if (!Subtarget->is64Bit())
-    setOperationAction(ISD::EH_RETURN       , MVT::Other, Custom);
+  setOperationAction(ISD::EH_RETURN       , MVT::Other, Custom);
 
   // Darwin ABI issue.
   setOperationAction(ISD::ConstantPool    , MVT::i32  , Custom);
@@ -298,10 +297,20 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
   setOperationAction(ISD::ATOMIC_CMP_SWAP_32, MVT::i32, Custom);
   setOperationAction(ISD::ATOMIC_CMP_SWAP_64, MVT::i64, Custom);
 
-  setOperationAction(ISD::ATOMIC_LOAD_SUB_8, MVT::i8, Expand);
-  setOperationAction(ISD::ATOMIC_LOAD_SUB_16, MVT::i16, Expand);
-  setOperationAction(ISD::ATOMIC_LOAD_SUB_32, MVT::i32, Expand);
-  setOperationAction(ISD::ATOMIC_LOAD_SUB_64, MVT::i64, Expand);
+  setOperationAction(ISD::ATOMIC_LOAD_SUB_8 , MVT::i8, Custom);
+  setOperationAction(ISD::ATOMIC_LOAD_SUB_16, MVT::i16, Custom);
+  setOperationAction(ISD::ATOMIC_LOAD_SUB_32, MVT::i32, Custom);
+  setOperationAction(ISD::ATOMIC_LOAD_SUB_64, MVT::i64, Custom);
+
+  if (!Subtarget->is64Bit()) {
+    setOperationAction(ISD::ATOMIC_LOAD_ADD_64, MVT::i64, Custom);
+    setOperationAction(ISD::ATOMIC_LOAD_SUB_64, MVT::i64, Custom);
+    setOperationAction(ISD::ATOMIC_LOAD_AND_64, MVT::i64, Custom);
+    setOperationAction(ISD::ATOMIC_LOAD_OR_64, MVT::i64, Custom);
+    setOperationAction(ISD::ATOMIC_LOAD_XOR_64, MVT::i64, Custom);
+    setOperationAction(ISD::ATOMIC_LOAD_NAND_64, MVT::i64, Custom);
+    setOperationAction(ISD::ATOMIC_SWAP_64, MVT::i64, Custom);
+  }
 
   // Use the default ISD::DBG_STOPPOINT, ISD::DECLARE expansion.
   setOperationAction(ISD::DBG_STOPPOINT, MVT::Other, Expand);
@@ -318,7 +327,6 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
   setOperationAction(ISD::EXCEPTIONADDR, MVT::i32, Expand);
   setOperationAction(ISD::EHSELECTION,   MVT::i32, Expand);
   if (Subtarget->is64Bit()) {
-    // FIXME: Verify
     setExceptionPointerRegister(X86::RAX);
     setExceptionSelectorRegister(X86::RDX);
   } else {
@@ -326,7 +334,8 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
     setExceptionSelectorRegister(X86::EDX);
   }
   setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i32, Custom);
-  
+  setOperationAction(ISD::FRAME_TO_ARGS_OFFSET, MVT::i64, Custom);
+
   setOperationAction(ISD::TRAMPOLINE, MVT::Other, Custom);
 
   setOperationAction(ISD::TRAP, MVT::Other, Legal);
@@ -495,6 +504,12 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
   setOperationAction(ISD::FPOW             , MVT::f64  , Expand);
   setOperationAction(ISD::FPOW             , MVT::f80  , Expand);
 
+  setOperationAction(ISD::FLOG, MVT::f80, Expand);
+  setOperationAction(ISD::FLOG2, MVT::f80, Expand);
+  setOperationAction(ISD::FLOG10, MVT::f80, Expand);
+  setOperationAction(ISD::FEXP, MVT::f80, Expand);
+  setOperationAction(ISD::FEXP2, MVT::f80, Expand);
+
   // 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::FIRST_VECTOR_VALUETYPE;
@@ -537,6 +552,11 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM)
     setOperationAction(ISD::ROTR, (MVT::SimpleValueType)VT, Expand);
     setOperationAction(ISD::BSWAP, (MVT::SimpleValueType)VT, Expand);
     setOperationAction(ISD::VSETCC, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FLOG, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FLOG2, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FLOG10, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FEXP, (MVT::SimpleValueType)VT, Expand);
+    setOperationAction(ISD::FEXP2, (MVT::SimpleValueType)VT, Expand);
   }
 
   if (Subtarget->hasMMX()) {
@@ -798,7 +818,7 @@ static void getMaxByValAlign(const Type *Ty, unsigned &MaxAlign) {
 unsigned X86TargetLowering::getByValTypeAlignment(const Type *Ty) const {
   if (Subtarget->is64Bit()) {
     // Max of 8 and alignment of type.
-    unsigned TyAlign = getTargetData()->getABITypeAlignment(Ty);
+    unsigned TyAlign = TD->getABITypeAlignment(Ty);
     if (TyAlign > 8)
       return TyAlign;
     return 8;
@@ -870,7 +890,7 @@ SDValue X86TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) {
     SDValue TargetAddress = TailCall.getOperand(1);
     SDValue StackAdjustment = TailCall.getOperand(2);
     assert(((TargetAddress.getOpcode() == ISD::Register &&
-               (cast<RegisterSDNode>(TargetAddress)->getReg() == X86::ECX ||
+               (cast<RegisterSDNode>(TargetAddress)->getReg() == X86::EAX ||
                 cast<RegisterSDNode>(TargetAddress)->getReg() == X86::R9)) ||
               TargetAddress.getOpcode() == ISD::TargetExternalSymbol ||
               TargetAddress.getOpcode() == ISD::TargetGlobalAddress) && 
@@ -957,12 +977,12 @@ SDValue X86TargetLowering::LowerRET(SDValue Op, SelectionDAG &DAG) {
 /// being lowered.  The returns a SDNode with the same number of values as the
 /// ISD::CALL.
 SDNode *X86TargetLowering::
-LowerCallResult(SDValue Chain, SDValue InFlag, SDNode *TheCall, 
+LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, 
                 unsigned CallingConv, SelectionDAG &DAG) {
   
   // Assign locations to each value returned by this call.
   SmallVector<CCValAssign, 16> RVLocs;
-  bool isVarArg = cast<ConstantSDNode>(TheCall->getOperand(2))->getValue() != 0;
+  bool isVarArg = TheCall->isVarArg();
   CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs);
   CCInfo.AnalyzeCallResult(TheCall, RetCC_X86);
 
@@ -1027,12 +1047,12 @@ static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
 
 /// CallIsStructReturn - Determines whether a CALL node uses struct return
 /// semantics.
-static bool CallIsStructReturn(SDValue Op) {
-  unsigned NumOps = (Op.getNumOperands() - 5) / 2;
+static bool CallIsStructReturn(CallSDNode *TheCall) {
+  unsigned NumOps = TheCall->getNumArgs();
   if (!NumOps)
     return false;
 
-  return cast<ARG_FLAGSSDNode>(Op.getOperand(6))->getArgFlags().isSRet();
+  return TheCall->getArgFlags(0).isSRet();
 }
 
 /// ArgsAreStructReturn - Determines whether a FORMAL_ARGUMENTS node uses struct
@@ -1048,12 +1068,11 @@ static bool ArgsAreStructReturn(SDValue Op) {
 /// 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(SDValue Op) {
-  bool IsVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
+bool X86TargetLowering::IsCalleePop(bool IsVarArg, unsigned CallingConv) {
   if (IsVarArg)
     return false;
 
-  switch (cast<ConstantSDNode>(Op.getOperand(1))->getValue()) {
+  switch (CallingConv) {
   default:
     return false;
   case CallingConv::X86_StdCall:
@@ -1065,26 +1084,22 @@ bool X86TargetLowering::IsCalleePop(SDValue Op) {
   }
 }
 
-/// CCAssignFnForNode - Selects the correct CCAssignFn for a CALL or
-/// FORMAL_ARGUMENTS node.
-CCAssignFn *X86TargetLowering::CCAssignFnForNode(SDValue Op) const {
-  unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
-  
+/// CCAssignFnForNode - Selects the correct CCAssignFn for a the
+/// given CallingConvention value.
+CCAssignFn *X86TargetLowering::CCAssignFnForNode(unsigned CC) const {
   if (Subtarget->is64Bit()) {
     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;
-    }
+    else if (CC == CallingConv::Fast && PerformTailCallOpt)
+      return CC_X86_64_TailCall;
+    else
+      return CC_X86_64_C;
   }
 
   if (CC == CallingConv::X86_FastCall)
     return CC_X86_32_FastCall;
-  else if (CC == CallingConv::Fast && PerformTailCallOpt)
-    return CC_X86_32_TailCall;
+  else if (CC == CallingConv::Fast)
+    return CC_X86_32_FastCC;
   else
     return CC_X86_32_C;
 }
@@ -1093,7 +1108,7 @@ CCAssignFn *X86TargetLowering::CCAssignFnForNode(SDValue Op) const {
 /// apply to a MachineFunction containing a given FORMAL_ARGUMENTS node.
 NameDecorationStyle
 X86TargetLowering::NameDecorationForFORMAL_ARGUMENTS(SDValue Op) {
-  unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
+  unsigned CC = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
   if (CC == CallingConv::X86_FastCall)
     return FastCall;
   else if (CC == CallingConv::X86_StdCall)
@@ -1171,7 +1186,7 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) {
   
   MachineFrameInfo *MFI = MF.getFrameInfo();
   SDValue Root = Op.getOperand(0);
-  bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
+  bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getZExtValue() != 0;
   unsigned CC = MF.getFunction()->getCallingConv();
   bool Is64Bit = Subtarget->is64Bit();
   bool IsWin64 = Subtarget->isTargetWin64();
@@ -1182,7 +1197,7 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) {
   // Assign locations to all of the incoming arguments.
   SmallVector<CCValAssign, 16> ArgLocs;
   CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
-  CCInfo.AnalyzeFormalArguments(Op.getNode(), CCAssignFnForNode(Op));
+  CCInfo.AnalyzeFormalArguments(Op.getNode(), CCAssignFnForNode(CC));
   
   SmallVector<SDValue, 8> ArgValues;
   unsigned LastVal = ~0U;
@@ -1277,7 +1292,7 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) {
 
   unsigned StackSize = CCInfo.getNextStackOffset();
   // align stack specially for tail calls
-  if (CC == CallingConv::Fast)
+  if (PerformTailCallOpt && CC == CallingConv::Fast)
     StackSize = GetAlignedArgumentStackSize(StackSize, DAG);
 
   // If the function takes variable number of arguments, make a frame index for
@@ -1364,24 +1379,16 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) {
     }
   }
   
-  // Make sure the instruction takes 8n+4 bytes to make sure the start of the
-  // arguments and the arguments after the retaddr has been pushed are
-  // aligned.
-  if (!Is64Bit && CC == CallingConv::X86_FastCall &&
-      !Subtarget->isTargetCygMing() && !Subtarget->isTargetWindows() &&
-      (StackSize & 7) == 0)
-    StackSize += 4;
-
   ArgValues.push_back(Root);
 
   // Some CCs need callee pop.
-  if (IsCalleePop(Op)) {
+  if (IsCalleePop(isVarArg, CC)) {
     BytesToPopOnReturn  = StackSize; // Callee pops everything.
     BytesCallerReserves = 0;
   } else {
     BytesToPopOnReturn  = 0; // Callee pops nothing.
     // If this is an sret function, the return should pop the hidden pointer.
-    if (!Is64Bit && ArgsAreStructReturn(Op))
+    if (!Is64Bit && CC != CallingConv::Fast && ArgsAreStructReturn(Op))
       BytesToPopOnReturn = 4;  
     BytesCallerReserves = StackSize;
   }
@@ -1400,16 +1407,14 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) {
 }
 
 SDValue
-X86TargetLowering::LowerMemOpCallTo(SDValue Op, SelectionDAG &DAG,
+X86TargetLowering::LowerMemOpCallTo(CallSDNode *TheCall, SelectionDAG &DAG,
                                     const SDValue &StackPtr,
                                     const CCValAssign &VA,
                                     SDValue Chain,
-                                    SDValue Arg) {
+                                    SDValue Arg, ISD::ArgFlagsTy Flags) {
   unsigned LocMemOffset = VA.getLocMemOffset();
   SDValue PtrOff = DAG.getIntPtrConstant(LocMemOffset);
   PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
-  ISD::ArgFlagsTy Flags =
-    cast<ARG_FLAGSSDNode>(Op.getOperand(6+2*VA.getValNo()))->getArgFlags();
   if (Flags.isByVal()) {
     return CreateCopyOfByValArgument(Arg, PtrOff, Chain, Flags, DAG);
   }
@@ -1457,14 +1462,15 @@ EmitTailCallStoreRetAddr(SelectionDAG & DAG, MachineFunction &MF,
 
 SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
   MachineFunction &MF = DAG.getMachineFunction();
-  SDValue Chain       = Op.getOperand(0);
-  unsigned CC         = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
-  bool isVarArg       = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0;
-  bool IsTailCall     = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0
-                        && CC == CallingConv::Fast && PerformTailCallOpt;
-  SDValue Callee      = Op.getOperand(4);
+  CallSDNode *TheCall = cast<CallSDNode>(Op.getNode());
+  SDValue Chain       = TheCall->getChain();
+  unsigned CC         = TheCall->getCallingConv();
+  bool isVarArg       = TheCall->isVarArg();
+  bool IsTailCall     = TheCall->isTailCall() &&
+                        CC == CallingConv::Fast && PerformTailCallOpt;
+  SDValue Callee      = TheCall->getCallee();
   bool Is64Bit        = Subtarget->is64Bit();
-  bool IsStructRet    = CallIsStructReturn(Op);
+  bool IsStructRet    = CallIsStructReturn(TheCall);
 
   assert(!(isVarArg && CC == CallingConv::Fast) &&
          "Var args not supported with calling convention fastcc");
@@ -1472,20 +1478,13 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
   // Analyze operands of the call, assigning locations to each operand.
   SmallVector<CCValAssign, 16> ArgLocs;
   CCState CCInfo(CC, isVarArg, getTargetMachine(), ArgLocs);
-  CCInfo.AnalyzeCallOperands(Op.getNode(), CCAssignFnForNode(Op));
+  CCInfo.AnalyzeCallOperands(TheCall, CCAssignFnForNode(CC));
   
   // Get a count of how many bytes are to be pushed on the stack.
   unsigned NumBytes = CCInfo.getNextStackOffset();
-  if (CC == CallingConv::Fast)
+  if (PerformTailCallOpt && CC == CallingConv::Fast)
     NumBytes = GetAlignedArgumentStackSize(NumBytes, DAG);
 
-  // Make sure the instruction takes 8n+4 bytes to make sure the start of the
-  // arguments and the arguments after the retaddr has been pushed are aligned.
-  if (!Is64Bit && CC == CallingConv::X86_FastCall &&
-      !Subtarget->isTargetCygMing() && !Subtarget->isTargetWindows() &&
-      (NumBytes & 7) == 0)
-    NumBytes += 4;
-
   int FPDiff = 0;
   if (IsTailCall) {
     // Lower arguments at fp - stackoffset + fpdiff.
@@ -1514,9 +1513,9 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
   // of tail call optimization arguments are handle later.
   for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) {
     CCValAssign &VA = ArgLocs[i];
-    SDValue Arg = Op.getOperand(5+2*VA.getValNo());
-    bool isByVal = cast<ARG_FLAGSSDNode>(Op.getOperand(6+2*VA.getValNo()))->
-      getArgFlags().isByVal();
+    SDValue Arg = TheCall->getArg(i);
+    ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i);
+    bool isByVal = Flags.isByVal();
   
     // Promote the value if needed.
     switch (VA.getLocInfo()) {
@@ -1565,8 +1564,8 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
         if (StackPtr.getNode() == 0)
           StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr, getPointerTy());
         
-        MemOpChains.push_back(LowerMemOpCallTo(Op, DAG, StackPtr, VA, Chain,
-                                               Arg));
+        MemOpChains.push_back(LowerMemOpCallTo(TheCall, DAG, StackPtr, VA,
+                                               Chain, Arg, Flags));
       }
     }
   }
@@ -1604,7 +1603,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
   if (CallRequiresFnAddressInReg(Is64Bit, IsTailCall)) {
     // Note: The actual moving to ecx is done further down.
     GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee);
-    if (G &&  !G->getGlobal()->hasHiddenVisibility() &&
+    if (G && !G->getGlobal()->hasHiddenVisibility() &&
         !G->getGlobal()->hasProtectedVisibility())
       Callee =  LowerGlobalAddress(Callee, DAG);
     else if (isa<ExternalSymbolSDNode>(Callee))
@@ -1645,10 +1644,8 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
       CCValAssign &VA = ArgLocs[i];
       if (!VA.isRegLoc()) {
         assert(VA.isMemLoc());
-        SDValue Arg = Op.getOperand(5+2*VA.getValNo());
-        SDValue FlagsOp = Op.getOperand(6+2*VA.getValNo());
-        ISD::ArgFlagsTy Flags =
-          cast<ARG_FLAGSSDNode>(FlagsOp)->getArgFlags();
+        SDValue Arg = TheCall->getArg(i);
+        ISD::ArgFlagsTy Flags = TheCall->getArgFlags(i);
         // Create frame index.
         int32_t Offset = VA.getLocMemOffset()+FPDiff;
         uint32_t OpSize = (VA.getLocVT().getSizeInBits()+7)/8;
@@ -1701,7 +1698,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
   } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
     Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
   } else if (IsTailCall) {
-    unsigned Opc = Is64Bit ? X86::R9 : X86::ECX;
+    unsigned Opc = Is64Bit ? X86::R9 : X86::EAX;
 
     Chain = DAG.getCopyToReg(Chain, 
                              DAG.getRegister(Opc, getPointerTy()), 
@@ -1758,7 +1755,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
     assert(InFlag.getNode() && 
            "Flag must be set. Depend on flag being set in LowerRET");
     Chain = DAG.getNode(X86ISD::TAILCALL,
-                        Op.getNode()->getVTList(), &Ops[0], Ops.size());
+                        TheCall->getVTList(), &Ops[0], Ops.size());
       
     return SDValue(Chain.getNode(), Op.getResNo());
   }
@@ -1768,9 +1765,9 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
 
   // Create the CALLSEQ_END node.
   unsigned NumBytesForCalleeToPush;
-  if (IsCalleePop(Op))
+  if (IsCalleePop(isVarArg, CC))
     NumBytesForCalleeToPush = NumBytes;    // Callee pops everything
-  else if (!Is64Bit && IsStructRet)
+  else if (!Is64Bit && CC != CallingConv::Fast && IsStructRet)
     // If this is is a call to a struct-return function, the callee
     // pops the hidden struct pointer, so we have to push it back.
     // This is common for Darwin/X86, Linux & Mingw32 targets.
@@ -1787,7 +1784,7 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
 
   // Handle result values, copying them out of physregs into vregs that we
   // return.
-  return SDValue(LowerCallResult(Chain, InFlag, Op.getNode(), CC, DAG),
+  return SDValue(LowerCallResult(Chain, InFlag, TheCall, CC, DAG),
                  Op.getResNo());
 }
 
@@ -1827,43 +1824,40 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) {
 /// for a 16 byte align requirement.
 unsigned X86TargetLowering::GetAlignedArgumentStackSize(unsigned StackSize, 
                                                         SelectionDAG& DAG) {
-  if (PerformTailCallOpt) {
-    MachineFunction &MF = DAG.getMachineFunction();
-    const TargetMachine &TM = MF.getTarget();
-    const TargetFrameInfo &TFI = *TM.getFrameInfo();
-    unsigned StackAlignment = TFI.getStackAlignment();
-    uint64_t AlignMask = StackAlignment - 1; 
-    int64_t Offset = StackSize;
-    unsigned SlotSize = Subtarget->is64Bit() ? 8 : 4;
-    if ( (Offset & AlignMask) <= (StackAlignment - SlotSize) ) {
-      // Number smaller than 12 so just add the difference.
-      Offset += ((StackAlignment - SlotSize) - (Offset & AlignMask));
-    } else {
-      // Mask out lower bits, add stackalignment once plus the 12 bytes.
-      Offset = ((~AlignMask) & Offset) + StackAlignment + 
-        (StackAlignment-SlotSize);
-    }
-    StackSize = Offset;
+  MachineFunction &MF = DAG.getMachineFunction();
+  const TargetMachine &TM = MF.getTarget();
+  const TargetFrameInfo &TFI = *TM.getFrameInfo();
+  unsigned StackAlignment = TFI.getStackAlignment();
+  uint64_t AlignMask = StackAlignment - 1; 
+  int64_t Offset = StackSize;
+  uint64_t SlotSize = TD->getPointerSize();
+  if ( (Offset & AlignMask) <= (StackAlignment - SlotSize) ) {
+    // Number smaller than 12 so just add the difference.
+    Offset += ((StackAlignment - SlotSize) - (Offset & AlignMask));
+  } else {
+    // Mask out lower bits, add stackalignment once plus the 12 bytes.
+    Offset = ((~AlignMask) & Offset) + StackAlignment + 
+      (StackAlignment-SlotSize);
   }
-  return StackSize;
+  return Offset;
 }
 
 /// IsEligibleForTailCallElimination - Check to see whether the next instruction
 /// following the call is a return. A function is eligible if caller/callee
 /// calling conventions match, currently only fastcc supports tail calls, and
 /// the function CALL is immediatly followed by a RET.
-bool X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Call,
+bool X86TargetLowering::IsEligibleForTailCallOptimization(CallSDNode *TheCall,
                                                       SDValue Ret,
                                                       SelectionDAG& DAG) const {
   if (!PerformTailCallOpt)
     return false;
 
-  if (CheckTailCallReturnConstraints(Call, Ret)) {
+  if (CheckTailCallReturnConstraints(TheCall, Ret)) {
     MachineFunction &MF = DAG.getMachineFunction();
     unsigned CallerCC = MF.getFunction()->getCallingConv();
-    unsigned CalleeCC = cast<ConstantSDNode>(Call.getOperand(1))->getValue();
+    unsigned CalleeCC= TheCall->getCallingConv();
     if (CalleeCC == CallingConv::Fast && CallerCC == CalleeCC) {
-      SDValue Callee = Call.getOperand(4);
+      SDValue Callee = TheCall->getCallee();
       // On x86/32Bit PIC/GOT  tail calls are supported.
       if (getTargetMachine().getRelocationModel() != Reloc::PIC_ ||
           !Subtarget->isPICStyleGOT()|| !Subtarget->is64Bit())
@@ -1880,8 +1874,15 @@ bool X86TargetLowering::IsEligibleForTailCallOptimization(SDValue Call,
   return false;
 }
 
-FastISel *X86TargetLowering::createFastISel(MachineFunction &mf) {
-  return X86::createFastISel(mf);
+FastISel *
+X86TargetLowering::createFastISel(MachineFunction &mf,
+                                  MachineModuleInfo *mmo,
+                                  DenseMap<const Value *, unsigned> &vm,
+                                  DenseMap<const BasicBlock *,
+                                           MachineBasicBlock *> &bm,
+                                  DenseMap<const AllocaInst *, int> &am) {
+                                         
+  return X86::createFastISel(mf, mmo, vm, bm, am);
 }
 
 
@@ -1894,14 +1895,11 @@ SDValue X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) {
   MachineFunction &MF = DAG.getMachineFunction();
   X86MachineFunctionInfo *FuncInfo = MF.getInfo<X86MachineFunctionInfo>();
   int ReturnAddrIndex = FuncInfo->getRAIndex();
+  uint64_t SlotSize = TD->getPointerSize();
 
   if (ReturnAddrIndex == 0) {
     // Set up a frame object for the return address.
-    if (Subtarget->is64Bit())
-      ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(8, -8);
-    else
-      ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(4, -4);
-
+    ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(SlotSize, -SlotSize);
     FuncInfo->setRAIndex(ReturnAddrIndex);
   }
 
@@ -1909,7 +1907,6 @@ SDValue X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) {
 }
 
 
-
 /// translateX86CC - do a one to one translation of a ISD::CondCode to the X86
 /// specific condition code. It returns a false if it cannot do a direct
 /// translation. X86CC is the translated CondCode.  LHS/RHS are modified as
@@ -1929,7 +1926,7 @@ static bool translateX86CC(ISD::CondCode SetCCOpcode, bool isFP,
         // X < 0   -> X == 0, jump on sign.
         X86CC = X86::COND_S;
         return true;
-      } else if (SetCCOpcode == ISD::SETLT && RHSC->getValue() == 1) {
+      } else if (SetCCOpcode == ISD::SETLT && RHSC->getZExtValue() == 1) {
         // X < 1   -> X <= 0
         RHS = DAG.getConstant(0, RHS.getValueType());
         X86CC = X86::COND_LE;
@@ -1951,36 +1948,71 @@ static bool translateX86CC(ISD::CondCode SetCCOpcode, bool isFP,
     case ISD::SETUGE: X86CC = X86::COND_AE; break;
     }
   } else {
+    // First determine if it requires or is profitable to flip the operands.
+    bool Flip = false;
+    switch (SetCCOpcode) {
+    default: break;
+    case ISD::SETOLT:
+    case ISD::SETOLE:
+    case ISD::SETUGT:
+    case ISD::SETUGE:
+      Flip = true;
+      break;
+    }
+
+    // If LHS is a foldable load, but RHS is not, flip the condition.
+    if (!Flip &&
+        (ISD::isNON_EXTLoad(LHS.getNode()) && LHS.hasOneUse()) &&
+        !(ISD::isNON_EXTLoad(RHS.getNode()) && RHS.hasOneUse())) {
+      SetCCOpcode = getSetCCSwappedOperands(SetCCOpcode);
+      Flip = true;
+    }
+    if (Flip)
+      std::swap(LHS, RHS);
+
     // On a floating point condition, the flags are set as follows:
     // ZF  PF  CF   op
     //  0 | 0 | 0 | X > Y
     //  0 | 0 | 1 | X < Y
     //  1 | 0 | 0 | X == Y
     //  1 | 1 | 1 | unordered
-    bool Flip = false;
     switch (SetCCOpcode) {
     default: break;
     case ISD::SETUEQ:
-    case ISD::SETEQ: X86CC = X86::COND_E;  break;
-    case ISD::SETOLT: Flip = true; // Fallthrough
+    case ISD::SETEQ:
+      X86CC = X86::COND_E;
+      break;
+    case ISD::SETOLT:              // flipped
     case ISD::SETOGT:
-    case ISD::SETGT: X86CC = X86::COND_A;  break;
-    case ISD::SETOLE: Flip = true; // Fallthrough
+    case ISD::SETGT:
+      X86CC = X86::COND_A;
+      break;
+    case ISD::SETOLE:              // flipped
     case ISD::SETOGE:
-    case ISD::SETGE: X86CC = X86::COND_AE; break;
-    case ISD::SETUGT: Flip = true; // Fallthrough
+    case ISD::SETGE:
+      X86CC = X86::COND_AE;
+      break;
+    case ISD::SETUGT:              // flipped
     case ISD::SETULT:
-    case ISD::SETLT: X86CC = X86::COND_B;  break;
-    case ISD::SETUGE: Flip = true; // Fallthrough
+    case ISD::SETLT:
+      X86CC = X86::COND_B;
+      break;
+    case ISD::SETUGE:              // flipped
     case ISD::SETULE:
-    case ISD::SETLE: X86CC = X86::COND_BE; break;
+    case ISD::SETLE:
+      X86CC = X86::COND_BE;
+      break;
     case ISD::SETONE:
-    case ISD::SETNE: X86CC = X86::COND_NE; break;
-    case ISD::SETUO: X86CC = X86::COND_P;  break;
-    case ISD::SETO:  X86CC = X86::COND_NP; break;
+    case ISD::SETNE:
+      X86CC = X86::COND_NE;
+      break;
+    case ISD::SETUO:
+      X86CC = X86::COND_P;
+      break;
+    case ISD::SETO:
+      X86CC = X86::COND_NP;
+      break;
     }
-    if (Flip)
-      std::swap(LHS, RHS);
   }
 
   return X86CC != X86::COND_INVALID;
@@ -2011,7 +2043,7 @@ static bool isUndefOrInRange(SDValue Op, unsigned Low, unsigned Hi) {
   if (Op.getOpcode() == ISD::UNDEF)
     return true;
 
-  unsigned Val = cast<ConstantSDNode>(Op)->getValue();
+  unsigned Val = cast<ConstantSDNode>(Op)->getZExtValue();
   return (Val >= Low && Val < Hi);
 }
 
@@ -2020,7 +2052,7 @@ static bool isUndefOrInRange(SDValue Op, unsigned Low, unsigned Hi) {
 static bool isUndefOrEqual(SDValue Op, unsigned Val) {
   if (Op.getOpcode() == ISD::UNDEF)
     return true;
-  return cast<ConstantSDNode>(Op)->getValue() == Val;
+  return cast<ConstantSDNode>(Op)->getZExtValue() == Val;
 }
 
 /// isPSHUFDMask - Return true if the specified VECTOR_SHUFFLE operand
@@ -2036,7 +2068,7 @@ bool X86::isPSHUFDMask(SDNode *N) {
     SDValue Arg = N->getOperand(i);
     if (Arg.getOpcode() == ISD::UNDEF) continue;
     assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
-    if (cast<ConstantSDNode>(Arg)->getValue() >= e)
+    if (cast<ConstantSDNode>(Arg)->getZExtValue() >= e)
       return false;
   }
 
@@ -2056,7 +2088,7 @@ bool X86::isPSHUFHWMask(SDNode *N) {
     SDValue Arg = N->getOperand(i);
     if (Arg.getOpcode() == ISD::UNDEF) continue;
     assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
-    if (cast<ConstantSDNode>(Arg)->getValue() != i)
+    if (cast<ConstantSDNode>(Arg)->getZExtValue() != i)
       return false;
   }
 
@@ -2065,7 +2097,7 @@ bool X86::isPSHUFHWMask(SDNode *N) {
     SDValue Arg = N->getOperand(i);
     if (Arg.getOpcode() == ISD::UNDEF) continue;
     assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
-    unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
+    unsigned Val = cast<ConstantSDNode>(Arg)->getZExtValue();
     if (Val < 4 || Val > 7)
       return false;
   }
@@ -2381,7 +2413,7 @@ bool X86::isMOVSHDUPMask(SDNode *N) {
     SDValue Arg = N->getOperand(i);
     if (Arg.getOpcode() == ISD::UNDEF) continue;
     assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
-    unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
+    unsigned Val = cast<ConstantSDNode>(Arg)->getZExtValue();
     if (Val != 1) return false;
   }
 
@@ -2390,7 +2422,7 @@ bool X86::isMOVSHDUPMask(SDNode *N) {
     SDValue Arg = N->getOperand(i);
     if (Arg.getOpcode() == ISD::UNDEF) continue;
     assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
-    unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
+    unsigned Val = cast<ConstantSDNode>(Arg)->getZExtValue();
     if (Val != 3) return false;
     HasHi = true;
   }
@@ -2412,7 +2444,7 @@ bool X86::isMOVSLDUPMask(SDNode *N) {
     SDValue Arg = N->getOperand(i);
     if (Arg.getOpcode() == ISD::UNDEF) continue;
     assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
-    unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
+    unsigned Val = cast<ConstantSDNode>(Arg)->getZExtValue();
     if (Val != 0) return false;
   }
 
@@ -2421,7 +2453,7 @@ bool X86::isMOVSLDUPMask(SDNode *N) {
     SDValue Arg = N->getOperand(i);
     if (Arg.getOpcode() == ISD::UNDEF) continue;
     assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
-    unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
+    unsigned Val = cast<ConstantSDNode>(Arg)->getZExtValue();
     if (Val != 2) return false;
     HasHi = true;
   }
@@ -2469,7 +2501,7 @@ static bool isSplatMask(SDNode *N) {
   }
 
   // Make sure it is a splat of the first vector operand.
-  return cast<ConstantSDNode>(ElementBase)->getValue() < NumElems;
+  return cast<ConstantSDNode>(ElementBase)->getZExtValue() < NumElems;
 }
 
 /// isSplatMask - Return true if the specified VECTOR_SHUFFLE operand specifies
@@ -2494,6 +2526,21 @@ bool X86::isSplatLoMask(SDNode *N) {
   return true;
 }
 
+/// isMOVDDUPMask - Return true if the specified VECTOR_SHUFFLE operand
+/// specifies a shuffle of elements that is suitable for input to MOVDDUP.
+bool X86::isMOVDDUPMask(SDNode *N) {
+  assert(N->getOpcode() == ISD::BUILD_VECTOR);
+
+  unsigned e = N->getNumOperands() / 2;
+  for (unsigned i = 0; i < e; ++i)
+    if (!isUndefOrEqual(N->getOperand(i), i))
+      return false;
+  for (unsigned i = 0; i < e; ++i)
+    if (!isUndefOrEqual(N->getOperand(e+i), i))
+      return false;
+  return true;
+}
+
 /// getShuffleSHUFImmediate - Return the appropriate immediate to shuffle
 /// the specified isShuffleMask VECTOR_SHUFFLE mask with PSHUF* and SHUFP*
 /// instructions.
@@ -2505,7 +2552,7 @@ unsigned X86::getShuffleSHUFImmediate(SDNode *N) {
     unsigned Val = 0;
     SDValue Arg = N->getOperand(NumOperands-i-1);
     if (Arg.getOpcode() != ISD::UNDEF)
-      Val = cast<ConstantSDNode>(Arg)->getValue();
+      Val = cast<ConstantSDNode>(Arg)->getZExtValue();
     if (Val >= NumOperands) Val -= NumOperands;
     Mask |= Val;
     if (i != NumOperands - 1)
@@ -2525,7 +2572,7 @@ unsigned X86::getShufflePSHUFHWImmediate(SDNode *N) {
     unsigned Val = 0;
     SDValue Arg = N->getOperand(i);
     if (Arg.getOpcode() != ISD::UNDEF)
-      Val = cast<ConstantSDNode>(Arg)->getValue();
+      Val = cast<ConstantSDNode>(Arg)->getZExtValue();
     Mask |= (Val - 4);
     if (i != 4)
       Mask <<= 2;
@@ -2544,7 +2591,7 @@ unsigned X86::getShufflePSHUFLWImmediate(SDNode *N) {
     unsigned Val = 0;
     SDValue Arg = N->getOperand(i);
     if (Arg.getOpcode() != ISD::UNDEF)
-      Val = cast<ConstantSDNode>(Arg)->getValue();
+      Val = cast<ConstantSDNode>(Arg)->getZExtValue();
     Mask |= Val;
     if (i != 0)
       Mask <<= 2;
@@ -2567,7 +2614,7 @@ static bool isPSHUFHW_PSHUFLWMask(SDNode *N) {
     SDValue Arg = N->getOperand(i);
     if (Arg.getOpcode() == ISD::UNDEF) continue;
     assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
-    unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
+    unsigned Val = cast<ConstantSDNode>(Arg)->getZExtValue();
     if (Val >= 4)
       return false;
   }
@@ -2577,7 +2624,7 @@ static bool isPSHUFHW_PSHUFLWMask(SDNode *N) {
     SDValue Arg = N->getOperand(i);
     if (Arg.getOpcode() == ISD::UNDEF) continue;
     assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
-    unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
+    unsigned Val = cast<ConstantSDNode>(Arg)->getZExtValue();
     if (Val < 4 || Val > 7)
       return false;
   }
@@ -2603,7 +2650,7 @@ static SDValue CommuteVectorShuffle(SDValue Op, SDValue &V1,
       continue;
     }
     assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
-    unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
+    unsigned Val = cast<ConstantSDNode>(Arg)->getZExtValue();
     if (Val < NumElems)
       MaskVec.push_back(DAG.getConstant(Val + NumElems, EltVT));
     else
@@ -2630,7 +2677,7 @@ SDValue CommuteVectorShuffleMask(SDValue Mask, SelectionDAG &DAG) {
       continue;
     }
     assert(isa<ConstantSDNode>(Arg) && "Invalid VECTOR_SHUFFLE mask!");
-    unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
+    unsigned Val = cast<ConstantSDNode>(Arg)->getZExtValue();
     if (Val < NumElems)
       MaskVec.push_back(DAG.getConstant(Val + NumElems, EltVT));
     else
@@ -2661,15 +2708,14 @@ static bool ShouldXformToMOVHLPS(SDNode *Mask) {
 /// 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).getNode();
-    if (ISD::isNON_EXTLoad(N)) {
-      if (LD)
-        *LD = cast<LoadSDNode>(N);
-      return true;
-    }
-  }
-  return false;
+  if (N->getOpcode() != ISD::SCALAR_TO_VECTOR)
+    return false;
+  N = N->getOperand(0).getNode();
+  if (!ISD::isNON_EXTLoad(N))
+    return false;
+  if (LD)
+    *LD = cast<LoadSDNode>(N);
+  return true;
 }
 
 /// ShouldXformToMOVLP{S|D} - Return true if the node should be transformed to
@@ -2723,7 +2769,7 @@ static bool isUndefShuffle(SDNode *N) {
   for (unsigned i = 0; i != NumElems; ++i) {
     SDValue Arg = Mask.getOperand(i);
     if (Arg.getOpcode() != ISD::UNDEF) {
-      unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
+      unsigned Val = cast<ConstantSDNode>(Arg)->getZExtValue();
       if (Val < NumElems && V1.getOpcode() != ISD::UNDEF)
         return false;
       else if (Val >= NumElems && V2.getOpcode() != ISD::UNDEF)
@@ -2737,7 +2783,7 @@ static bool isUndefShuffle(SDNode *N) {
 /// constant +0.0.
 static inline bool isZeroNode(SDValue Elt) {
   return ((isa<ConstantSDNode>(Elt) &&
-           cast<ConstantSDNode>(Elt)->getValue() == 0) ||
+           cast<ConstantSDNode>(Elt)->getZExtValue() == 0) ||
           (isa<ConstantFPSDNode>(Elt) &&
            cast<ConstantFPSDNode>(Elt)->getValueAPF().isPosZero()));
 }
@@ -2757,7 +2803,7 @@ static bool isZeroShuffle(SDNode *N) {
     if (Arg.getOpcode() == ISD::UNDEF)
       continue;
     
-    unsigned Idx = cast<ConstantSDNode>(Arg)->getValue();
+    unsigned Idx = cast<ConstantSDNode>(Arg)->getZExtValue();
     if (Idx < NumElems) {
       unsigned Opc = V1.getNode()->getOpcode();
       if (Opc == ISD::UNDEF || ISD::isBuildVectorAllZeros(V1.getNode()))
@@ -2826,7 +2872,7 @@ static SDValue NormalizeMask(SDValue Mask, SelectionDAG &DAG) {
   for (unsigned i = 0; i != NumElems; ++i) {
     SDValue Arg = Mask.getOperand(i);
     if (Arg.getOpcode() != ISD::UNDEF) {
-      unsigned Val = cast<ConstantSDNode>(Arg)->getValue();
+      unsigned Val = cast<ConstantSDNode>(Arg)->getZExtValue();
       if (Val > NumElems) {
         Arg = DAG.getConstant(NumElems, Arg.getValueType());
         Changed = true;
@@ -2921,6 +2967,46 @@ static SDValue PromoteSplat(SDValue Op, SelectionDAG &DAG, bool HasSSE2) {
   return DAG.getNode(ISD::BIT_CONVERT, VT, Shuffle);
 }
 
+/// isVectorLoad - Returns true if the node is a vector load, a scalar
+/// load that's promoted to vector, or a load bitcasted.
+static bool isVectorLoad(SDValue Op) {
+  assert(Op.getValueType().isVector() && "Expected a vector type");
+  if (Op.getOpcode() == ISD::SCALAR_TO_VECTOR ||
+      Op.getOpcode() == ISD::BIT_CONVERT) {
+    return isa<LoadSDNode>(Op.getOperand(0));
+  }
+  return isa<LoadSDNode>(Op);
+}
+
+
+/// CanonicalizeMovddup - Cannonicalize movddup shuffle to v2f64.
+///
+static SDValue CanonicalizeMovddup(SDValue Op, SDValue V1, SDValue Mask,
+                                   SelectionDAG &DAG, bool HasSSE3) {
+  // If we have sse3 and shuffle has more than one use or input is a load, then
+  // use movddup. Otherwise, use movlhps.
+  bool UseMovddup = HasSSE3 && (!Op.hasOneUse() || isVectorLoad(V1));
+  MVT PVT = UseMovddup ? MVT::v2f64 : MVT::v4f32;
+  MVT VT = Op.getValueType();
+  if (VT == PVT)
+    return Op;
+  unsigned NumElems = PVT.getVectorNumElements();
+  if (NumElems == 2) {
+    SDValue Cst = DAG.getTargetConstant(0, MVT::i32);
+    Mask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i32, Cst, Cst);
+  } else {
+    assert(NumElems == 4);
+    SDValue Cst0 = DAG.getTargetConstant(0, MVT::i32);
+    SDValue Cst1 = DAG.getTargetConstant(1, MVT::i32);
+    Mask = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Cst0, Cst1, Cst0, Cst1);
+  }
+
+  V1 = DAG.getNode(ISD::BIT_CONVERT, PVT, V1);
+  SDValue Shuffle = DAG.getNode(ISD::VECTOR_SHUFFLE, PVT, V1,
+                                DAG.getNode(ISD::UNDEF, PVT), Mask);
+  return DAG.getNode(ISD::BIT_CONVERT, VT, Shuffle);
+}
+
 /// getShuffleVectorZeroOrUndef - Return a vector_shuffle of the specified
 /// 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
@@ -2990,7 +3076,7 @@ static bool isVectorShift(SDValue Op, SDValue Mask, SelectionDAG &DAG,
     SDValue Idx = Mask.getOperand(isLeft ? i : (i - NumZeros));
     if (Idx.getOpcode() == ISD::UNDEF)
       continue;
-    unsigned Index = cast<ConstantSDNode>(Idx)->getValue();
+    unsigned Index = cast<ConstantSDNode>(Idx)->getZExtValue();
     if (Index < NumElems)
       SeenV1 = true;
     else {
@@ -3355,7 +3441,7 @@ SDValue LowerVECTOR_SHUFFLEv8i16(SDValue V1, SDValue V2,
     SDValue Elt = MaskElts[i];
     if (Elt.getOpcode() == ISD::UNDEF)
       continue;
-    unsigned EltIdx = cast<ConstantSDNode>(Elt)->getValue();
+    unsigned EltIdx = cast<ConstantSDNode>(Elt)->getZExtValue();
     int QuadIdx = EltIdx / 4;
     ++LowQuad[QuadIdx];
   }
@@ -3375,7 +3461,7 @@ SDValue LowerVECTOR_SHUFFLEv8i16(SDValue V1, SDValue V2,
     SDValue Elt = MaskElts[i];
     if (Elt.getOpcode() == ISD::UNDEF)
       continue;
-    unsigned EltIdx = cast<ConstantSDNode>(Elt)->getValue();
+    unsigned EltIdx = cast<ConstantSDNode>(Elt)->getZExtValue();
     int QuadIdx = EltIdx / 4;
     ++HighQuad[QuadIdx];
   }
@@ -3423,7 +3509,7 @@ SDValue LowerVECTOR_SHUFFLEv8i16(SDValue V1, SDValue V2,
           MaskVec.push_back(Elt);
           InOrder.set(i);
         } else {
-          unsigned EltIdx = cast<ConstantSDNode>(Elt)->getValue();
+          unsigned EltIdx = cast<ConstantSDNode>(Elt)->getZExtValue();
           if (EltIdx != i)
             AnyOutOrder = true;
 
@@ -3457,7 +3543,7 @@ SDValue LowerVECTOR_SHUFFLEv8i16(SDValue V1, SDValue V2,
           MaskVec.push_back(Elt);
           InOrder.set(i);
         } else {
-          unsigned EltIdx = cast<ConstantSDNode>(Elt)->getValue();
+          unsigned EltIdx = cast<ConstantSDNode>(Elt)->getZExtValue();
           if (EltIdx != i)
             AnyOutOrder = true;
 
@@ -3483,7 +3569,7 @@ SDValue LowerVECTOR_SHUFFLEv8i16(SDValue V1, SDValue V2,
       SDValue Elt = MaskElts[i];
       if (Elt.getOpcode() == ISD::UNDEF)
         continue;
-      unsigned EltIdx = cast<ConstantSDNode>(Elt)->getValue();
+      unsigned EltIdx = cast<ConstantSDNode>(Elt)->getZExtValue();
       SDValue ExtOp = (EltIdx < 8)
         ? DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, V1,
                       DAG.getConstant(EltIdx, PtrVT))
@@ -3514,7 +3600,7 @@ SDValue LowerVECTOR_SHUFFLEv8i16(SDValue V1, SDValue V2,
       ++V2InOrder;
       continue;
     }
-    unsigned EltIdx = cast<ConstantSDNode>(Elt)->getValue();
+    unsigned EltIdx = cast<ConstantSDNode>(Elt)->getZExtValue();
     if (EltIdx == i) {
       V1Elts.push_back(Elt);
       V2Elts.push_back(DAG.getConstant(i+8, MaskEVT));
@@ -3551,7 +3637,7 @@ SDValue LowerVECTOR_SHUFFLEv8i16(SDValue V1, SDValue V2,
           MaskVec.push_back(DAG.getNode(ISD::UNDEF, MaskEVT));
           continue;
         }
-        unsigned EltIdx = cast<ConstantSDNode>(Elt)->getValue();
+        unsigned EltIdx = cast<ConstantSDNode>(Elt)->getZExtValue();
         if (EltIdx >= 8)
           MaskVec.push_back(DAG.getNode(ISD::UNDEF, MaskEVT));
         else
@@ -3566,7 +3652,7 @@ SDValue LowerVECTOR_SHUFFLEv8i16(SDValue V1, SDValue V2,
       SDValue Elt = V1Elts[i];
       if (Elt.getOpcode() == ISD::UNDEF)
         continue;
-      unsigned EltIdx = cast<ConstantSDNode>(Elt)->getValue();
+      unsigned EltIdx = cast<ConstantSDNode>(Elt)->getZExtValue();
       if (EltIdx < 8)
         continue;
       SDValue ExtOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, V2,
@@ -3582,7 +3668,7 @@ SDValue LowerVECTOR_SHUFFLEv8i16(SDValue V1, SDValue V2,
       SDValue Elt = V1Elts[i];
       if (Elt.getOpcode() == ISD::UNDEF)
         continue;
-      unsigned EltIdx = cast<ConstantSDNode>(Elt)->getValue();
+      unsigned EltIdx = cast<ConstantSDNode>(Elt)->getZExtValue();
       SDValue ExtOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i16, V1,
                                     DAG.getConstant(EltIdx, PtrVT));
       NewV = DAG.getNode(ISD::INSERT_VECTOR_ELT, MVT::v8i16, NewV, ExtOp,
@@ -3629,7 +3715,7 @@ SDValue RewriteAsNarrowerShuffle(SDValue V1, SDValue V2,
       SDValue Elt = PermMask.getOperand(i+j);
       if (Elt.getOpcode() == ISD::UNDEF)
         continue;
-      unsigned EltIdx = cast<ConstantSDNode>(Elt)->getValue();
+      unsigned EltIdx = cast<ConstantSDNode>(Elt)->getZExtValue();
       if (StartIdx == ~0U)
         StartIdx = EltIdx - (EltIdx % Scale);
       if (EltIdx != StartIdx + j)
@@ -3698,7 +3784,7 @@ LowerVECTOR_SHUFFLE_4wide(SDValue V1, SDValue V2,
     if (Elt.getOpcode() == ISD::UNDEF) {
       Locs[i] = std::make_pair(-1, -1);
     } else {
-      unsigned Val = cast<ConstantSDNode>(Elt)->getValue();
+      unsigned Val = cast<ConstantSDNode>(Elt)->getZExtValue();
       assert(Val < 8 && "Invalid VECTOR_SHUFFLE index!");
       if (Val < 4) {
         Locs[i] = std::make_pair(0, NumLo);
@@ -3756,7 +3842,7 @@ LowerVECTOR_SHUFFLE_4wide(SDValue V1, SDValue V2,
       SDValue Elt = PermMask.getOperand(HiIndex);
       if (Elt.getOpcode() == ISD::UNDEF)
         continue;
-      unsigned Val = cast<ConstantSDNode>(Elt)->getValue();
+      unsigned Val = cast<ConstantSDNode>(Elt)->getZExtValue();
       if (Val >= 4)
         break;
     }
@@ -3781,11 +3867,13 @@ LowerVECTOR_SHUFFLE_4wide(SDValue V1, SDValue V2,
       Mask1[2] = PermMask.getOperand(2);
       Mask1[3] = PermMask.getOperand(3);
       if (Mask1[2].getOpcode() != ISD::UNDEF)
-        Mask1[2] = DAG.getConstant(cast<ConstantSDNode>(Mask1[2])->getValue()+4,
-                                   MaskEVT);
+        Mask1[2] =
+          DAG.getConstant(cast<ConstantSDNode>(Mask1[2])->getZExtValue()+4,
+                          MaskEVT);
       if (Mask1[3].getOpcode() != ISD::UNDEF)
-        Mask1[3] = DAG.getConstant(cast<ConstantSDNode>(Mask1[3])->getValue()+4,
-                                   MaskEVT);
+        Mask1[3] =
+          DAG.getConstant(cast<ConstantSDNode>(Mask1[3])->getZExtValue()+4,
+                          MaskEVT);
       return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, V2, V1,
                          DAG.getNode(ISD::BUILD_VECTOR, MaskVT, &Mask1[0], 4));
     }
@@ -3809,7 +3897,7 @@ LowerVECTOR_SHUFFLE_4wide(SDValue V1, SDValue V2,
     SDValue Elt = PermMask.getOperand(i);
     if (Elt.getOpcode() == ISD::UNDEF) {
       Locs[i] = std::make_pair(-1, -1);
-    } else if (cast<ConstantSDNode>(Elt)->getValue() < 4) {
+    } else if (cast<ConstantSDNode>(Elt)->getZExtValue() < 4) {
       Locs[i] = std::make_pair(MaskIdx, LoIdx);
       (*MaskPtr)[LoIdx] = Elt;
       LoIdx++;
@@ -3864,6 +3952,11 @@ X86TargetLowering::LowerVECTOR_SHUFFLE(SDValue Op, SelectionDAG &DAG) {
   else if (isIdentityMask(PermMask.getNode(), true))
     return V2;
 
+  // Canonicalize movddup shuffles.
+  if (V2IsUndef && Subtarget->hasSSE2() &&
+      X86::isMOVDDUPMask(PermMask.getNode()))
+    return CanonicalizeMovddup(Op, V1, PermMask, DAG, Subtarget->hasSSE3());
+
   if (isSplatMask(PermMask.getNode())) {
     if (isMMX || NumElems < 4) return Op;
     // Promote it to a v4{if}32 splat.
@@ -4105,7 +4198,7 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
   // TODO: handle v16i8.
   if (VT.getSizeInBits() == 16) {
     SDValue Vec = Op.getOperand(0);
-    unsigned Idx = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
+    unsigned Idx = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
     if (Idx == 0)
       return DAG.getNode(ISD::TRUNCATE, MVT::i16,
                          DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::i32,
@@ -4119,7 +4212,7 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
                                     DAG.getValueType(VT));
     return DAG.getNode(ISD::TRUNCATE, VT, Assert);
   } else if (VT.getSizeInBits() == 32) {
-    unsigned Idx = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
+    unsigned Idx = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
     if (Idx == 0)
       return Op;
     // SHUFPS the element to the lowest double word, then movss.
@@ -4144,7 +4237,7 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
     // 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.
-    unsigned Idx = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
+    unsigned Idx = cast<ConstantSDNode>(Op.getOperand(1))->getZExtValue();
     if (Idx == 0)
       return Op;
 
@@ -4186,7 +4279,7 @@ X86TargetLowering::LowerINSERT_VECTOR_ELT_SSE4(SDValue Op, SelectionDAG &DAG){
     if (N1.getValueType() != MVT::i32)
       N1 = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, N1);
     if (N2.getValueType() != MVT::i32)
-      N2 = DAG.getIntPtrConstant(cast<ConstantSDNode>(N2)->getValue());
+      N2 = DAG.getIntPtrConstant(cast<ConstantSDNode>(N2)->getZExtValue());
     return DAG.getNode(Opc, VT, N0, N1, N2);
   } else if (EVT == MVT::f32 && isa<ConstantSDNode>(N2)) {
     // Bits [7:6] of the constant are the source select.  This will always be
@@ -4197,7 +4290,7 @@ X86TargetLowering::LowerINSERT_VECTOR_ELT_SSE4(SDValue Op, SelectionDAG &DAG){
     //  value of the incoming immediate.
     // Bits [3:0] of the constant are the zero mask.  The DAG Combiner may 
     //   combine either bitwise AND or insert of float 0.0 to set these bits.
-    N2 = DAG.getIntPtrConstant(cast<ConstantSDNode>(N2)->getValue() << 4);
+    N2 = DAG.getIntPtrConstant(cast<ConstantSDNode>(N2)->getZExtValue() << 4);
     return DAG.getNode(X86ISD::INSERTPS, VT, N0, N1, N2);
   }
   return SDValue();
@@ -4224,7 +4317,7 @@ X86TargetLowering::LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) {
     if (N1.getValueType() != MVT::i32)
       N1 = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, N1);
     if (N2.getValueType() != MVT::i32)
-      N2 = DAG.getIntPtrConstant(cast<ConstantSDNode>(N2)->getValue());
+      N2 = DAG.getIntPtrConstant(cast<ConstantSDNode>(N2)->getZExtValue());
     return DAG.getNode(X86ISD::PINSRW, VT, N0, N1, N2);
   }
   return SDValue();
@@ -4276,8 +4369,8 @@ X86TargetLowering::LowerConstantPool(SDValue Op, SelectionDAG &DAG) {
 }
 
 SDValue
-X86TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) {
-  GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
+X86TargetLowering::LowerGlobalAddress(const GlobalValue *GV,
+                                      SelectionDAG &DAG) const {
   SDValue Result = DAG.getTargetGlobalAddress(GV, getPointerTy());
   Result = DAG.getNode(X86ISD::Wrapper, getPointerTy(), Result);
   // With PIC, the address is actually $g + Offset.
@@ -4300,6 +4393,12 @@ X86TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) {
   return Result;
 }
 
+SDValue
+X86TargetLowering::LowerGlobalAddress(SDValue Op, SelectionDAG &DAG) {
+  const GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal();
+  return LowerGlobalAddress(GV, DAG);
+}
+
 // Lower ISD::GlobalTLSAddress using the "general dynamic" model, 32 bit
 static SDValue
 LowerToTLSGeneralDynamicModel32(GlobalAddressSDNode *GA, SelectionDAG &DAG,
@@ -4930,7 +5029,7 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) {
     bool IllegalFPCMov = false;
     if (VT.isFloatingPoint() && !VT.isVector() &&
         !isScalarFPTypeInSSEReg(VT))  // FPStack?
-      IllegalFPCMov = !hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended());
+      IllegalFPCMov = !hasFPCMov(cast<ConstantSDNode>(CC)->getSExtValue());
     
     if ((Opc == X86ISD::CMP ||
          Opc == X86ISD::COMI ||
@@ -5039,26 +5138,29 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDValue Op,
 
 SDValue
 X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG,
-                                        SDValue Chain,
-                                        SDValue Dst, SDValue Src,
-                                        SDValue Size, unsigned Align,
-                                        const Value *DstSV, uint64_t DstSVOff) {
+                                           SDValue Chain,
+                                           SDValue Dst, SDValue Src,
+                                           SDValue 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 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()) {
+      ConstantSize->getZExtValue() >
+        getSubtarget()->getMaxInlineSizeThreshold()) {
     SDValue 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) {
+
+    if (const char *bzeroEntry =  V &&
+        V->isNullValue() ? Subtarget->getBZeroEntry() : 0) {
       MVT IntPtr = getPointerTy();
-      const Type *IntPtrTy = getTargetData()->getIntPtrType();
+      const Type *IntPtrTy = TD->getIntPtrType();
       TargetLowering::ArgListTy Args; 
       TargetLowering::ArgListEntry Entry;
       Entry.Node = Dst;
@@ -5067,9 +5169,9 @@ X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG,
       Entry.Node = Size;
       Args.push_back(Entry);
       std::pair<SDValue,SDValue> CallResult =
-        LowerCallTo(Chain, Type::VoidTy, false, false, false, CallingConv::C,
-                    false, DAG.getExternalSymbol(bzeroEntry, IntPtr),
-                    Args, DAG);
+        LowerCallTo(Chain, Type::VoidTy, false, false, false, false, 
+                    CallingConv::C, false, 
+                    DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, DAG);
       return CallResult.second;
     }
 
@@ -5077,7 +5179,7 @@ X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG,
     return SDValue();
   }
 
-  uint64_t SizeVal = ConstantSize->getValue();
+  uint64_t SizeVal = ConstantSize->getZExtValue();
   SDValue InFlag(0, 0);
   MVT AVT;
   SDValue Count;
@@ -5086,7 +5188,7 @@ X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG,
   bool TwoRepStos = false;
   if (ValC) {
     unsigned ValReg;
-    uint64_t Val = ValC->getValue() & 255;
+    uint64_t Val = ValC->getZExtValue() & 255;
 
     // If the value is a constant, then we can potentially use larger sets.
     switch (Align & 3) {
@@ -5188,7 +5290,7 @@ X86TargetLowering::EmitTargetCodeForMemcpy(SelectionDAG &DAG,
   ConstantSDNode *ConstantSize = dyn_cast<ConstantSDNode>(Size);
   if (!ConstantSize)
     return SDValue();
-  uint64_t SizeVal = ConstantSize->getValue();
+  uint64_t SizeVal = ConstantSize->getZExtValue();
   if (!AlwaysInline && SizeVal > getSubtarget()->getMaxInlineSizeThreshold())
     return SDValue();
 
@@ -5348,7 +5450,7 @@ SDValue X86TargetLowering::LowerVACOPY(SDValue Op, SelectionDAG &DAG) {
 
 SDValue
 X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) {
-  unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getValue();
+  unsigned IntNo = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
   switch (IntNo) {
   default: return SDValue();    // Don't custom lower most intrinsics.
   // Comparison intrinsics.
@@ -5546,7 +5648,7 @@ X86TargetLowering::LowerINTRINSIC_WO_CHAIN(SDValue Op, SelectionDAG &DAG) {
 
 SDValue X86TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
   // Depths > 0 not supported yet!
-  if (cast<ConstantSDNode>(Op.getOperand(0))->getValue() > 0)
+  if (cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue() > 0)
     return SDValue();
   
   // Just load the return address
@@ -5555,46 +5657,43 @@ SDValue X86TargetLowering::LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
 }
 
 SDValue X86TargetLowering::LowerFRAMEADDR(SDValue Op, SelectionDAG &DAG) {
-  // Depths > 0 not supported yet!
-  if (cast<ConstantSDNode>(Op.getOperand(0))->getValue() > 0)
-    return SDValue();
-    
-  SDValue RetAddrFI = getReturnAddressFrameIndex(DAG);
-  return DAG.getNode(ISD::SUB, getPointerTy(), RetAddrFI, 
-                     DAG.getIntPtrConstant(!Subtarget->is64Bit() ? 4 : 8));
+  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
+  MFI->setFrameAddressIsTaken(true);
+  MVT VT = Op.getValueType();
+  unsigned Depth = cast<ConstantSDNode>(Op.getOperand(0))->getZExtValue();
+  unsigned FrameReg = Subtarget->is64Bit() ? X86::RBP : X86::EBP;
+  SDValue FrameAddr = DAG.getCopyFromReg(DAG.getEntryNode(), FrameReg, VT);
+  while (Depth--)
+    FrameAddr = DAG.getLoad(VT, DAG.getEntryNode(), FrameAddr, NULL, 0);
+  return FrameAddr;
 }
 
 SDValue X86TargetLowering::LowerFRAME_TO_ARGS_OFFSET(SDValue Op,
-                                                       SelectionDAG &DAG) {
-  // Is not yet supported on x86-64
-  if (Subtarget->is64Bit())
-    return SDValue();
-  
-  return DAG.getIntPtrConstant(8);
+                                                     SelectionDAG &DAG) {
+  return DAG.getIntPtrConstant(2*TD->getPointerSize());
 }
 
 SDValue X86TargetLowering::LowerEH_RETURN(SDValue Op, SelectionDAG &DAG)
 {
-  assert(!Subtarget->is64Bit() &&
-         "Lowering of eh_return builtin is not supported yet on x86-64");
-    
   MachineFunction &MF = DAG.getMachineFunction();
   SDValue Chain     = Op.getOperand(0);
   SDValue Offset    = Op.getOperand(1);
   SDValue Handler   = Op.getOperand(2);
 
-  SDValue Frame = DAG.getRegister(RegInfo->getFrameRegister(MF),
-                                    getPointerTy());
+  SDValue Frame = DAG.getRegister(Subtarget->is64Bit() ? X86::RBP : X86::EBP,
+                                  getPointerTy());
+  unsigned StoreAddrReg = (Subtarget->is64Bit() ? X86::RCX : X86::ECX);
 
   SDValue StoreAddr = DAG.getNode(ISD::SUB, getPointerTy(), Frame,
-                                    DAG.getIntPtrConstant(-4UL));
+                                  DAG.getIntPtrConstant(-TD->getPointerSize()));
   StoreAddr = DAG.getNode(ISD::ADD, getPointerTy(), StoreAddr, Offset);
   Chain = DAG.getStore(Chain, Handler, StoreAddr, NULL, 0);
-  Chain = DAG.getCopyToReg(Chain, X86::ECX, StoreAddr);
-  MF.getRegInfo().addLiveOut(X86::ECX);
+  Chain = DAG.getCopyToReg(Chain, StoreAddrReg, StoreAddr);
+  MF.getRegInfo().addLiveOut(StoreAddrReg);
 
-  return DAG.getNode(X86ISD::EH_RETURN, MVT::Other,
-                     Chain, DAG.getRegister(X86::ECX, getPointerTy()));
+  return DAG.getNode(X86ISD::EH_RETURN,
+                     MVT::Other,
+                     Chain, DAG.getRegister(StoreAddrReg, getPointerTy()));
 }
 
 SDValue X86TargetLowering::LowerTRAMPOLINE(SDValue Op,
@@ -5672,7 +5771,7 @@ SDValue X86TargetLowering::LowerTRAMPOLINE(SDValue Op,
 
       // Check that ECX wasn't needed by an 'inreg' parameter.
       const FunctionType *FTy = Func->getFunctionType();
-      const PAListPtr &Attrs = Func->getParamAttrs();
+      const AttrListPtr &Attrs = Func->getAttributes();
 
       if (!Attrs.isEmpty() && !Func->isVarArg()) {
         unsigned InRegCount = 0;
@@ -5680,9 +5779,9 @@ SDValue X86TargetLowering::LowerTRAMPOLINE(SDValue Op,
 
         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, Attribute::InReg))
             // FIXME: should only count parameters that are lowered to integers.
-            InRegCount += (getTargetData()->getTypeSizeInBits(*I) + 31) / 32;
+            InRegCount += (TD->getTypeSizeInBits(*I) + 31) / 32;
 
         if (InRegCount > 2) {
           cerr << "Nest register in use - reduce number of inreg parameters!\n";
@@ -5692,6 +5791,7 @@ SDValue X86TargetLowering::LowerTRAMPOLINE(SDValue Op,
       break;
     }
     case CallingConv::X86_FastCall:
+    case CallingConv::Fast:
       // Pass 'nest' parameter in EAX.
       // Must be kept in sync with X86CallingConv.td
       NestReg = X86::EAX;
@@ -5757,7 +5857,7 @@ SDValue X86TargetLowering::LowerFLT_ROUNDS_(SDValue Op, SelectionDAG &DAG) {
   SDValue StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
 
   SDValue Chain = DAG.getNode(X86ISD::FNSTCW16m, MVT::Other,
-                                DAG.getEntryNode(), StackSlot);
+                              DAG.getEntryNode(), StackSlot);
 
   // Load FP Control Word from stack slot
   SDValue CWD = DAG.getLoad(MVT::i16, Chain, StackSlot, NULL, 0);
@@ -5864,12 +5964,12 @@ SDValue X86TargetLowering::LowerCMP_SWAP(SDValue Op, SelectionDAG &DAG) {
     break;
   };
   SDValue cpIn = DAG.getCopyToReg(Op.getOperand(0), Reg,
-                                    Op.getOperand(3), SDValue());
+                                    Op.getOperand(2), SDValue());
   SDValue Ops[] = { cpIn.getValue(0),
-                      Op.getOperand(1),
-                      Op.getOperand(2),
-                      DAG.getTargetConstant(size, MVT::i8),
-                      cpIn.getValue(1) };
+                    Op.getOperand(1),
+                    Op.getOperand(3),
+                    DAG.getTargetConstant(size, MVT::i8),
+                    cpIn.getValue(1) };
   SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
   SDValue Result = DAG.getNode(X86ISD::LCMPXCHG_DAG, Tys, Ops, 5);
   SDValue cpOut = 
@@ -5882,26 +5982,26 @@ SDNode* X86TargetLowering::ExpandATOMIC_CMP_SWAP(SDNode* Op,
   MVT T = Op->getValueType(0);
   assert (T == MVT::i64 && "Only know how to expand i64 Cmp and Swap");
   SDValue cpInL, cpInH;
-  cpInL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(3),
+  cpInL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(2),
                       DAG.getConstant(0, MVT::i32));
-  cpInH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(3),
+  cpInH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(2),
                       DAG.getConstant(1, MVT::i32));
   cpInL = DAG.getCopyToReg(Op->getOperand(0), X86::EAX,
                            cpInL, SDValue());
   cpInH = DAG.getCopyToReg(cpInL.getValue(0), X86::EDX,
                            cpInH, cpInL.getValue(1));
   SDValue swapInL, swapInH;
-  swapInL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(2),
+  swapInL = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(3),
                         DAG.getConstant(0, MVT::i32));
-  swapInH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(2),
+  swapInH = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op->getOperand(3),
                         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));
   SDValue Ops[] = { swapInH.getValue(0),
-                      Op->getOperand(1),
-                      swapInH.getValue(1)};
+                    Op->getOperand(1),
+                    swapInH.getValue(1) };
   SDVTList Tys = DAG.getVTList(MVT::Other, MVT::Flag);
   SDValue Result = DAG.getNode(X86ISD::LCMPXCHG8_DAG, Tys, Ops, 3);
   SDValue cpOutL = DAG.getCopyFromReg(Result.getValue(0), X86::EAX, MVT::i32, 
@@ -5914,18 +6014,43 @@ SDNode* X86TargetLowering::ExpandATOMIC_CMP_SWAP(SDNode* Op,
   return DAG.getMergeValues(Vals, 2).getNode();
 }
 
-SDNode* X86TargetLowering::ExpandATOMIC_LOAD_SUB(SDNode* Op,
-                                                 SelectionDAG &DAG) {
-  MVT T = Op->getValueType(0);
+SDValue X86TargetLowering::LowerATOMIC_BINARY_64(SDValue Op,
+                                                 SelectionDAG &DAG,
+                                                 unsigned NewOp) {
+  SDNode *Node = Op.getNode();
+  MVT T = Node->getValueType(0);
+  assert (T == MVT::i64 && "Only know how to expand i64 atomics");
+  
+  SDValue Chain = Node->getOperand(0);
+  SDValue In1 = Node->getOperand(1);
+  assert(Node->getOperand(2).getNode()->getOpcode()==ISD::BUILD_PAIR);
+  SDValue In2L = Node->getOperand(2).getNode()->getOperand(0);
+  SDValue In2H = Node->getOperand(2).getNode()->getOperand(1);
+  SDValue Ops[] = { Chain, In1, In2L, In2H };
+  SDVTList Tys = DAG.getVTList(MVT::i32, MVT::i32, MVT::Other);
+  SDValue Result = DAG.getNode(NewOp, Tys, Ops, 4);
+  SDValue OpsF[] = { Result.getValue(0), Result.getValue(1)};
+  SDValue ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OpsF, 2);
+  SDValue Vals[2] = { ResultVal, Result.getValue(2) };
+  return SDValue(DAG.getMergeValues(Vals, 2).getNode(), 0);
+}
+
+SDValue X86TargetLowering::LowerLOAD_SUB(SDValue Op, SelectionDAG &DAG) {
+  SDNode *Node = Op.getNode();
+  MVT T = Node->getValueType(0);
   SDValue negOp = DAG.getNode(ISD::SUB, T,
-                                DAG.getConstant(0, T), Op->getOperand(2));
-  return DAG.getAtomic((T==MVT::i8 ? ISD::ATOMIC_LOAD_ADD_8:
-                        T==MVT::i16 ? ISD::ATOMIC_LOAD_ADD_16:
-                        T==MVT::i32 ? ISD::ATOMIC_LOAD_ADD_32:
-                        T==MVT::i64 ? ISD::ATOMIC_LOAD_ADD_64: 0),
-                       Op->getOperand(0), Op->getOperand(1), negOp,
-                       cast<AtomicSDNode>(Op)->getSrcValue(),
-                       cast<AtomicSDNode>(Op)->getAlignment()).getNode();
+                                DAG.getConstant(0, T), Node->getOperand(2));
+  return DAG.getAtomic((Op.getOpcode()==ISD::ATOMIC_LOAD_SUB_8 ? 
+                                        ISD::ATOMIC_LOAD_ADD_8 :
+                        Op.getOpcode()==ISD::ATOMIC_LOAD_SUB_16 ? 
+                                        ISD::ATOMIC_LOAD_ADD_16 :
+                        Op.getOpcode()==ISD::ATOMIC_LOAD_SUB_32 ? 
+                                        ISD::ATOMIC_LOAD_ADD_32 :
+                                        ISD::ATOMIC_LOAD_ADD_64),
+                       Node->getOperand(0),
+                       Node->getOperand(1), negOp,
+                       cast<AtomicSDNode>(Node)->getSrcValue(),
+                       cast<AtomicSDNode>(Node)->getAlignment());
 }
 
 /// LowerOperation - Provide custom lowering hooks for some operations.
@@ -5933,10 +6058,27 @@ SDNode* X86TargetLowering::ExpandATOMIC_LOAD_SUB(SDNode* Op,
 SDValue X86TargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) {
   switch (Op.getOpcode()) {
   default: assert(0 && "Should not custom lower this!");
-  case ISD::ATOMIC_CMP_SWAP_8:  return LowerCMP_SWAP(Op,DAG);
-  case ISD::ATOMIC_CMP_SWAP_16: return LowerCMP_SWAP(Op,DAG);
-  case ISD::ATOMIC_CMP_SWAP_32: return LowerCMP_SWAP(Op,DAG);
+  case ISD::ATOMIC_CMP_SWAP_8:  
+  case ISD::ATOMIC_CMP_SWAP_16: 
+  case ISD::ATOMIC_CMP_SWAP_32: 
   case ISD::ATOMIC_CMP_SWAP_64: return LowerCMP_SWAP(Op,DAG);
+  case ISD::ATOMIC_LOAD_SUB_8:  
+  case ISD::ATOMIC_LOAD_SUB_16: 
+  case ISD::ATOMIC_LOAD_SUB_32: return LowerLOAD_SUB(Op,DAG);
+  case ISD::ATOMIC_LOAD_SUB_64: return (Subtarget->is64Bit()) ?
+                                  LowerLOAD_SUB(Op,DAG) :
+                                  LowerATOMIC_BINARY_64(Op,DAG,
+                                        X86ISD::ATOMSUB64_DAG);
+  case ISD::ATOMIC_LOAD_AND_64: return LowerATOMIC_BINARY_64(Op,DAG,
+                                        X86ISD::ATOMAND64_DAG);
+  case ISD::ATOMIC_LOAD_OR_64: return LowerATOMIC_BINARY_64(Op, DAG,
+                                        X86ISD::ATOMOR64_DAG);
+  case ISD::ATOMIC_LOAD_XOR_64: return LowerATOMIC_BINARY_64(Op,DAG,
+                                        X86ISD::ATOMXOR64_DAG);
+  case ISD::ATOMIC_LOAD_NAND_64: return LowerATOMIC_BINARY_64(Op,DAG,
+                                        X86ISD::ATOMNAND64_DAG);
+  case ISD::ATOMIC_LOAD_ADD_64: return LowerATOMIC_BINARY_64(Op,DAG,
+                                        X86ISD::ATOMADD64_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);
@@ -5991,10 +6133,6 @@ SDNode *X86TargetLowering::ReplaceNodeResults(SDNode *N, SelectionDAG &DAG) {
   case ISD::FP_TO_SINT:         return ExpandFP_TO_SINT(N, DAG);
   case ISD::READCYCLECOUNTER:   return ExpandREADCYCLECOUNTER(N, DAG);
   case ISD::ATOMIC_CMP_SWAP_64: return ExpandATOMIC_CMP_SWAP(N, DAG);
-  case ISD::ATOMIC_LOAD_SUB_8:  return ExpandATOMIC_LOAD_SUB(N,DAG);
-  case ISD::ATOMIC_LOAD_SUB_16: return ExpandATOMIC_LOAD_SUB(N,DAG);
-  case ISD::ATOMIC_LOAD_SUB_32: return ExpandATOMIC_LOAD_SUB(N,DAG);
-  case ISD::ATOMIC_LOAD_SUB_64: return ExpandATOMIC_LOAD_SUB(N,DAG);
   }
 }
 
@@ -6046,6 +6184,12 @@ const char *X86TargetLowering::getTargetNodeName(unsigned Opcode) const {
   case X86ISD::FNSTCW16m:          return "X86ISD::FNSTCW16m";
   case X86ISD::LCMPXCHG_DAG:       return "X86ISD::LCMPXCHG_DAG";
   case X86ISD::LCMPXCHG8_DAG:      return "X86ISD::LCMPXCHG8_DAG";
+  case X86ISD::ATOMADD64_DAG:      return "X86ISD::ATOMADD64_DAG";
+  case X86ISD::ATOMSUB64_DAG:      return "X86ISD::ATOMSUB64_DAG";
+  case X86ISD::ATOMOR64_DAG:       return "X86ISD::ATOMOR64_DAG";
+  case X86ISD::ATOMXOR64_DAG:      return "X86ISD::ATOMXOR64_DAG";
+  case X86ISD::ATOMAND64_DAG:      return "X86ISD::ATOMAND64_DAG";
+  case X86ISD::ATOMNAND64_DAG:     return "X86ISD::ATOMNAND64_DAG";
   case X86ISD::VZEXT_MOVL:         return "X86ISD::VZEXT_MOVL";
   case X86ISD::VZEXT_LOAD:         return "X86ISD::VZEXT_LOAD";
   case X86ISD::VSHL:               return "X86ISD::VSHL";
@@ -6241,9 +6385,10 @@ X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr,
     tt = t1;
 
   unsigned t2 = F->getRegInfo().createVirtualRegister(RC);
-  assert(   (argOpers[valArgIndx]->isReg() || argOpers[valArgIndx]->isImm())
-         && "invalid operand");
-  if (argOpers[valArgIndx]->isReg())
+  assert((argOpers[valArgIndx]->isRegister() ||
+          argOpers[valArgIndx]->isImmediate()) &&
+         "invalid operand");
+  if (argOpers[valArgIndx]->isRegister())
     MIB = BuildMI(newMBB, TII->get(regOpc), t2);
   else
     MIB = BuildMI(newMBB, TII->get(immOpc), t2);
@@ -6270,6 +6415,146 @@ X86TargetLowering::EmitAtomicBitwiseWithCustomInserter(MachineInstr *bInstr,
   return nextMBB;
 }
 
+// private utility function
+MachineBasicBlock *
+X86TargetLowering::EmitAtomicBit6432WithCustomInserter(MachineInstr *bInstr,
+                                                       MachineBasicBlock *MBB,
+                                                       unsigned regOpcL,
+                                                       unsigned regOpcH,
+                                                       unsigned immOpcL,
+                                                       unsigned immOpcH,
+                                                       bool invSrc) {
+  // For the atomic bitwise operator, we generate
+  //   thisMBB (instructions are in pairs, except cmpxchg8b)
+  //     ld t1,t2 = [bitinstr.addr]
+  //   newMBB:
+  //     out1, out2 = phi (thisMBB, t1/t2) (newMBB, t3/t4)
+  //     op  t5, t6 <- out1, out2, [bitinstr.val]
+  //     mov ECX, EBX <- t5, t6
+  //     mov EAX, EDX <- t1, t2
+  //     cmpxchg8b [bitinstr.addr]  [EAX, EDX, EBX, ECX implicit]
+  //     mov t3, t4 <- EAX, EDX
+  //     bz  newMBB
+  //     result in out1, out2
+  //     fallthrough -->nextMBB
+
+  const TargetRegisterClass *RC = X86::GR32RegisterClass;
+  const unsigned LoadOpc = X86::MOV32rm;
+  const unsigned copyOpc = X86::MOV32rr;
+  const unsigned NotOpc = X86::NOT32r;
+  const TargetInstrInfo *TII = getTargetMachine().getInstrInfo();
+  const BasicBlock *LLVM_BB = MBB->getBasicBlock();
+  MachineFunction::iterator MBBIter = MBB;
+  ++MBBIter;
+  
+  /// First build the CFG
+  MachineFunction *F = MBB->getParent();
+  MachineBasicBlock *thisMBB = MBB;
+  MachineBasicBlock *newMBB = F->CreateMachineBasicBlock(LLVM_BB);
+  MachineBasicBlock *nextMBB = F->CreateMachineBasicBlock(LLVM_BB);
+  F->insert(MBBIter, newMBB);
+  F->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
+  // There are 8 "real" operands plus 9 implicit def/uses, ignored here.
+  assert(bInstr->getNumOperands() < 18 && "unexpected number of operands");
+  MachineOperand& dest1Oper = bInstr->getOperand(0);
+  MachineOperand& dest2Oper = bInstr->getOperand(1);
+  MachineOperand* argOpers[6];
+  for (int i=0; i < 6; ++i)
+    argOpers[i] = &bInstr->getOperand(i+2);
+
+  // x86 address has 4 operands: base, index, scale, and displacement
+  int lastAddrIndx = 3; // [0,3]
+  
+  unsigned t1 = F->getRegInfo().createVirtualRegister(RC);
+  MachineInstrBuilder MIB = BuildMI(thisMBB, TII->get(LoadOpc), t1);
+  for (int i=0; i <= lastAddrIndx; ++i)
+    (*MIB).addOperand(*argOpers[i]);
+  unsigned t2 = F->getRegInfo().createVirtualRegister(RC);
+  MIB = BuildMI(thisMBB, TII->get(LoadOpc), t2);
+  // add 4 to displacement.  getImm verifies it's immediate.
+  for (int i=0; i <= lastAddrIndx-1; ++i)
+    (*MIB).addOperand(*argOpers[i]);
+  MachineOperand newOp3 = MachineOperand::CreateImm(argOpers[3]->getImm()+4);
+  (*MIB).addOperand(newOp3);
+
+  // t3/4 are defined later, at the bottom of the loop
+  unsigned t3 = F->getRegInfo().createVirtualRegister(RC);
+  unsigned t4 = F->getRegInfo().createVirtualRegister(RC);
+  BuildMI(newMBB, TII->get(X86::PHI), dest1Oper.getReg())
+    .addReg(t1).addMBB(thisMBB).addReg(t3).addMBB(newMBB);
+  BuildMI(newMBB, TII->get(X86::PHI), dest2Oper.getReg())
+    .addReg(t2).addMBB(thisMBB).addReg(t4).addMBB(newMBB);
+
+  unsigned tt1 = F->getRegInfo().createVirtualRegister(RC);
+  unsigned tt2 = F->getRegInfo().createVirtualRegister(RC);
+  if (invSrc) {  
+    MIB = BuildMI(newMBB, TII->get(NotOpc), tt1).addReg(t1);
+    MIB = BuildMI(newMBB, TII->get(NotOpc), tt2).addReg(t2);
+  } else {
+    tt1 = t1;
+    tt2 = t2;
+  }
+
+  assert((argOpers[4]->isRegister() || argOpers[4]->isImmediate()) &&
+         "invalid operand");
+  unsigned t5 = F->getRegInfo().createVirtualRegister(RC);
+  unsigned t6 = F->getRegInfo().createVirtualRegister(RC);
+  if (argOpers[4]->isRegister())
+    MIB = BuildMI(newMBB, TII->get(regOpcL), t5);
+  else
+    MIB = BuildMI(newMBB, TII->get(immOpcL), t5);
+  MIB.addReg(tt1);
+  (*MIB).addOperand(*argOpers[4]);
+  assert(argOpers[5]->isRegister() == argOpers[4]->isRegister());
+  assert(argOpers[5]->isImmediate() == argOpers[4]->isImmediate());
+  if (argOpers[5]->isRegister())
+    MIB = BuildMI(newMBB, TII->get(regOpcH), t6);
+  else
+    MIB = BuildMI(newMBB, TII->get(immOpcH), t6);
+  MIB.addReg(tt2);
+  (*MIB).addOperand(*argOpers[5]);
+
+  MIB = BuildMI(newMBB, TII->get(copyOpc), X86::EAX);
+  MIB.addReg(t1);
+  MIB = BuildMI(newMBB, TII->get(copyOpc), X86::EDX);
+  MIB.addReg(t2);
+
+  MIB = BuildMI(newMBB, TII->get(copyOpc), X86::EBX);
+  MIB.addReg(t5);
+  MIB = BuildMI(newMBB, TII->get(copyOpc), X86::ECX);
+  MIB.addReg(t6);
+  
+  MIB = BuildMI(newMBB, TII->get(X86::LCMPXCHG8B));
+  for (int i=0; i <= lastAddrIndx; ++i)
+    (*MIB).addOperand(*argOpers[i]);
+
+  assert(bInstr->hasOneMemOperand() && "Unexpected number of memoperand");
+  (*MIB).addMemOperand(*F, *bInstr->memoperands_begin());
+
+  MIB = BuildMI(newMBB, TII->get(copyOpc), t3);
+  MIB.addReg(X86::EAX);
+  MIB = BuildMI(newMBB, TII->get(copyOpc), t4);
+  MIB.addReg(X86::EDX);
+  
+  // insert branch
+  BuildMI(newMBB, TII->get(X86::JNE)).addMBB(newMBB);
+
+  F->DeleteMachineInstr(bInstr);   // The pseudo instruction is gone now.
+  return nextMBB;
+}
+
 // private utility function
 MachineBasicBlock *
 X86TargetLowering::EmitAtomicMinMaxWithCustomInserter(MachineInstr *mInstr,
@@ -6328,11 +6613,12 @@ X86TargetLowering::EmitAtomicMinMaxWithCustomInserter(MachineInstr *mInstr,
     (*MIB).addOperand(*argOpers[i]);
 
   // We only support register and immediate values
-  assert(   (argOpers[valArgIndx]->isReg() || argOpers[valArgIndx]->isImm())
-         && "invalid operand");
+  assert((argOpers[valArgIndx]->isRegister() ||
+          argOpers[valArgIndx]->isImmediate()) &&
+         "invalid operand");
   
   unsigned t2 = F->getRegInfo().createVirtualRegister(X86::GR32RegisterClass);  
-  if (argOpers[valArgIndx]->isReg())
+  if (argOpers[valArgIndx]->isRegister())
     MIB = BuildMI(newMBB, TII->get(X86::MOV32rr), t2);
   else 
     MIB = BuildMI(newMBB, TII->get(X86::MOV32rr), t2);
@@ -6599,6 +6885,7 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
                                                X86::NOT8r, X86::AL,
                                                X86::GR8RegisterClass, true);
   // FIXME: There are no CMOV8 instructions; MIN/MAX need some other way.
+  // This group is for 64-bit host.
   case X86::ATOMAND64:
     return EmitAtomicBitwiseWithCustomInserter(MI, BB, X86::AND64rr,
                                                X86::AND64ri32, X86::MOV64rm, 
@@ -6631,6 +6918,40 @@ X86TargetLowering::EmitInstrWithCustomInserter(MachineInstr *MI,
     return EmitAtomicMinMaxWithCustomInserter(MI, BB, X86::CMOVB64rr);
   case X86::ATOMUMAX64:
     return EmitAtomicMinMaxWithCustomInserter(MI, BB, X86::CMOVA64rr);
+
+  // This group does 64-bit operations on a 32-bit host.
+  case X86::ATOMAND6432:
+    return EmitAtomicBit6432WithCustomInserter(MI, BB, 
+                                               X86::AND32rr, X86::AND32rr,
+                                               X86::AND32ri, X86::AND32ri,
+                                               false);
+  case X86::ATOMOR6432:
+    return EmitAtomicBit6432WithCustomInserter(MI, BB, 
+                                               X86::OR32rr, X86::OR32rr,
+                                               X86::OR32ri, X86::OR32ri,
+                                               false);
+  case X86::ATOMXOR6432:
+    return EmitAtomicBit6432WithCustomInserter(MI, BB, 
+                                               X86::XOR32rr, X86::XOR32rr,
+                                               X86::XOR32ri, X86::XOR32ri,
+                                               false);
+  case X86::ATOMNAND6432:
+    return EmitAtomicBit6432WithCustomInserter(MI, BB, 
+                                               X86::AND32rr, X86::AND32rr,
+                                               X86::AND32ri, X86::AND32ri,
+                                               true);
+  // FIXME carry
+  case X86::ATOMADD6432:
+    return EmitAtomicBit6432WithCustomInserter(MI, BB, 
+                                               X86::ADD32rr, X86::ADC32rr,
+                                               X86::ADD32ri, X86::ADC32ri,
+                                               false);
+  // FIXME carry
+  case X86::ATOMSUB6432:
+    return EmitAtomicBit6432WithCustomInserter(MI, BB, 
+                                               X86::SUB32rr, X86::SBB32rr,
+                                               X86::SUB32ri, X86::SBB32ri,
+                                               false);
   }
 }
 
@@ -6746,8 +7067,8 @@ static SDValue PerformShuffleCombine(SDNode *N, SelectionDAG &DAG,
 
 /// PerformBuildVectorCombine - build_vector 0,(load i64 / f64) -> movq / movsd.
 static SDValue PerformBuildVectorCombine(SDNode *N, SelectionDAG &DAG,
-                                           const X86Subtarget *Subtarget,
-                                           const TargetLowering &TLI) {
+                                         const X86Subtarget *Subtarget,
+                                         const TargetLowering &TLI) {
   unsigned NumOps = N->getNumOperands();
 
   // Ignore single operand BUILD_VECTOR.
@@ -6783,7 +7104,11 @@ static SDValue PerformBuildVectorCombine(SDNode *N, SelectionDAG &DAG,
   if (LD->getExtensionType() != ISD::NON_EXTLOAD)
     return SDValue();
   
-  return DAG.getNode(X86ISD::VZEXT_LOAD, VT, LD->getChain(), LD->getBasePtr());
+  SDVTList Tys = DAG.getVTList(VT, MVT::Other);
+  SDValue Ops[] = { LD->getChain(), LD->getBasePtr() };
+  SDValue ResNode = DAG.getNode(X86ISD::VZEXT_LOAD, Tys, Ops, 2);
+  DAG.ReplaceAllUsesOfValueWith(SDValue(Base, 1), ResNode.getValue(1));
+  return ResNode;
 }                                           
 
 /// PerformSELECTCombine - Do target-specific dag combines on SELECT nodes.
@@ -7044,6 +7369,7 @@ LowerXConstraint(MVT ConstraintVT) const {
 /// vector.  If it is invalid, don't add anything to Ops.
 void X86TargetLowering::LowerAsmOperandForConstraint(SDValue Op,
                                                      char Constraint,
+                                                     bool hasMemory,
                                                      std::vector<SDValue>&Ops,
                                                      SelectionDAG &DAG) const {
   SDValue Result(0, 0);
@@ -7052,16 +7378,24 @@ void X86TargetLowering::LowerAsmOperandForConstraint(SDValue Op,
   default: break;
   case 'I':
     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
-      if (C->getValue() <= 31) {
-        Result = DAG.getTargetConstant(C->getValue(), Op.getValueType());
+      if (C->getZExtValue() <= 31) {
+        Result = DAG.getTargetConstant(C->getZExtValue(), Op.getValueType());
+        break;
+      }
+    }
+    return;
+  case 'J':
+    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
+      if (C->getZExtValue() <= 63) {
+        Result = DAG.getTargetConstant(C->getZExtValue(), Op.getValueType());
         break;
       }
     }
     return;
   case 'N':
     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op)) {
-      if (C->getValue() <= 255) {
-        Result = DAG.getTargetConstant(C->getValue(), Op.getValueType());
+      if (C->getZExtValue() <= 255) {
+        Result = DAG.getTargetConstant(C->getZExtValue(), Op.getValueType());
         break;
       }
     }
@@ -7069,7 +7403,7 @@ void X86TargetLowering::LowerAsmOperandForConstraint(SDValue Op,
   case 'i': {
     // Literal immediates are always ok.
     if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(Op)) {
-      Result = DAG.getTargetConstant(CST->getValue(), Op.getValueType());
+      Result = DAG.getTargetConstant(CST->getZExtValue(), Op.getValueType());
       break;
     }
 
@@ -7085,26 +7419,23 @@ void X86TargetLowering::LowerAsmOperandForConstraint(SDValue Op,
       ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
       GA = dyn_cast<GlobalAddressSDNode>(Op.getOperand(0));
       if (C && GA) {
-        Offset = GA->getOffset()+C->getValue();
+        Offset = GA->getOffset()+C->getZExtValue();
       } else {
         C = dyn_cast<ConstantSDNode>(Op.getOperand(1));
         GA = dyn_cast<GlobalAddressSDNode>(Op.getOperand(0));
         if (C && GA)
-          Offset = GA->getOffset()+C->getValue();
+          Offset = GA->getOffset()+C->getZExtValue();
         else
           C = 0, GA = 0;
       }
     }
     
     if (GA) {
-      // If addressing this global requires a load (e.g. in PIC mode), we can't
-      // match.
-      if (Subtarget->GVRequiresExtraLoad(GA->getGlobal(), getTargetMachine(),
-                                         false))
-        return;
-
-      Op = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0),
-                                      Offset);
+      if (hasMemory) 
+        Op = LowerGlobalAddress(GA->getGlobal(), DAG);
+      else
+        Op = DAG.getTargetGlobalAddress(GA->getGlobal(), GA->getValueType(0),
+                                        Offset);
       Result = Op;
       break;
     }
@@ -7118,7 +7449,8 @@ void X86TargetLowering::LowerAsmOperandForConstraint(SDValue Op,
     Ops.push_back(Result);
     return;
   }
-  return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, Ops, DAG);
+  return TargetLowering::LowerAsmOperandForConstraint(Op, Constraint, hasMemory,
+                                                      Ops, DAG);
 }
 
 std::vector<unsigned> X86TargetLowering::