This commit changes:
[oota-llvm.git] / lib / Target / X86 / X86ISelLowering.cpp
index de55a7c6f4b2157ce7018a75ba84b5c757cda66e..bd1ee55345e196eff31fa4d49d6e7b42b456a13a 100644 (file)
@@ -82,6 +82,14 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
 
   setLoadXAction(ISD::SEXTLOAD, MVT::i1, Expand);
 
+  // We don't accept any truncstore of integer registers.  
+  setTruncStoreAction(MVT::i64, MVT::i32, Expand);
+  setTruncStoreAction(MVT::i64, MVT::i16, Expand);
+  setTruncStoreAction(MVT::i64, MVT::i8 , Expand);
+  setTruncStoreAction(MVT::i32, MVT::i16, Expand);
+  setTruncStoreAction(MVT::i32, MVT::i8 , Expand);
+  setTruncStoreAction(MVT::i16, MVT::i8, Expand);
+
   // Promote all UINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have this
   // operation.
   setOperationAction(ISD::UINT_TO_FP       , MVT::i1   , Promote);
@@ -638,6 +646,8 @@ X86TargetLowering::X86TargetLowering(TargetMachine &TM)
       AddPromotedToType (ISD::SELECT, (MVT::ValueType)VT, MVT::v2i64);
     }
 
+    setTruncStoreAction(MVT::f64, MVT::f32, Expand);
+    
     // Custom lower v2i64 and v2f64 selects.
     setOperationAction(ISD::LOAD,               MVT::v2f64, Legal);
     setOperationAction(ISD::LOAD,               MVT::v2i64, Legal);
@@ -760,8 +770,7 @@ SDOperand X86TargetLowering::LowerRET(SDOperand Op, SelectionDAG &DAG) {
     
     // If this is an FP return with ScalarSSE, we need to move the value from
     // an XMM register onto the fp-stack.
-    if ((X86ScalarSSEf32 && RVLocs[0].getValVT()==MVT::f32) ||
-        (X86ScalarSSEf64 && RVLocs[0].getValVT()==MVT::f64)) {
+    if (isScalarFPTypeInSSEReg(RVLocs[0].getValVT())) {
       SDOperand MemLoc;
         
       // If this is a load into a scalarsse value, don't store the loaded value
@@ -836,8 +845,7 @@ LowerCallResult(SDOperand Chain, SDOperand InFlag, SDNode *TheCall,
     
     // If we are using ScalarSSE, store ST(0) to the stack and reload it into
     // an XMM register.
-    if ((X86ScalarSSEf32 && RVLocs[0].getValVT() == MVT::f32) ||
-        (X86ScalarSSEf64 && RVLocs[0].getValVT() == MVT::f64)) {
+    if (isScalarFPTypeInSSEReg(RVLocs[0].getValVT())) {
       SDOperand StoreLoc;
       const Value *SrcVal = 0;
       int SrcValOffset = 0;
@@ -1184,8 +1192,7 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
       SmallVector<SDOperand, 8> MemOps;
       SDOperand RSFIN = DAG.getFrameIndex(RegSaveFrameIndex, getPointerTy());
       SDOperand FIN = DAG.getNode(ISD::ADD, getPointerTy(), RSFIN,
-                                  DAG.getConstant(VarArgsGPOffset,
-                                  getPointerTy()));
+                                  DAG.getIntPtrConstant(VarArgsGPOffset));
       for (; NumIntRegs != 6; ++NumIntRegs) {
         unsigned VReg = AddLiveIn(MF, GPR64ArgRegs[NumIntRegs],
                                   X86::GR64RegisterClass);
@@ -1193,12 +1200,12 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
         SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
         MemOps.push_back(Store);
         FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
-                          DAG.getConstant(8, getPointerTy()));
+                          DAG.getIntPtrConstant(8));
       }
       
       // Now store the XMM (fp + vector) parameter registers.
       FIN = DAG.getNode(ISD::ADD, getPointerTy(), RSFIN,
-                        DAG.getConstant(VarArgsFPOffset, getPointerTy()));
+                        DAG.getIntPtrConstant(VarArgsFPOffset));
       for (; NumXMMRegs != 8; ++NumXMMRegs) {
         unsigned VReg = AddLiveIn(MF, XMMArgRegs[NumXMMRegs],
                                   X86::VR128RegisterClass);
@@ -1206,7 +1213,7 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) {
         SDOperand Store = DAG.getStore(Val.getValue(1), Val, FIN, NULL, 0);
         MemOps.push_back(Store);
         FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
-                          DAG.getConstant(16, getPointerTy()));
+                          DAG.getIntPtrConstant(16));
       }
       if (!MemOps.empty())
           Root = DAG.getNode(ISD::TokenFactor, MVT::Other,
@@ -1255,7 +1262,7 @@ X86TargetLowering::LowerMemOpCallTo(SDOperand Op, SelectionDAG &DAG,
                                     const CCValAssign &VA,
                                     SDOperand Chain,
                                     SDOperand Arg) {
-  SDOperand PtrOff = DAG.getConstant(VA.getLocMemOffset(), getPointerTy());
+  SDOperand PtrOff = DAG.getIntPtrConstant(VA.getLocMemOffset());
   PtrOff = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, PtrOff);
   SDOperand FlagsOp = Op.getOperand(6+2*VA.getValNo());
   unsigned Flags    = cast<ConstantSDNode>(FlagsOp)->getValue();
@@ -1308,7 +1315,7 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
       MF.getInfo<X86MachineFunctionInfo>()->setTCReturnAddrDelta(FPDiff);
   }
 
-  Chain = DAG.getCALLSEQ_START(Chain,DAG.getConstant(NumBytes, getPointerTy()));
+  Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(NumBytes));
 
   SDOperand RetAddrFrIdx, NewRetAddrFrIdx;
   if (IsTailCall) {
@@ -1442,7 +1449,7 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
           // needs to be done because if we would lower the arguments directly
           // to their real stack slot we might end up overwriting each other.
           // Get source stack slot.
-          Source = DAG.getConstant(VA.getLocMemOffset(), getPointerTy());
+          Source = DAG.getIntPtrConstant(VA.getLocMemOffset());
           if (StackPtr.Val == 0)
             StackPtr = DAG.getCopyFromReg(Chain, X86StackPtr, getPointerTy());
           Source = DAG.getNode(ISD::ADD, getPointerTy(), StackPtr, Source);
@@ -1503,8 +1510,8 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
 
   if (IsTailCall) {
     Ops.push_back(Chain);
-    Ops.push_back(DAG.getConstant(NumBytes, getPointerTy()));
-    Ops.push_back(DAG.getConstant(0, getPointerTy()));
+    Ops.push_back(DAG.getIntPtrConstant(NumBytes));
+    Ops.push_back(DAG.getIntPtrConstant(0));
     if (InFlag.Val)
       Ops.push_back(InFlag);
     Chain = DAG.getNode(ISD::CALLSEQ_END, NodeTys, &Ops[0], Ops.size());
@@ -1562,9 +1569,8 @@ SDOperand X86TargetLowering::LowerCALL(SDOperand Op, SelectionDAG &DAG) {
   
   // Returns a flag for retval copy to use.
   Chain = DAG.getCALLSEQ_END(Chain,
-                             DAG.getConstant(NumBytes, getPointerTy()),
-                             DAG.getConstant(NumBytesForCalleeToPush,
-                                             getPointerTy()),
+                             DAG.getIntPtrConstant(NumBytes),
+                             DAG.getIntPtrConstant(NumBytesForCalleeToPush),
                              InFlag);
   InFlag = Chain.getValue(1);
 
@@ -2734,7 +2740,7 @@ static SDOperand LowerBuildVectorv16i8(SDOperand Op, unsigned NonZeros,
 
       if (ThisElt.Val)
         V = DAG.getNode(ISD::INSERT_VECTOR_ELT, MVT::v8i16, V, ThisElt,
-                        DAG.getConstant(i/2, TLI.getPointerTy()));
+                        DAG.getIntPtrConstant(i/2));
     }
   }
 
@@ -2762,7 +2768,7 @@ static SDOperand LowerBuildVectorv8i16(SDOperand Op, unsigned NonZeros,
         First = false;
       }
       V = DAG.getNode(ISD::INSERT_VECTOR_ELT, MVT::v8i16, V, Op.getOperand(i),
-                      DAG.getConstant(i, TLI.getPointerTy()));
+                      DAG.getIntPtrConstant(i));
     }
   }
 
@@ -3571,7 +3577,7 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
     Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(),
                       Vec, DAG.getNode(ISD::UNDEF, Vec.getValueType()), Mask);
     return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, VT, Vec,
-                       DAG.getConstant(0, getPointerTy()));
+                       DAG.getIntPtrConstant(0));
   } else if (MVT::getSizeInBits(VT) == 64) {
     unsigned Idx = cast<ConstantSDNode>(Op.getOperand(1))->getValue();
     if (Idx == 0)
@@ -3591,7 +3597,7 @@ X86TargetLowering::LowerEXTRACT_VECTOR_ELT(SDOperand Op, SelectionDAG &DAG) {
     Vec = DAG.getNode(ISD::VECTOR_SHUFFLE, Vec.getValueType(),
                       Vec, DAG.getNode(ISD::UNDEF, Vec.getValueType()), Mask);
     return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, VT, Vec,
-                       DAG.getConstant(0, getPointerTy()));
+                       DAG.getIntPtrConstant(0));
   }
 
   return SDOperand();
@@ -3614,7 +3620,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(),getPointerTy());
+      N2 = DAG.getIntPtrConstant(cast<ConstantSDNode>(N2)->getValue());
     return DAG.getNode(X86ISD::PINSRW, VT, N0, N1, N2);
   }
   return SDOperand();
@@ -3862,18 +3868,15 @@ SDOperand X86TargetLowering::LowerSINT_TO_FP(SDOperand Op, SelectionDAG &DAG) {
                                  StackSlot, NULL, 0);
 
   // These are really Legal; caller falls through into that case.
-  if (SrcVT==MVT::i32 && Op.getValueType() == MVT::f32 && X86ScalarSSEf32)
-    return Result;
-  if (SrcVT==MVT::i32 && Op.getValueType() == MVT::f64 && X86ScalarSSEf64)
+  if (SrcVT == MVT::i32 && isScalarFPTypeInSSEReg(Op.getValueType()))
     return Result;
-  if (SrcVT==MVT::i64 && Op.getValueType() != MVT::f80 && 
+  if (SrcVT == MVT::i64 && Op.getValueType() != MVT::f80 && 
       Subtarget->is64Bit())
     return Result;
 
   // Build the FILD
   SDVTList Tys;
-  bool useSSE = (X86ScalarSSEf32 && Op.getValueType() == MVT::f32) ||
-                (X86ScalarSSEf64 && Op.getValueType() == MVT::f64);
+  bool useSSE = isScalarFPTypeInSSEReg(Op.getValueType());
   if (useSSE)
     Tys = DAG.getVTList(MVT::f64, MVT::Other, MVT::Flag);
   else
@@ -3916,10 +3919,7 @@ FP_TO_SINTHelper(SDOperand Op, SelectionDAG &DAG) {
 
   // These are really Legal.
   if (Op.getValueType() == MVT::i32 && 
-      X86ScalarSSEf32 && Op.getOperand(0).getValueType() == MVT::f32)
-    return std::make_pair(SDOperand(), SDOperand());
-  if (Op.getValueType() == MVT::i32 && 
-      X86ScalarSSEf64 && Op.getOperand(0).getValueType() == MVT::f64)
+      isScalarFPTypeInSSEReg(Op.getOperand(0).getValueType()))
     return std::make_pair(SDOperand(), SDOperand());
   if (Subtarget->is64Bit() &&
       Op.getValueType() == MVT::i64 &&
@@ -3942,8 +3942,7 @@ FP_TO_SINTHelper(SDOperand Op, SelectionDAG &DAG) {
 
   SDOperand Chain = DAG.getEntryNode();
   SDOperand Value = Op.getOperand(0);
-  if ((X86ScalarSSEf32 && Op.getOperand(0).getValueType() == MVT::f32) ||
-      (X86ScalarSSEf64 && Op.getOperand(0).getValueType() == MVT::f64)) {
+  if (isScalarFPTypeInSSEReg(Op.getOperand(0).getValueType())) {
     assert(Op.getValueType() == MVT::i64 && "Invalid FP_TO_SINT to lower!");
     Chain = DAG.getStore(Chain, Value, StackSlot, NULL, 0);
     SDVTList Tys = DAG.getVTList(Op.getOperand(0).getValueType(), MVT::Other);
@@ -4059,7 +4058,7 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
   }
   // And if it is bigger, shrink it first.
   if (MVT::getSizeInBits(SrcVT) > MVT::getSizeInBits(VT)) {
-    Op1 = DAG.getNode(ISD::FP_ROUND, VT, Op1);
+    Op1 = DAG.getNode(ISD::FP_ROUND, VT, Op1, DAG.getIntPtrConstant(1));
     SrcVT = VT;
     SrcTy = MVT::getTypeForValueType(SrcVT);
   }
@@ -4092,7 +4091,7 @@ SDOperand X86TargetLowering::LowerFCOPYSIGN(SDOperand Op, SelectionDAG &DAG) {
                           DAG.getConstant(32, MVT::i32));
     SignBit = DAG.getNode(ISD::BIT_CONVERT, MVT::v4f32, SignBit);
     SignBit = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, MVT::f32, SignBit,
-                          DAG.getConstant(0, getPointerTy()));
+                          DAG.getIntPtrConstant(0));
   }
 
   // Clear first operand sign bit.
@@ -4172,13 +4171,12 @@ SDOperand X86TargetLowering::LowerSELECT(SDOperand Op, SelectionDAG &DAG) {
     SDOperand Cmp = Cond.getOperand(1);
     unsigned Opc = Cmp.getOpcode();
     MVT::ValueType VT = Op.getValueType();
+    
     bool IllegalFPCMov = false;
-    if (VT == MVT::f32 && !X86ScalarSSEf32)
-      IllegalFPCMov = !hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended());
-    else if (VT == MVT::f64 && !X86ScalarSSEf64)
-      IllegalFPCMov = !hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended());
-    else if (VT == MVT::f80)
+    if (MVT::isFloatingPoint(VT) && !MVT::isVector(VT) &&
+        !isScalarFPTypeInSSEReg(VT))  // FPStack?
       IllegalFPCMov = !hasFPCMov(cast<ConstantSDNode>(CC)->getSignExtended());
+    
     if ((Opc == X86ISD::CMP ||
          Opc == X86ISD::COMI ||
          Opc == X86ISD::UCOMI) && !IllegalFPCMov) {
@@ -4257,7 +4255,7 @@ X86TargetLowering::LowerDYNAMIC_STACKALLOC(SDOperand Op,
   SDOperand Flag;
   
   MVT::ValueType IntPtr = getPointerTy();
-  MVT::ValueType SPTy = (Subtarget->is64Bit() ? MVT::i64 : MVT::i32);
+  MVT::ValueType SPTy = Subtarget->is64Bit() ? MVT::i64 : MVT::i32;
 
   Chain = DAG.getCopyToReg(Chain, X86::EAX, Size, Flag);
   Flag = Chain.getValue(1);
@@ -4348,7 +4346,7 @@ SDOperand X86TargetLowering::LowerMEMSET(SDOperand Op, SelectionDAG &DAG) {
     if (AVT > MVT::i8) {
       if (I) {
         unsigned UBytes = MVT::getSizeInBits(AVT) / 8;
-        Count = DAG.getConstant(I->getValue() / UBytes, getPointerTy());
+        Count = DAG.getIntPtrConstant(I->getValue() / UBytes);
         BytesLeft = I->getValue() % UBytes;
       } else {
         assert(AVT >= MVT::i32 &&
@@ -4460,7 +4458,7 @@ SDOperand X86TargetLowering::LowerMEMCPYInline(SDOperand Chain,
   }
 
   unsigned UBytes = MVT::getSizeInBits(AVT) / 8;
-  SDOperand Count = DAG.getConstant(Size / UBytes, getPointerTy());
+  SDOperand Count = DAG.getIntPtrConstant(Size / UBytes);
   BytesLeft = Size % UBytes;
 
   SDOperand InFlag(0, 0);
@@ -4589,24 +4587,21 @@ SDOperand X86TargetLowering::LowerVASTART(SDOperand Op, SelectionDAG &DAG) {
   MemOps.push_back(Store);
 
   // Store fp_offset
-  FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
-                    DAG.getConstant(4, getPointerTy()));
+  FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN, DAG.getIntPtrConstant(4));
   Store = DAG.getStore(Op.getOperand(0),
                        DAG.getConstant(VarArgsFPOffset, MVT::i32),
                        FIN, SV->getValue(), SV->getOffset());
   MemOps.push_back(Store);
 
   // Store ptr to overflow_arg_area
-  FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
-                    DAG.getConstant(4, getPointerTy()));
+  FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN, DAG.getIntPtrConstant(4));
   SDOperand OVFIN = DAG.getFrameIndex(VarArgsFrameIndex, getPointerTy());
   Store = DAG.getStore(Op.getOperand(0), OVFIN, FIN, SV->getValue(),
                        SV->getOffset());
   MemOps.push_back(Store);
 
   // Store ptr to reg_save_area.
-  FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN,
-                    DAG.getConstant(8, getPointerTy()));
+  FIN = DAG.getNode(ISD::ADD, getPointerTy(), FIN, DAG.getIntPtrConstant(8));
   SDOperand RSFIN = DAG.getFrameIndex(RegSaveFrameIndex, getPointerTy());
   Store = DAG.getStore(Op.getOperand(0), RSFIN, FIN, SV->getValue(),
                        SV->getOffset());
@@ -4634,9 +4629,9 @@ SDOperand X86TargetLowering::LowerVACOPY(SDOperand Op, SelectionDAG &DAG) {
     if (i == 2)
       break;
     SrcPtr = DAG.getNode(ISD::ADD, getPointerTy(), SrcPtr, 
-                         DAG.getConstant(8, getPointerTy()));
+                         DAG.getIntPtrConstant(8));
     DstPtr = DAG.getNode(ISD::ADD, getPointerTy(), DstPtr, 
-                         DAG.getConstant(8, getPointerTy()));
+                         DAG.getIntPtrConstant(8));
   }
   return Chain;
 }
@@ -4767,7 +4762,7 @@ SDOperand X86TargetLowering::LowerFRAMEADDR(SDOperand Op, SelectionDAG &DAG) {
     
   SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG);
   return DAG.getNode(ISD::SUB, getPointerTy(), RetAddrFI, 
-                     DAG.getConstant(4, getPointerTy()));
+                     DAG.getIntPtrConstant(4));
 }
 
 SDOperand X86TargetLowering::LowerFRAME_TO_ARGS_OFFSET(SDOperand Op,
@@ -4776,7 +4771,7 @@ SDOperand X86TargetLowering::LowerFRAME_TO_ARGS_OFFSET(SDOperand Op,
   if (Subtarget->is64Bit())
     return SDOperand();
   
-  return DAG.getConstant(8, getPointerTy());
+  return DAG.getIntPtrConstant(8);
 }
 
 SDOperand X86TargetLowering::LowerEH_RETURN(SDOperand Op, SelectionDAG &DAG)
@@ -4793,7 +4788,7 @@ SDOperand X86TargetLowering::LowerEH_RETURN(SDOperand Op, SelectionDAG &DAG)
                                     getPointerTy());
 
   SDOperand StoreAddr = DAG.getNode(ISD::SUB, getPointerTy(), Frame,
-                                    DAG.getConstant(-4UL, getPointerTy()));
+                                    DAG.getIntPtrConstant(-4UL));
   StoreAddr = DAG.getNode(ISD::ADD, getPointerTy(), StoreAddr, Offset);
   Chain = DAG.getStore(Chain, Handler, StoreAddr, NULL, 0);
   Chain = DAG.getCopyToReg(Chain, X86::ECX, StoreAddr);
@@ -4812,8 +4807,59 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
 
   SrcValueSDNode *TrmpSV = cast<SrcValueSDNode>(Op.getOperand(4));
 
+  const X86InstrInfo *TII =
+    ((X86TargetMachine&)getTargetMachine()).getInstrInfo();
+
   if (Subtarget->is64Bit()) {
-    return SDOperand(); // not yet supported
+    SDOperand OutChains[6];
+
+    // Large code-model.
+
+    const unsigned char JMP64r  = TII->getBaseOpcodeFor(X86::JMP64r);
+    const unsigned char MOV64ri = TII->getBaseOpcodeFor(X86::MOV64ri);
+
+    const unsigned char N86R10 =
+      ((X86RegisterInfo*)RegInfo)->getX86RegNum(X86::R10);
+    const unsigned char N86R11 =
+      ((X86RegisterInfo*)RegInfo)->getX86RegNum(X86::R11);
+
+    const unsigned char REX_WB = 0x40 | 0x08 | 0x01; // REX prefix
+
+    // Load the pointer to the nested function into R11.
+    unsigned OpCode = ((MOV64ri | N86R11) << 8) | REX_WB; // movabsq r11
+    SDOperand Addr = Trmp;
+    OutChains[0] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
+                                TrmpSV->getValue(), TrmpSV->getOffset());
+
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(2, MVT::i64));
+    OutChains[1] = DAG.getStore(Root, FPtr, Addr, TrmpSV->getValue(),
+                                TrmpSV->getOffset() + 2, false, 2);
+
+    // Load the 'nest' parameter value into R10.
+    // R10 is specified in X86CallingConv.td
+    OpCode = ((MOV64ri | N86R10) << 8) | REX_WB; // movabsq r10
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(10, MVT::i64));
+    OutChains[2] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
+                                TrmpSV->getValue(), TrmpSV->getOffset() + 10);
+
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(12, MVT::i64));
+    OutChains[3] = DAG.getStore(Root, Nest, Addr, TrmpSV->getValue(),
+                                TrmpSV->getOffset() + 12, false, 2);
+
+    // Jump to the nested function.
+    OpCode = (JMP64r << 8) | REX_WB; // jmpq *...
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(20, MVT::i64));
+    OutChains[4] = DAG.getStore(Root, DAG.getConstant(OpCode, MVT::i16), Addr,
+                                TrmpSV->getValue(), TrmpSV->getOffset() + 20);
+
+    unsigned char ModRM = N86R11 | (4 << 3) | (3 << 6); // ...r11
+    Addr = DAG.getNode(ISD::ADD, MVT::i64, Trmp, DAG.getConstant(22, MVT::i64));
+    OutChains[5] = DAG.getStore(Root, DAG.getConstant(ModRM, MVT::i8), Addr,
+                                TrmpSV->getValue(), TrmpSV->getOffset() + 22);
+
+    SDOperand Ops[] =
+      { Trmp, DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains, 6) };
+    return DAG.getNode(ISD::MERGE_VALUES, Op.Val->getVTList(), Ops, 2);
   } else {
     Function *Func = (Function *)
       cast<Function>(cast<SrcValueSDNode>(Op.getOperand(5))->getValue());
@@ -4857,17 +4903,15 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
       break;
     }
 
-    const X86InstrInfo *TII =
-      ((X86TargetMachine&)getTargetMachine()).getInstrInfo();
-
     SDOperand OutChains[4];
     SDOperand Addr, Disp;
 
     Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(10, MVT::i32));
     Disp = DAG.getNode(ISD::SUB, MVT::i32, FPtr, Addr);
 
-    unsigned char MOV32ri = TII->getBaseOpcodeFor(X86::MOV32ri);
-    unsigned char N86Reg  = ((X86RegisterInfo*)RegInfo)->getX86RegNum(NestReg);
+    const unsigned char MOV32ri = TII->getBaseOpcodeFor(X86::MOV32ri);
+    const unsigned char N86Reg =
+      ((X86RegisterInfo*)RegInfo)->getX86RegNum(NestReg);
     OutChains[0] = DAG.getStore(Root, DAG.getConstant(MOV32ri|N86Reg, MVT::i8),
                                 Trmp, TrmpSV->getValue(), TrmpSV->getOffset());
 
@@ -4875,7 +4919,7 @@ SDOperand X86TargetLowering::LowerTRAMPOLINE(SDOperand Op,
     OutChains[1] = DAG.getStore(Root, Nest, Addr, TrmpSV->getValue(),
                                 TrmpSV->getOffset() + 1, false, 1);
 
-    unsigned char JMP = TII->getBaseOpcodeFor(X86::JMP);
+    const unsigned char JMP = TII->getBaseOpcodeFor(X86::JMP);
     Addr = DAG.getNode(ISD::ADD, MVT::i32, Trmp, DAG.getConstant(5, MVT::i32));
     OutChains[2] = DAG.getStore(Root, DAG.getConstant(JMP, MVT::i8), Addr,
                                 TrmpSV->getValue() + 5, TrmpSV->getOffset());