diff --git a/lib/Target/X86/X86.h b/lib/Target/X86/X86.h
index f17dd8b..dc79b80 100644
--- a/lib/Target/X86/X86.h
+++ b/lib/Target/X86/X86.h
@@ -32,10 +32,16 @@
 extern X86VectorEnum X86Vector;
 extern bool X86ScalarSSE;
 
-/// createX86PatternInstructionSelector - This pass converts an LLVM function
-/// into a machine code representation in a more aggressive way.
+/// createX86ISelPattern - This pass converts an LLVM function into a 
+/// machine code representation using pattern matching and a machine
+/// description file.
 ///
-FunctionPass *createX86PatternInstructionSelector(TargetMachine &TM);
+FunctionPass *createX86ISelPattern(TargetMachine &TM);
+
+/// createX86ISelDag - This pass converts a legalized DAG into a 
+/// X86-specific DAG, ready for instruction scheduling.
+///
+FunctionPass *createX86ISelDag(TargetMachine &TM);
 
 /// createX86SSAPeepholeOptimizerPass - Create a pass to perform SSA-based X86
 /// specific peephole optimizations.
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
new file mode 100644
index 0000000..e33bf95
--- /dev/null
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -0,0 +1,916 @@
+//===-- X86ISelLowering.h - X86 DAG Lowering Interface ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interfaces that X86 uses to lower LLVM code into a
+// selection DAG.
+//
+//===----------------------------------------------------------------------===//
+
+#include "X86.h"
+#include "X86ISelLowering.h"
+#include "X86TargetMachine.h"
+#include "llvm/CallingConv.h"
+#include "llvm/Function.h"
+#include "llvm/CodeGen/MachineFunction.h"
+#include "llvm/CodeGen/MachineFrameInfo.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+#include "llvm/CodeGen/SSARegMap.h"
+#include "llvm/Target/TargetOptions.h"
+using namespace llvm;
+
+// FIXME: temporary.
+#include "llvm/Support/CommandLine.h"
+static cl::opt<bool> EnableFastCC("enable-x86-fastcc", cl::Hidden,
+                                  cl::desc("Enable fastcc on X86"));
+
+X86TargetLowering::X86TargetLowering(TargetMachine &TM)
+  : TargetLowering(TM) {
+
+  // Set up the TargetLowering object.
+
+  // X86 is weird, it always uses i8 for shift amounts and setcc results.
+  setShiftAmountType(MVT::i8);
+  setSetCCResultType(MVT::i8);
+  setSetCCResultContents(ZeroOrOneSetCCResult);
+  setShiftAmountFlavor(Mask);   // shl X, 32 == shl X, 0
+
+  // Set up the register classes.
+  // FIXME: Eliminate these two classes when legalize can handle promotions
+  // well.
+  addRegisterClass(MVT::i1, X86::R8RegisterClass);
+  addRegisterClass(MVT::i8, X86::R8RegisterClass);
+  addRegisterClass(MVT::i16, X86::R16RegisterClass);
+  addRegisterClass(MVT::i32, X86::R32RegisterClass);
+
+  // 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);
+  setOperationAction(ISD::UINT_TO_FP       , MVT::i8   , Promote);
+  setOperationAction(ISD::UINT_TO_FP       , MVT::i16  , Promote);
+  setOperationAction(ISD::UINT_TO_FP       , MVT::i32  , Promote);
+
+  // Promote i1/i8 SINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have
+  // this operation.
+  setOperationAction(ISD::SINT_TO_FP       , MVT::i1   , Promote);
+  setOperationAction(ISD::SINT_TO_FP       , MVT::i8   , Promote);
+
+  if (!X86ScalarSSE) {
+    // We can handle SINT_TO_FP and FP_TO_SINT from/TO i64 even though i64
+    // isn't legal.
+    setOperationAction(ISD::SINT_TO_FP     , MVT::i64  , Custom);
+    setOperationAction(ISD::FP_TO_SINT     , MVT::i64  , Custom);
+    setOperationAction(ISD::FP_TO_SINT     , MVT::i32  , Custom);
+    setOperationAction(ISD::FP_TO_SINT     , MVT::i16  , Custom);
+  }
+
+  // Handle FP_TO_UINT by promoting the destination to a larger signed
+  // conversion.
+  setOperationAction(ISD::FP_TO_UINT       , MVT::i1   , Promote);
+  setOperationAction(ISD::FP_TO_UINT       , MVT::i8   , Promote);
+  setOperationAction(ISD::FP_TO_UINT       , MVT::i16  , Promote);
+
+  if (!X86ScalarSSE)
+    setOperationAction(ISD::FP_TO_UINT     , MVT::i32  , Promote);
+
+  // Promote i1/i8 FP_TO_SINT to larger FP_TO_SINTS's, as X86 doesn't have
+  // this operation.
+  setOperationAction(ISD::FP_TO_SINT       , MVT::i1   , Promote);
+  setOperationAction(ISD::FP_TO_SINT       , MVT::i8   , Promote);
+  setOperationAction(ISD::FP_TO_SINT       , MVT::i16  , Promote);
+
+  setOperationAction(ISD::BRCONDTWOWAY     , MVT::Other, Expand);
+  setOperationAction(ISD::BRTWOWAY_CC      , MVT::Other, Expand);
+  setOperationAction(ISD::MEMMOVE          , MVT::Other, Expand);
+  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16  , Expand);
+  setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1   , Expand);
+  setOperationAction(ISD::FP_ROUND_INREG   , MVT::f32  , Expand);
+  setOperationAction(ISD::SEXTLOAD         , MVT::i1   , Expand);
+  setOperationAction(ISD::FREM             , MVT::f64  , Expand);
+  setOperationAction(ISD::CTPOP            , MVT::i8   , Expand);
+  setOperationAction(ISD::CTTZ             , MVT::i8   , Expand);
+  setOperationAction(ISD::CTLZ             , MVT::i8   , Expand);
+  setOperationAction(ISD::CTPOP            , MVT::i16  , Expand);
+  setOperationAction(ISD::CTTZ             , MVT::i16  , Expand);
+  setOperationAction(ISD::CTLZ             , MVT::i16  , Expand);
+  setOperationAction(ISD::CTPOP            , MVT::i32  , Expand);
+  setOperationAction(ISD::CTTZ             , MVT::i32  , Expand);
+  setOperationAction(ISD::CTLZ             , MVT::i32  , Expand);
+
+  setOperationAction(ISD::READIO           , MVT::i1   , Expand);
+  setOperationAction(ISD::READIO           , MVT::i8   , Expand);
+  setOperationAction(ISD::READIO           , MVT::i16  , Expand);
+  setOperationAction(ISD::READIO           , MVT::i32  , Expand);
+  setOperationAction(ISD::WRITEIO          , MVT::i1   , Expand);
+  setOperationAction(ISD::WRITEIO          , MVT::i8   , Expand);
+  setOperationAction(ISD::WRITEIO          , MVT::i16  , Expand);
+  setOperationAction(ISD::WRITEIO          , MVT::i32  , Expand);
+
+  // These should be promoted to a larger select which is supported.
+  setOperationAction(ISD::SELECT           , MVT::i1   , Promote);
+  setOperationAction(ISD::SELECT           , MVT::i8   , Promote);
+
+  if (X86ScalarSSE) {
+    // Set up the FP register classes.
+    addRegisterClass(MVT::f32, X86::V4F4RegisterClass);
+    addRegisterClass(MVT::f64, X86::V2F8RegisterClass);
+
+    // SSE has no load+extend ops
+    setOperationAction(ISD::EXTLOAD,  MVT::f32, Expand);
+    setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand);
+
+    // SSE has no i16 to fp conversion, only i32
+    setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
+    setOperationAction(ISD::FP_TO_SINT, MVT::i16, Promote);
+
+    // Expand FP_TO_UINT into a select.
+    // FIXME: We would like to use a Custom expander here eventually to do
+    // the optimal thing for SSE vs. the default expansion in the legalizer.
+    setOperationAction(ISD::FP_TO_UINT       , MVT::i32  , Expand);
+        
+    // We don't support sin/cos/sqrt/fmod
+    setOperationAction(ISD::FSIN , MVT::f64, Expand);
+    setOperationAction(ISD::FCOS , MVT::f64, Expand);
+    setOperationAction(ISD::FABS , MVT::f64, Expand);
+    setOperationAction(ISD::FNEG , MVT::f64, Expand);
+    setOperationAction(ISD::FREM , MVT::f64, Expand);
+    setOperationAction(ISD::FSIN , MVT::f32, Expand);
+    setOperationAction(ISD::FCOS , MVT::f32, Expand);
+    setOperationAction(ISD::FABS , MVT::f32, Expand);
+    setOperationAction(ISD::FNEG , MVT::f32, Expand);
+    setOperationAction(ISD::FREM , MVT::f32, Expand);
+
+    addLegalFPImmediate(+0.0); // xorps / xorpd
+  } else {
+    // Set up the FP register classes.
+    addRegisterClass(MVT::f64, X86::RFPRegisterClass);
+
+    if (!UnsafeFPMath) {
+      setOperationAction(ISD::FSIN           , MVT::f64  , Expand);
+      setOperationAction(ISD::FCOS           , MVT::f64  , Expand);
+    }
+
+    addLegalFPImmediate(+0.0); // FLD0
+    addLegalFPImmediate(+1.0); // FLD1
+    addLegalFPImmediate(-0.0); // FLD0/FCHS
+    addLegalFPImmediate(-1.0); // FLD1/FCHS
+  }
+  computeRegisterProperties();
+
+  maxStoresPerMemSet = 8; // For %llvm.memset -> sequence of stores
+  maxStoresPerMemCpy = 8; // For %llvm.memcpy -> sequence of stores
+  maxStoresPerMemMove = 8; // For %llvm.memmove -> sequence of stores
+  allowUnalignedMemoryAccesses = true; // x86 supports it!
+}
+
+std::vector<SDOperand>
+X86TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
+  if (F.getCallingConv() == CallingConv::Fast && EnableFastCC)
+    return LowerFastCCArguments(F, DAG);
+  return LowerCCCArguments(F, DAG);
+}
+
+std::pair<SDOperand, SDOperand>
+X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
+                               bool isVarArg, unsigned CallingConv,
+                               bool isTailCall,
+                               SDOperand Callee, ArgListTy &Args,
+                               SelectionDAG &DAG) {
+  assert((!isVarArg || CallingConv == CallingConv::C) &&
+         "Only C takes varargs!");
+  if (CallingConv == CallingConv::Fast && EnableFastCC)
+    return LowerFastCCCallTo(Chain, RetTy, isTailCall, Callee, Args, DAG);
+  return  LowerCCCCallTo(Chain, RetTy, isVarArg, isTailCall, Callee, Args, DAG);
+}
+
+//===----------------------------------------------------------------------===//
+//                    C Calling Convention implementation
+//===----------------------------------------------------------------------===//
+
+std::vector<SDOperand>
+X86TargetLowering::LowerCCCArguments(Function &F, SelectionDAG &DAG) {
+  std::vector<SDOperand> ArgValues;
+
+  MachineFunction &MF = DAG.getMachineFunction();
+  MachineFrameInfo *MFI = MF.getFrameInfo();
+
+  // Add DAG nodes to load the arguments...  On entry to a function on the X86,
+  // the stack frame looks like this:
+  //
+  // [ESP] -- return address
+  // [ESP + 4] -- first argument (leftmost lexically)
+  // [ESP + 8] -- second argument, if first argument is four bytes in size
+  //    ...
+  //
+  unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
+  for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
+    MVT::ValueType ObjectVT = getValueType(I->getType());
+    unsigned ArgIncrement = 4;
+    unsigned ObjSize;
+    switch (ObjectVT) {
+    default: assert(0 && "Unhandled argument type!");
+    case MVT::i1:
+    case MVT::i8:  ObjSize = 1;                break;
+    case MVT::i16: ObjSize = 2;                break;
+    case MVT::i32: ObjSize = 4;                break;
+    case MVT::i64: ObjSize = ArgIncrement = 8; break;
+    case MVT::f32: ObjSize = 4;                break;
+    case MVT::f64: ObjSize = ArgIncrement = 8; break;
+    }
+    // Create the frame index object for this incoming parameter...
+    int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
+
+    // Create the SelectionDAG nodes corresponding to a load from this parameter
+    SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
+
+    // Don't codegen dead arguments.  FIXME: remove this check when we can nuke
+    // dead loads.
+    SDOperand ArgValue;
+    if (!I->use_empty())
+      ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN,
+                             DAG.getSrcValue(NULL));
+    else {
+      if (MVT::isInteger(ObjectVT))
+        ArgValue = DAG.getConstant(0, ObjectVT);
+      else
+        ArgValue = DAG.getConstantFP(0, ObjectVT);
+    }
+    ArgValues.push_back(ArgValue);
+
+    ArgOffset += ArgIncrement;   // Move on to the next argument...
+  }
+
+  // If the function takes variable number of arguments, make a frame index for
+  // the start of the first vararg value... for expansion of llvm.va_start.
+  if (F.isVarArg())
+    VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset);
+  ReturnAddrIndex = 0;     // No return address slot generated yet.
+  BytesToPopOnReturn = 0;  // Callee pops nothing.
+  BytesCallerReserves = ArgOffset;
+
+  // Finally, inform the code generator which regs we return values in.
+  switch (getValueType(F.getReturnType())) {
+  default: assert(0 && "Unknown type!");
+  case MVT::isVoid: break;
+  case MVT::i1:
+  case MVT::i8:
+  case MVT::i16:
+  case MVT::i32:
+    MF.addLiveOut(X86::EAX);
+    break;
+  case MVT::i64:
+    MF.addLiveOut(X86::EAX);
+    MF.addLiveOut(X86::EDX);
+    break;
+  case MVT::f32:
+  case MVT::f64:
+    MF.addLiveOut(X86::ST0);
+    break;
+  }
+  return ArgValues;
+}
+
+std::pair<SDOperand, SDOperand>
+X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy,
+                                  bool isVarArg, bool isTailCall,
+                                  SDOperand Callee, ArgListTy &Args,
+                                  SelectionDAG &DAG) {
+  // Count how many bytes are to be pushed on the stack.
+  unsigned NumBytes = 0;
+
+  if (Args.empty()) {
+    // Save zero bytes.
+    Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
+                        DAG.getConstant(0, getPointerTy()));
+  } else {
+    for (unsigned i = 0, e = Args.size(); i != e; ++i)
+      switch (getValueType(Args[i].second)) {
+      default: assert(0 && "Unknown value type!");
+      case MVT::i1:
+      case MVT::i8:
+      case MVT::i16:
+      case MVT::i32:
+      case MVT::f32:
+        NumBytes += 4;
+        break;
+      case MVT::i64:
+      case MVT::f64:
+        NumBytes += 8;
+        break;
+      }
+
+    Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
+                        DAG.getConstant(NumBytes, getPointerTy()));
+
+    // Arguments go on the stack in reverse order, as specified by the ABI.
+    unsigned ArgOffset = 0;
+    SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(),
+                                            X86::ESP, MVT::i32);
+    std::vector<SDOperand> Stores;
+
+    for (unsigned i = 0, e = Args.size(); i != e; ++i) {
+      SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
+      PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
+
+      switch (getValueType(Args[i].second)) {
+      default: assert(0 && "Unexpected ValueType for argument!");
+      case MVT::i1:
+      case MVT::i8:
+      case MVT::i16:
+        // Promote the integer to 32 bits.  If the input type is signed use a
+        // sign extend, otherwise use a zero extend.
+        if (Args[i].second->isSigned())
+          Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first);
+        else
+          Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first);
+
+        // FALL THROUGH
+      case MVT::i32:
+      case MVT::f32:
+        Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                     Args[i].first, PtrOff,
+                                     DAG.getSrcValue(NULL)));
+        ArgOffset += 4;
+        break;
+      case MVT::i64:
+      case MVT::f64:
+        Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                     Args[i].first, PtrOff,
+                                     DAG.getSrcValue(NULL)));
+        ArgOffset += 8;
+        break;
+      }
+    }
+    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
+  }
+
+  std::vector<MVT::ValueType> RetVals;
+  MVT::ValueType RetTyVT = getValueType(RetTy);
+  RetVals.push_back(MVT::Other);
+
+  // The result values produced have to be legal.  Promote the result.
+  switch (RetTyVT) {
+  case MVT::isVoid: break;
+  default:
+    RetVals.push_back(RetTyVT);
+    break;
+  case MVT::i1:
+  case MVT::i8:
+  case MVT::i16:
+    RetVals.push_back(MVT::i32);
+    break;
+  case MVT::f32:
+    if (X86ScalarSSE)
+      RetVals.push_back(MVT::f32);
+    else
+      RetVals.push_back(MVT::f64);
+    break;
+  case MVT::i64:
+    RetVals.push_back(MVT::i32);
+    RetVals.push_back(MVT::i32);
+    break;
+  }
+  std::vector<SDOperand> Ops;
+  Ops.push_back(Chain);
+  Ops.push_back(Callee);
+  Ops.push_back(DAG.getConstant(NumBytes, getPointerTy()));
+  Ops.push_back(DAG.getConstant(0, getPointerTy()));
+  SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL,
+                                  RetVals, Ops);
+  Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall);
+
+  SDOperand ResultVal;
+  switch (RetTyVT) {
+  case MVT::isVoid: break;
+  default:
+    ResultVal = TheCall.getValue(1);
+    break;
+  case MVT::i1:
+  case MVT::i8:
+  case MVT::i16:
+    ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1));
+    break;
+  case MVT::f32:
+    // FIXME: we would really like to remember that this FP_ROUND operation is
+    // okay to eliminate if we allow excess FP precision.
+    ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1));
+    break;
+  case MVT::i64:
+    ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1),
+                            TheCall.getValue(2));
+    break;
+  }
+
+  return std::make_pair(ResultVal, Chain);
+}
+
+SDOperand
+X86TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
+                                Value *VAListV, SelectionDAG &DAG) {
+  // vastart just stores the address of the VarArgsFrameIndex slot.
+  SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32);
+  return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP,
+                     DAG.getSrcValue(VAListV));
+}
+
+
+std::pair<SDOperand,SDOperand>
+X86TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP,
+                              Value *VAListV, const Type *ArgTy,
+                              SelectionDAG &DAG) {
+  MVT::ValueType ArgVT = getValueType(ArgTy);
+  SDOperand Val = DAG.getLoad(MVT::i32, Chain,
+                              VAListP, DAG.getSrcValue(VAListV));
+  SDOperand Result = DAG.getLoad(ArgVT, Chain, Val,
+                                 DAG.getSrcValue(NULL));
+  unsigned Amt;
+  if (ArgVT == MVT::i32)
+    Amt = 4;
+  else {
+    assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) &&
+           "Other types should have been promoted for varargs!");
+    Amt = 8;
+  }
+  Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val,
+                    DAG.getConstant(Amt, Val.getValueType()));
+  Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                      Val, VAListP, DAG.getSrcValue(VAListV));
+  return std::make_pair(Result, Chain);
+}
+
+//===----------------------------------------------------------------------===//
+//                    Fast Calling Convention implementation
+//===----------------------------------------------------------------------===//
+//
+// The X86 'fast' calling convention passes up to two integer arguments in
+// registers (an appropriate portion of EAX/EDX), passes arguments in C order,
+// and requires that the callee pop its arguments off the stack (allowing proper
+// tail calls), and has the same return value conventions as C calling convs.
+//
+// This calling convention always arranges for the callee pop value to be 8n+4
+// bytes, which is needed for tail recursion elimination and stack alignment
+// reasons.
+//
+// Note that this can be enhanced in the future to pass fp vals in registers
+// (when we have a global fp allocator) and do other tricks.
+//
+
+/// AddLiveIn - This helper function adds the specified physical register to the
+/// MachineFunction as a live in value.  It also creates a corresponding virtual
+/// register for it.
+static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
+                          TargetRegisterClass *RC) {
+  assert(RC->contains(PReg) && "Not the correct regclass!");
+  unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC);
+  MF.addLiveIn(PReg, VReg);
+  return VReg;
+}
+
+
+std::vector<SDOperand>
+X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
+  std::vector<SDOperand> ArgValues;
+
+  MachineFunction &MF = DAG.getMachineFunction();
+  MachineFrameInfo *MFI = MF.getFrameInfo();
+
+  // Add DAG nodes to load the arguments...  On entry to a function the stack
+  // frame looks like this:
+  //
+  // [ESP] -- return address
+  // [ESP + 4] -- first nonreg argument (leftmost lexically)
+  // [ESP + 8] -- second nonreg argument, if first argument is 4 bytes in size
+  //    ...
+  unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
+
+  // Keep track of the number of integer regs passed so far.  This can be either
+  // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both
+  // used).
+  unsigned NumIntRegs = 0;
+
+  for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
+    MVT::ValueType ObjectVT = getValueType(I->getType());
+    unsigned ArgIncrement = 4;
+    unsigned ObjSize = 0;
+    SDOperand ArgValue;
+
+    switch (ObjectVT) {
+    default: assert(0 && "Unhandled argument type!");
+    case MVT::i1:
+    case MVT::i8:
+      if (NumIntRegs < 2) {
+        if (!I->use_empty()) {
+          unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL,
+                                    X86::R8RegisterClass);
+          ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i8);
+          DAG.setRoot(ArgValue.getValue(1));
+        }
+        ++NumIntRegs;
+        break;
+      }
+
+      ObjSize = 1;
+      break;
+    case MVT::i16:
+      if (NumIntRegs < 2) {
+        if (!I->use_empty()) {
+          unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::AX,
+                                    X86::R16RegisterClass);
+          ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i16);
+          DAG.setRoot(ArgValue.getValue(1));
+        }
+        ++NumIntRegs;
+        break;
+      }
+      ObjSize = 2;
+      break;
+    case MVT::i32:
+      if (NumIntRegs < 2) {
+        if (!I->use_empty()) {
+          unsigned VReg = AddLiveIn(MF,NumIntRegs ? X86::EDX : X86::EAX,
+                                    X86::R32RegisterClass);
+          ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
+          DAG.setRoot(ArgValue.getValue(1));
+        }
+        ++NumIntRegs;
+        break;
+      }
+      ObjSize = 4;
+      break;
+    case MVT::i64:
+      if (NumIntRegs == 0) {
+        if (!I->use_empty()) {
+          unsigned BotReg = AddLiveIn(MF, X86::EAX, X86::R32RegisterClass);
+          unsigned TopReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass);
+
+          SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32);
+          SDOperand Hi  = DAG.getCopyFromReg(Low.getValue(1), TopReg, MVT::i32);
+          DAG.setRoot(Hi.getValue(1));
+
+          ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi);
+        }
+        NumIntRegs = 2;
+        break;
+      } else if (NumIntRegs == 1) {
+        if (!I->use_empty()) {
+          unsigned BotReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass);
+          SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32);
+          DAG.setRoot(Low.getValue(1));
+
+          // Load the high part from memory.
+          // Create the frame index object for this incoming parameter...
+          int FI = MFI->CreateFixedObject(4, ArgOffset);
+          SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
+          SDOperand Hi = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN,
+                                     DAG.getSrcValue(NULL));
+          ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi);
+        }
+        ArgOffset += 4;
+        NumIntRegs = 2;
+        break;
+      }
+      ObjSize = ArgIncrement = 8;
+      break;
+    case MVT::f32: ObjSize = 4;                break;
+    case MVT::f64: ObjSize = ArgIncrement = 8; break;
+    }
+
+    // Don't codegen dead arguments.  FIXME: remove this check when we can nuke
+    // dead loads.
+    if (ObjSize && !I->use_empty()) {
+      // Create the frame index object for this incoming parameter...
+      int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
+
+      // Create the SelectionDAG nodes corresponding to a load from this
+      // parameter.
+      SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
+
+      ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN,
+                             DAG.getSrcValue(NULL));
+    } else if (ArgValue.Val == 0) {
+      if (MVT::isInteger(ObjectVT))
+        ArgValue = DAG.getConstant(0, ObjectVT);
+      else
+        ArgValue = DAG.getConstantFP(0, ObjectVT);
+    }
+    ArgValues.push_back(ArgValue);
+
+    if (ObjSize)
+      ArgOffset += ArgIncrement;   // Move on to the next argument.
+  }
+
+  // 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 ((ArgOffset & 7) == 0)
+    ArgOffset += 4;
+
+  VarArgsFrameIndex = 0xAAAAAAA;   // fastcc functions can't have varargs.
+  ReturnAddrIndex = 0;             // No return address slot generated yet.
+  BytesToPopOnReturn = ArgOffset;  // Callee pops all stack arguments.
+  BytesCallerReserves = 0;
+
+  // Finally, inform the code generator which regs we return values in.
+  switch (getValueType(F.getReturnType())) {
+  default: assert(0 && "Unknown type!");
+  case MVT::isVoid: break;
+  case MVT::i1:
+  case MVT::i8:
+  case MVT::i16:
+  case MVT::i32:
+    MF.addLiveOut(X86::EAX);
+    break;
+  case MVT::i64:
+    MF.addLiveOut(X86::EAX);
+    MF.addLiveOut(X86::EDX);
+    break;
+  case MVT::f32:
+  case MVT::f64:
+    MF.addLiveOut(X86::ST0);
+    break;
+  }
+  return ArgValues;
+}
+
+std::pair<SDOperand, SDOperand>
+X86TargetLowering::LowerFastCCCallTo(SDOperand Chain, const Type *RetTy,
+                                     bool isTailCall, SDOperand Callee,
+                                     ArgListTy &Args, SelectionDAG &DAG) {
+  // Count how many bytes are to be pushed on the stack.
+  unsigned NumBytes = 0;
+
+  // Keep track of the number of integer regs passed so far.  This can be either
+  // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both
+  // used).
+  unsigned NumIntRegs = 0;
+
+  for (unsigned i = 0, e = Args.size(); i != e; ++i)
+    switch (getValueType(Args[i].second)) {
+    default: assert(0 && "Unknown value type!");
+    case MVT::i1:
+    case MVT::i8:
+    case MVT::i16:
+    case MVT::i32:
+      if (NumIntRegs < 2) {
+        ++NumIntRegs;
+        break;
+      }
+      // fall through
+    case MVT::f32:
+      NumBytes += 4;
+      break;
+    case MVT::i64:
+      if (NumIntRegs == 0) {
+        NumIntRegs = 2;
+        break;
+      } else if (NumIntRegs == 1) {
+        NumIntRegs = 2;
+        NumBytes += 4;
+        break;
+      }
+
+      // fall through
+    case MVT::f64:
+      NumBytes += 8;
+      break;
+    }
+
+  // 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 ((NumBytes & 7) == 0)
+    NumBytes += 4;
+
+  Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
+                      DAG.getConstant(NumBytes, getPointerTy()));
+
+  // Arguments go on the stack in reverse order, as specified by the ABI.
+  unsigned ArgOffset = 0;
+  SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(),
+                                          X86::ESP, MVT::i32);
+  NumIntRegs = 0;
+  std::vector<SDOperand> Stores;
+  std::vector<SDOperand> RegValuesToPass;
+  for (unsigned i = 0, e = Args.size(); i != e; ++i) {
+    switch (getValueType(Args[i].second)) {
+    default: assert(0 && "Unexpected ValueType for argument!");
+    case MVT::i1:
+    case MVT::i8:
+    case MVT::i16:
+    case MVT::i32:
+      if (NumIntRegs < 2) {
+        RegValuesToPass.push_back(Args[i].first);
+        ++NumIntRegs;
+        break;
+      }
+      // Fall through
+    case MVT::f32: {
+      SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
+      PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
+      Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                   Args[i].first, PtrOff,
+                                   DAG.getSrcValue(NULL)));
+      ArgOffset += 4;
+      break;
+    }
+    case MVT::i64:
+      if (NumIntRegs < 2) {    // Can pass part of it in regs?
+        SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
+                                   Args[i].first, DAG.getConstant(1, MVT::i32));
+        SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
+                                   Args[i].first, DAG.getConstant(0, MVT::i32));
+        RegValuesToPass.push_back(Lo);
+        ++NumIntRegs;
+        if (NumIntRegs < 2) {   // Pass both parts in regs?
+          RegValuesToPass.push_back(Hi);
+          ++NumIntRegs;
+        } else {
+          // Pass the high part in memory.
+          SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
+          PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
+          Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                       Hi, PtrOff, DAG.getSrcValue(NULL)));
+          ArgOffset += 4;
+        }
+        break;
+      }
+      // Fall through
+    case MVT::f64:
+      SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
+      PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
+      Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
+                                   Args[i].first, PtrOff,
+                                   DAG.getSrcValue(NULL)));
+      ArgOffset += 8;
+      break;
+    }
+  }
+  if (!Stores.empty())
+    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
+
+  // 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 ((ArgOffset & 7) == 0)
+    ArgOffset += 4;
+
+  std::vector<MVT::ValueType> RetVals;
+  MVT::ValueType RetTyVT = getValueType(RetTy);
+
+  RetVals.push_back(MVT::Other);
+
+  // The result values produced have to be legal.  Promote the result.
+  switch (RetTyVT) {
+  case MVT::isVoid: break;
+  default:
+    RetVals.push_back(RetTyVT);
+    break;
+  case MVT::i1:
+  case MVT::i8:
+  case MVT::i16:
+    RetVals.push_back(MVT::i32);
+    break;
+  case MVT::f32:
+    if (X86ScalarSSE)
+      RetVals.push_back(MVT::f32);
+    else
+      RetVals.push_back(MVT::f64);
+    break;
+  case MVT::i64:
+    RetVals.push_back(MVT::i32);
+    RetVals.push_back(MVT::i32);
+    break;
+  }
+
+  std::vector<SDOperand> Ops;
+  Ops.push_back(Chain);
+  Ops.push_back(Callee);
+  Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy()));
+  // Callee pops all arg values on the stack.
+  Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy()));
+
+  // Pass register arguments as needed.
+  Ops.insert(Ops.end(), RegValuesToPass.begin(), RegValuesToPass.end());
+
+  SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL,
+                                  RetVals, Ops);
+  Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall);
+
+  SDOperand ResultVal;
+  switch (RetTyVT) {
+  case MVT::isVoid: break;
+  default:
+    ResultVal = TheCall.getValue(1);
+    break;
+  case MVT::i1:
+  case MVT::i8:
+  case MVT::i16:
+    ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1));
+    break;
+  case MVT::f32:
+    // FIXME: we would really like to remember that this FP_ROUND operation is
+    // okay to eliminate if we allow excess FP precision.
+    ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1));
+    break;
+  case MVT::i64:
+    ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1),
+                            TheCall.getValue(2));
+    break;
+  }
+
+  return std::make_pair(ResultVal, Chain);
+}
+
+SDOperand X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) {
+  if (ReturnAddrIndex == 0) {
+    // Set up a frame object for the return address.
+    MachineFunction &MF = DAG.getMachineFunction();
+    ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(4, -4);
+  }
+
+  return DAG.getFrameIndex(ReturnAddrIndex, MVT::i32);
+}
+
+
+
+std::pair<SDOperand, SDOperand> X86TargetLowering::
+LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
+                        SelectionDAG &DAG) {
+  SDOperand Result;
+  if (Depth)        // Depths > 0 not supported yet!
+    Result = DAG.getConstant(0, getPointerTy());
+  else {
+    SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG);
+    if (!isFrameAddress)
+      // Just load the return address
+      Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(), RetAddrFI,
+                           DAG.getSrcValue(NULL));
+    else
+      Result = DAG.getNode(ISD::SUB, MVT::i32, RetAddrFI,
+                           DAG.getConstant(4, MVT::i32));
+  }
+  return std::make_pair(Result, Chain);
+}
+
+//===----------------------------------------------------------------------===//
+//                           X86 Custom Lowering Hooks
+//===----------------------------------------------------------------------===//
+
+/// LowerOperation - Provide custom lowering hooks for some operations.
+///
+SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
+  switch (Op.getOpcode()) {
+  default: assert(0 && "Should not custom lower this!");
+  case ISD::SINT_TO_FP: {
+    assert(Op.getValueType() == MVT::f64 &&
+           Op.getOperand(0).getValueType() == MVT::i64 &&
+           "Unknown SINT_TO_FP to lower!");
+    // We lower sint64->FP into a store to a temporary stack slot, followed by a
+    // FILD64m node.
+    MachineFunction &MF = DAG.getMachineFunction();
+    int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
+    SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
+    SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+                           Op.getOperand(0), StackSlot, DAG.getSrcValue(NULL));
+    std::vector<MVT::ValueType> RTs;
+    RTs.push_back(MVT::f64);
+    RTs.push_back(MVT::Other);
+    std::vector<SDOperand> Ops;
+    Ops.push_back(Store);
+    Ops.push_back(StackSlot);
+    return DAG.getNode(X86ISD::FILD64m, RTs, Ops);
+  }
+  case ISD::FP_TO_SINT: {
+    assert(Op.getValueType() <= MVT::i64 && Op.getValueType() >= MVT::i16 &&
+           Op.getOperand(0).getValueType() == MVT::f64 &&
+           "Unknown FP_TO_SINT to lower!");
+    // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary
+    // stack slot.
+    MachineFunction &MF = DAG.getMachineFunction();
+    unsigned MemSize = MVT::getSizeInBits(Op.getValueType())/8;
+    int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
+    SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
+
+    unsigned Opc;
+    switch (Op.getValueType()) {
+    default: assert(0 && "Invalid FP_TO_SINT to lower!");
+    case MVT::i16: Opc = X86ISD::FP_TO_INT16_IN_MEM; break;
+    case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break;
+    case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break;
+    }
+
+    // Build the FP_TO_INT*_IN_MEM
+    std::vector<SDOperand> Ops;
+    Ops.push_back(DAG.getEntryNode());
+    Ops.push_back(Op.getOperand(0));
+    Ops.push_back(StackSlot);
+    SDOperand FIST = DAG.getNode(Opc, MVT::Other, Ops);
+
+    // Load the result.
+    return DAG.getLoad(Op.getValueType(), FIST, StackSlot,
+                       DAG.getSrcValue(NULL));
+  }
+  }
+}
diff --git a/lib/Target/X86/X86ISelLowering.h b/lib/Target/X86/X86ISelLowering.h
new file mode 100644
index 0000000..b4468ac
--- /dev/null
+++ b/lib/Target/X86/X86ISelLowering.h
@@ -0,0 +1,131 @@
+//===-- X86ISelLowering.h - X86 DAG Lowering Interface ----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file was developed by Chris Lattner and is distributed under
+// the University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the interfaces that X86 uses to lower LLVM code into a
+// selection DAG.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef X86ISELLOWERING_H
+#define X86ISELLOWERING_H
+
+#include "llvm/Target/TargetLowering.h"
+#include "llvm/CodeGen/SelectionDAG.h"
+
+namespace llvm {
+  // X86 Specific DAG Nodes
+  namespace X86ISD {
+    enum NodeType {
+      // Start the numbering where the builtin ops leave off.
+      FIRST_NUMBER = ISD::BUILTIN_OP_END,
+
+      /// FILD64m - This instruction implements SINT_TO_FP with a
+      /// 64-bit source in memory and a FP reg result.  This corresponds to
+      /// the X86::FILD64m instruction.  It has two inputs (token chain and
+      /// address) and two outputs (FP value and token chain).
+      FILD64m,
+
+      /// FP_TO_INT*_IN_MEM - This instruction implements FP_TO_SINT with the
+      /// integer destination in memory and a FP reg source.  This corresponds
+      /// to the X86::FIST*m instructions and the rounding mode change stuff. It
+      /// has two inputs (token chain and address) and two outputs (FP value and
+      /// token chain).
+      FP_TO_INT16_IN_MEM,
+      FP_TO_INT32_IN_MEM,
+      FP_TO_INT64_IN_MEM,
+
+      /// CALL/TAILCALL - These operations represent an abstract X86 call
+      /// instruction, which includes a bunch of information.  In particular the
+      /// operands of these node are:
+      ///
+      ///     #0 - The incoming token chain
+      ///     #1 - The callee
+      ///     #2 - The number of arg bytes the caller pushes on the stack.
+      ///     #3 - The number of arg bytes the callee pops off the stack.
+      ///     #4 - The value to pass in AL/AX/EAX (optional)
+      ///     #5 - The value to pass in DL/DX/EDX (optional)
+      ///
+      /// The result values of these nodes are:
+      ///
+      ///     #0 - The outgoing token chain
+      ///     #1 - The first register result value (optional)
+      ///     #2 - The second register result value (optional)
+      ///
+      /// The CALL vs TAILCALL distinction boils down to whether the callee is
+      /// known not to modify the caller's stack frame, as is standard with
+      /// LLVM.
+      CALL,
+      TAILCALL,
+    };
+  }
+
+  //===----------------------------------------------------------------------===//
+  //  X86TargetLowering - X86 Implementation of the TargetLowering interface
+  class X86TargetLowering : public TargetLowering {
+    int VarArgsFrameIndex;            // FrameIndex for start of varargs area.
+    int ReturnAddrIndex;              // FrameIndex for return slot.
+    int BytesToPopOnReturn;           // Number of arg bytes ret should pop.
+    int BytesCallerReserves;          // Number of arg bytes caller makes.
+  public:
+    X86TargetLowering(TargetMachine &TM);
+
+    // Return the number of bytes that a function should pop when it returns (in
+    // addition to the space used by the return address).
+    //
+    unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; }
+
+    // Return the number of bytes that the caller reserves for arguments passed
+    // to this function.
+    unsigned getBytesCallerReserves() const { return BytesCallerReserves; }
+ 
+    /// LowerOperation - Provide custom lowering hooks for some operations.
+    ///
+    virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
+
+    /// LowerArguments - This hook must be implemented to indicate how we should
+    /// lower the arguments for the specified function, into the specified DAG.
+    virtual std::vector<SDOperand>
+    LowerArguments(Function &F, SelectionDAG &DAG);
+
+    /// LowerCallTo - This hook lowers an abstract call to a function into an
+    /// actual call.
+    virtual std::pair<SDOperand, SDOperand>
+    LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CC,
+                bool isTailCall, SDOperand Callee, ArgListTy &Args,
+                SelectionDAG &DAG);
+
+    virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
+                                   Value *VAListV, SelectionDAG &DAG);
+    virtual std::pair<SDOperand,SDOperand>
+    LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
+               const Type *ArgTy, SelectionDAG &DAG);
+
+    virtual std::pair<SDOperand, SDOperand>
+    LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
+                            SelectionDAG &DAG);
+
+    SDOperand getReturnAddressFrameIndex(SelectionDAG &DAG);
+
+  private:
+    // C Calling Convention implementation.
+    std::vector<SDOperand> LowerCCCArguments(Function &F, SelectionDAG &DAG);
+    std::pair<SDOperand, SDOperand>
+    LowerCCCCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
+                   bool isTailCall,
+                   SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
+
+    // Fast Calling Convention implementation.
+    std::vector<SDOperand> LowerFastCCArguments(Function &F, SelectionDAG &DAG);
+    std::pair<SDOperand, SDOperand>
+    LowerFastCCCallTo(SDOperand Chain, const Type *RetTy, bool isTailCall,
+                      SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
+  };
+}
+
+#endif    // X86ISELLOWERING_H
diff --git a/lib/Target/X86/X86ISelPattern.cpp b/lib/Target/X86/X86ISelPattern.cpp
index a244afd..58c6069 100644
--- a/lib/Target/X86/X86ISelPattern.cpp
+++ b/lib/Target/X86/X86ISelPattern.cpp
@@ -15,6 +15,7 @@
 #include "X86InstrBuilder.h"
 #include "X86RegisterInfo.h"
 #include "X86Subtarget.h"
+#include "X86ISelLowering.h"
 #include "llvm/CallingConv.h"
 #include "llvm/Constants.h"
 #include "llvm/Instructions.h"
@@ -36,1006 +37,6 @@
 #include <algorithm>
 using namespace llvm;
 
-// FIXME: temporary.
-#include "llvm/Support/CommandLine.h"
-static cl::opt<bool> EnableFastCC("enable-x86-fastcc", cl::Hidden,
-                                  cl::desc("Enable fastcc on X86"));
-
-namespace {
-  // X86 Specific DAG Nodes
-  namespace X86ISD {
-    enum NodeType {
-      // Start the numbering where the builtin ops leave off.
-      FIRST_NUMBER = ISD::BUILTIN_OP_END,
-
-      /// FILD64m - This instruction implements SINT_TO_FP with a
-      /// 64-bit source in memory and a FP reg result.  This corresponds to
-      /// the X86::FILD64m instruction.  It has two inputs (token chain and
-      /// address) and two outputs (FP value and token chain).
-      FILD64m,
-
-      /// FP_TO_INT*_IN_MEM - This instruction implements FP_TO_SINT with the
-      /// integer destination in memory and a FP reg source.  This corresponds
-      /// to the X86::FIST*m instructions and the rounding mode change stuff. It
-      /// has two inputs (token chain and address) and two outputs (FP value and
-      /// token chain).
-      FP_TO_INT16_IN_MEM,
-      FP_TO_INT32_IN_MEM,
-      FP_TO_INT64_IN_MEM,
-
-      /// CALL/TAILCALL - These operations represent an abstract X86 call
-      /// instruction, which includes a bunch of information.  In particular the
-      /// operands of these node are:
-      ///
-      ///     #0 - The incoming token chain
-      ///     #1 - The callee
-      ///     #2 - The number of arg bytes the caller pushes on the stack.
-      ///     #3 - The number of arg bytes the callee pops off the stack.
-      ///     #4 - The value to pass in AL/AX/EAX (optional)
-      ///     #5 - The value to pass in DL/DX/EDX (optional)
-      ///
-      /// The result values of these nodes are:
-      ///
-      ///     #0 - The outgoing token chain
-      ///     #1 - The first register result value (optional)
-      ///     #2 - The second register result value (optional)
-      ///
-      /// The CALL vs TAILCALL distinction boils down to whether the callee is
-      /// known not to modify the caller's stack frame, as is standard with
-      /// LLVM.
-      CALL,
-      TAILCALL,
-    };
-  }
-}
-
-//===----------------------------------------------------------------------===//
-//  X86TargetLowering - X86 Implementation of the TargetLowering interface
-namespace {
-  class X86TargetLowering : public TargetLowering {
-    int VarArgsFrameIndex;            // FrameIndex for start of varargs area.
-    int ReturnAddrIndex;              // FrameIndex for return slot.
-    int BytesToPopOnReturn;           // Number of arg bytes ret should pop.
-    int BytesCallerReserves;          // Number of arg bytes caller makes.
-  public:
-    X86TargetLowering(TargetMachine &TM) : TargetLowering(TM) {
-      // Set up the TargetLowering object.
-
-      // X86 is weird, it always uses i8 for shift amounts and setcc results.
-      setShiftAmountType(MVT::i8);
-      setSetCCResultType(MVT::i8);
-      setSetCCResultContents(ZeroOrOneSetCCResult);
-      setShiftAmountFlavor(Mask);   // shl X, 32 == shl X, 0
-
-      // Set up the register classes.
-      // FIXME: Eliminate these two classes when legalize can handle promotions
-      // well.
-      addRegisterClass(MVT::i1, X86::R8RegisterClass);
-      addRegisterClass(MVT::i8, X86::R8RegisterClass);
-      addRegisterClass(MVT::i16, X86::R16RegisterClass);
-      addRegisterClass(MVT::i32, X86::R32RegisterClass);
-
-      // 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);
-      setOperationAction(ISD::UINT_TO_FP       , MVT::i8   , Promote);
-      setOperationAction(ISD::UINT_TO_FP       , MVT::i16  , Promote);
-      setOperationAction(ISD::UINT_TO_FP       , MVT::i32  , Promote);
-
-      // Promote i1/i8 SINT_TO_FP to larger SINT_TO_FP's, as X86 doesn't have
-      // this operation.
-      setOperationAction(ISD::SINT_TO_FP       , MVT::i1   , Promote);
-      setOperationAction(ISD::SINT_TO_FP       , MVT::i8   , Promote);
-
-      if (!X86ScalarSSE) {
-        // We can handle SINT_TO_FP and FP_TO_SINT from/TO i64 even though i64
-        // isn't legal.
-        setOperationAction(ISD::SINT_TO_FP     , MVT::i64  , Custom);
-        setOperationAction(ISD::FP_TO_SINT     , MVT::i64  , Custom);
-        setOperationAction(ISD::FP_TO_SINT     , MVT::i32  , Custom);
-        setOperationAction(ISD::FP_TO_SINT     , MVT::i16  , Custom);
-      }
-
-      // Handle FP_TO_UINT by promoting the destination to a larger signed
-      // conversion.
-      setOperationAction(ISD::FP_TO_UINT       , MVT::i1   , Promote);
-      setOperationAction(ISD::FP_TO_UINT       , MVT::i8   , Promote);
-      setOperationAction(ISD::FP_TO_UINT       , MVT::i16  , Promote);
-
-      if (!X86ScalarSSE)
-        setOperationAction(ISD::FP_TO_UINT     , MVT::i32  , Promote);
-
-      // Promote i1/i8 FP_TO_SINT to larger FP_TO_SINTS's, as X86 doesn't have
-      // this operation.
-      setOperationAction(ISD::FP_TO_SINT       , MVT::i1   , Promote);
-      setOperationAction(ISD::FP_TO_SINT       , MVT::i8   , Promote);
-      setOperationAction(ISD::FP_TO_SINT       , MVT::i16  , Promote);
-
-      setOperationAction(ISD::BRCONDTWOWAY     , MVT::Other, Expand);
-      setOperationAction(ISD::BRTWOWAY_CC      , MVT::Other, Expand);
-      setOperationAction(ISD::MEMMOVE          , MVT::Other, Expand);
-      setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16  , Expand);
-      setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1   , Expand);
-      setOperationAction(ISD::FP_ROUND_INREG   , MVT::f32  , Expand);
-      setOperationAction(ISD::SEXTLOAD         , MVT::i1   , Expand);
-      setOperationAction(ISD::FREM             , MVT::f64  , Expand);
-      setOperationAction(ISD::CTPOP            , MVT::i8   , Expand);
-      setOperationAction(ISD::CTTZ             , MVT::i8   , Expand);
-      setOperationAction(ISD::CTLZ             , MVT::i8   , Expand);
-      setOperationAction(ISD::CTPOP            , MVT::i16  , Expand);
-      setOperationAction(ISD::CTTZ             , MVT::i16  , Expand);
-      setOperationAction(ISD::CTLZ             , MVT::i16  , Expand);
-      setOperationAction(ISD::CTPOP            , MVT::i32  , Expand);
-      setOperationAction(ISD::CTTZ             , MVT::i32  , Expand);
-      setOperationAction(ISD::CTLZ             , MVT::i32  , Expand);
-
-      setOperationAction(ISD::READIO           , MVT::i1   , Expand);
-      setOperationAction(ISD::READIO           , MVT::i8   , Expand);
-      setOperationAction(ISD::READIO           , MVT::i16  , Expand);
-      setOperationAction(ISD::READIO           , MVT::i32  , Expand);
-      setOperationAction(ISD::WRITEIO          , MVT::i1   , Expand);
-      setOperationAction(ISD::WRITEIO          , MVT::i8   , Expand);
-      setOperationAction(ISD::WRITEIO          , MVT::i16  , Expand);
-      setOperationAction(ISD::WRITEIO          , MVT::i32  , Expand);
-
-      // These should be promoted to a larger select which is supported.
-      setOperationAction(ISD::SELECT           , MVT::i1   , Promote);
-      setOperationAction(ISD::SELECT           , MVT::i8   , Promote);
-
-      if (X86ScalarSSE) {
-        // Set up the FP register classes.
-        addRegisterClass(MVT::f32, X86::V4F4RegisterClass);
-        addRegisterClass(MVT::f64, X86::V2F8RegisterClass);
-
-        // SSE has no load+extend ops
-        setOperationAction(ISD::EXTLOAD,  MVT::f32, Expand);
-        setOperationAction(ISD::ZEXTLOAD, MVT::f32, Expand);
-
-        // SSE has no i16 to fp conversion, only i32
-        setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote);
-        setOperationAction(ISD::FP_TO_SINT, MVT::i16, Promote);
-
-        // Expand FP_TO_UINT into a select.
-        // FIXME: We would like to use a Custom expander here eventually to do
-        // the optimal thing for SSE vs. the default expansion in the legalizer.
-        setOperationAction(ISD::FP_TO_UINT       , MVT::i32  , Expand);
-        
-        // We don't support sin/cos/sqrt/fmod
-        setOperationAction(ISD::FSIN , MVT::f64, Expand);
-        setOperationAction(ISD::FCOS , MVT::f64, Expand);
-        setOperationAction(ISD::FABS , MVT::f64, Expand);
-        setOperationAction(ISD::FNEG , MVT::f64, Expand);
-        setOperationAction(ISD::FREM , MVT::f64, Expand);
-        setOperationAction(ISD::FSIN , MVT::f32, Expand);
-        setOperationAction(ISD::FCOS , MVT::f32, Expand);
-        setOperationAction(ISD::FABS , MVT::f32, Expand);
-        setOperationAction(ISD::FNEG , MVT::f32, Expand);
-        setOperationAction(ISD::FREM , MVT::f32, Expand);
-
-        addLegalFPImmediate(+0.0); // xorps / xorpd
-      } else {
-        // Set up the FP register classes.
-        addRegisterClass(MVT::f64, X86::RFPRegisterClass);
-
-        if (!UnsafeFPMath) {
-          setOperationAction(ISD::FSIN           , MVT::f64  , Expand);
-          setOperationAction(ISD::FCOS           , MVT::f64  , Expand);
-        }
-
-        addLegalFPImmediate(+0.0); // FLD0
-        addLegalFPImmediate(+1.0); // FLD1
-        addLegalFPImmediate(-0.0); // FLD0/FCHS
-        addLegalFPImmediate(-1.0); // FLD1/FCHS
-      }
-      computeRegisterProperties();
-
-      maxStoresPerMemSet = 8; // For %llvm.memset -> sequence of stores
-      maxStoresPerMemCpy = 8; // For %llvm.memcpy -> sequence of stores
-      maxStoresPerMemMove = 8; // For %llvm.memmove -> sequence of stores
-      allowUnalignedMemoryAccesses = true; // x86 supports it!
-    }
-
-    // Return the number of bytes that a function should pop when it returns (in
-    // addition to the space used by the return address).
-    //
-    unsigned getBytesToPopOnReturn() const { return BytesToPopOnReturn; }
-
-    // Return the number of bytes that the caller reserves for arguments passed
-    // to this function.
-    unsigned getBytesCallerReserves() const { return BytesCallerReserves; }
-
-    /// LowerOperation - Provide custom lowering hooks for some operations.
-    ///
-    virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG);
-
-    /// LowerArguments - This hook must be implemented to indicate how we should
-    /// lower the arguments for the specified function, into the specified DAG.
-    virtual std::vector<SDOperand>
-    LowerArguments(Function &F, SelectionDAG &DAG);
-
-    /// LowerCallTo - This hook lowers an abstract call to a function into an
-    /// actual call.
-    virtual std::pair<SDOperand, SDOperand>
-    LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, unsigned CC,
-                bool isTailCall, SDOperand Callee, ArgListTy &Args,
-                SelectionDAG &DAG);
-
-    virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP,
-                                   Value *VAListV, SelectionDAG &DAG);
-    virtual std::pair<SDOperand,SDOperand>
-      LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV,
-                 const Type *ArgTy, SelectionDAG &DAG);
-
-    virtual std::pair<SDOperand, SDOperand>
-    LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth,
-                            SelectionDAG &DAG);
-
-    SDOperand getReturnAddressFrameIndex(SelectionDAG &DAG);
-
-  private:
-    // C Calling Convention implementation.
-    std::vector<SDOperand> LowerCCCArguments(Function &F, SelectionDAG &DAG);
-    std::pair<SDOperand, SDOperand>
-    LowerCCCCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg,
-                   bool isTailCall,
-                   SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
-
-    // Fast Calling Convention implementation.
-    std::vector<SDOperand> LowerFastCCArguments(Function &F, SelectionDAG &DAG);
-    std::pair<SDOperand, SDOperand>
-    LowerFastCCCallTo(SDOperand Chain, const Type *RetTy, bool isTailCall,
-                      SDOperand Callee, ArgListTy &Args, SelectionDAG &DAG);
-  };
-}
-
-std::vector<SDOperand>
-X86TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
-  if (F.getCallingConv() == CallingConv::Fast && EnableFastCC)
-    return LowerFastCCArguments(F, DAG);
-  return LowerCCCArguments(F, DAG);
-}
-
-std::pair<SDOperand, SDOperand>
-X86TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy,
-                               bool isVarArg, unsigned CallingConv,
-                               bool isTailCall,
-                               SDOperand Callee, ArgListTy &Args,
-                               SelectionDAG &DAG) {
-  assert((!isVarArg || CallingConv == CallingConv::C) &&
-         "Only C takes varargs!");
-  if (CallingConv == CallingConv::Fast && EnableFastCC)
-    return LowerFastCCCallTo(Chain, RetTy, isTailCall, Callee, Args, DAG);
-  return  LowerCCCCallTo(Chain, RetTy, isVarArg, isTailCall, Callee, Args, DAG);
-}
-
-//===----------------------------------------------------------------------===//
-//                    C Calling Convention implementation
-//===----------------------------------------------------------------------===//
-
-std::vector<SDOperand>
-X86TargetLowering::LowerCCCArguments(Function &F, SelectionDAG &DAG) {
-  std::vector<SDOperand> ArgValues;
-
-  MachineFunction &MF = DAG.getMachineFunction();
-  MachineFrameInfo *MFI = MF.getFrameInfo();
-
-  // Add DAG nodes to load the arguments...  On entry to a function on the X86,
-  // the stack frame looks like this:
-  //
-  // [ESP] -- return address
-  // [ESP + 4] -- first argument (leftmost lexically)
-  // [ESP + 8] -- second argument, if first argument is four bytes in size
-  //    ...
-  //
-  unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
-  for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
-    MVT::ValueType ObjectVT = getValueType(I->getType());
-    unsigned ArgIncrement = 4;
-    unsigned ObjSize;
-    switch (ObjectVT) {
-    default: assert(0 && "Unhandled argument type!");
-    case MVT::i1:
-    case MVT::i8:  ObjSize = 1;                break;
-    case MVT::i16: ObjSize = 2;                break;
-    case MVT::i32: ObjSize = 4;                break;
-    case MVT::i64: ObjSize = ArgIncrement = 8; break;
-    case MVT::f32: ObjSize = 4;                break;
-    case MVT::f64: ObjSize = ArgIncrement = 8; break;
-    }
-    // Create the frame index object for this incoming parameter...
-    int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
-
-    // Create the SelectionDAG nodes corresponding to a load from this parameter
-    SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
-
-    // Don't codegen dead arguments.  FIXME: remove this check when we can nuke
-    // dead loads.
-    SDOperand ArgValue;
-    if (!I->use_empty())
-      ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN,
-                             DAG.getSrcValue(NULL));
-    else {
-      if (MVT::isInteger(ObjectVT))
-        ArgValue = DAG.getConstant(0, ObjectVT);
-      else
-        ArgValue = DAG.getConstantFP(0, ObjectVT);
-    }
-    ArgValues.push_back(ArgValue);
-
-    ArgOffset += ArgIncrement;   // Move on to the next argument...
-  }
-
-  // If the function takes variable number of arguments, make a frame index for
-  // the start of the first vararg value... for expansion of llvm.va_start.
-  if (F.isVarArg())
-    VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset);
-  ReturnAddrIndex = 0;     // No return address slot generated yet.
-  BytesToPopOnReturn = 0;  // Callee pops nothing.
-  BytesCallerReserves = ArgOffset;
-
-  // Finally, inform the code generator which regs we return values in.
-  switch (getValueType(F.getReturnType())) {
-  default: assert(0 && "Unknown type!");
-  case MVT::isVoid: break;
-  case MVT::i1:
-  case MVT::i8:
-  case MVT::i16:
-  case MVT::i32:
-    MF.addLiveOut(X86::EAX);
-    break;
-  case MVT::i64:
-    MF.addLiveOut(X86::EAX);
-    MF.addLiveOut(X86::EDX);
-    break;
-  case MVT::f32:
-  case MVT::f64:
-    MF.addLiveOut(X86::ST0);
-    break;
-  }
-  return ArgValues;
-}
-
-std::pair<SDOperand, SDOperand>
-X86TargetLowering::LowerCCCCallTo(SDOperand Chain, const Type *RetTy,
-                                  bool isVarArg, bool isTailCall,
-                                  SDOperand Callee, ArgListTy &Args,
-                                  SelectionDAG &DAG) {
-  // Count how many bytes are to be pushed on the stack.
-  unsigned NumBytes = 0;
-
-  if (Args.empty()) {
-    // Save zero bytes.
-    Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
-                        DAG.getConstant(0, getPointerTy()));
-  } else {
-    for (unsigned i = 0, e = Args.size(); i != e; ++i)
-      switch (getValueType(Args[i].second)) {
-      default: assert(0 && "Unknown value type!");
-      case MVT::i1:
-      case MVT::i8:
-      case MVT::i16:
-      case MVT::i32:
-      case MVT::f32:
-        NumBytes += 4;
-        break;
-      case MVT::i64:
-      case MVT::f64:
-        NumBytes += 8;
-        break;
-      }
-
-    Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
-                        DAG.getConstant(NumBytes, getPointerTy()));
-
-    // Arguments go on the stack in reverse order, as specified by the ABI.
-    unsigned ArgOffset = 0;
-    SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(),
-                                            X86::ESP, MVT::i32);
-    std::vector<SDOperand> Stores;
-
-    for (unsigned i = 0, e = Args.size(); i != e; ++i) {
-      SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
-      PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
-
-      switch (getValueType(Args[i].second)) {
-      default: assert(0 && "Unexpected ValueType for argument!");
-      case MVT::i1:
-      case MVT::i8:
-      case MVT::i16:
-        // Promote the integer to 32 bits.  If the input type is signed use a
-        // sign extend, otherwise use a zero extend.
-        if (Args[i].second->isSigned())
-          Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first);
-        else
-          Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first);
-
-        // FALL THROUGH
-      case MVT::i32:
-      case MVT::f32:
-        Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                     Args[i].first, PtrOff,
-                                     DAG.getSrcValue(NULL)));
-        ArgOffset += 4;
-        break;
-      case MVT::i64:
-      case MVT::f64:
-        Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                     Args[i].first, PtrOff,
-                                     DAG.getSrcValue(NULL)));
-        ArgOffset += 8;
-        break;
-      }
-    }
-    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
-  }
-
-  std::vector<MVT::ValueType> RetVals;
-  MVT::ValueType RetTyVT = getValueType(RetTy);
-  RetVals.push_back(MVT::Other);
-
-  // The result values produced have to be legal.  Promote the result.
-  switch (RetTyVT) {
-  case MVT::isVoid: break;
-  default:
-    RetVals.push_back(RetTyVT);
-    break;
-  case MVT::i1:
-  case MVT::i8:
-  case MVT::i16:
-    RetVals.push_back(MVT::i32);
-    break;
-  case MVT::f32:
-    if (X86ScalarSSE)
-      RetVals.push_back(MVT::f32);
-    else
-      RetVals.push_back(MVT::f64);
-    break;
-  case MVT::i64:
-    RetVals.push_back(MVT::i32);
-    RetVals.push_back(MVT::i32);
-    break;
-  }
-  std::vector<SDOperand> Ops;
-  Ops.push_back(Chain);
-  Ops.push_back(Callee);
-  Ops.push_back(DAG.getConstant(NumBytes, getPointerTy()));
-  Ops.push_back(DAG.getConstant(0, getPointerTy()));
-  SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL,
-                                  RetVals, Ops);
-  Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall);
-
-  SDOperand ResultVal;
-  switch (RetTyVT) {
-  case MVT::isVoid: break;
-  default:
-    ResultVal = TheCall.getValue(1);
-    break;
-  case MVT::i1:
-  case MVT::i8:
-  case MVT::i16:
-    ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1));
-    break;
-  case MVT::f32:
-    // FIXME: we would really like to remember that this FP_ROUND operation is
-    // okay to eliminate if we allow excess FP precision.
-    ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1));
-    break;
-  case MVT::i64:
-    ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1),
-                            TheCall.getValue(2));
-    break;
-  }
-
-  return std::make_pair(ResultVal, Chain);
-}
-
-SDOperand
-X86TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
-                                Value *VAListV, SelectionDAG &DAG) {
-  // vastart just stores the address of the VarArgsFrameIndex slot.
-  SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32);
-  return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP,
-                     DAG.getSrcValue(VAListV));
-}
-
-
-std::pair<SDOperand,SDOperand>
-X86TargetLowering::LowerVAArg(SDOperand Chain, SDOperand VAListP,
-                              Value *VAListV, const Type *ArgTy,
-                              SelectionDAG &DAG) {
-  MVT::ValueType ArgVT = getValueType(ArgTy);
-  SDOperand Val = DAG.getLoad(MVT::i32, Chain,
-                              VAListP, DAG.getSrcValue(VAListV));
-  SDOperand Result = DAG.getLoad(ArgVT, Chain, Val,
-                                 DAG.getSrcValue(NULL));
-  unsigned Amt;
-  if (ArgVT == MVT::i32)
-    Amt = 4;
-  else {
-    assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) &&
-           "Other types should have been promoted for varargs!");
-    Amt = 8;
-  }
-  Val = DAG.getNode(ISD::ADD, Val.getValueType(), Val,
-                    DAG.getConstant(Amt, Val.getValueType()));
-  Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                      Val, VAListP, DAG.getSrcValue(VAListV));
-  return std::make_pair(Result, Chain);
-}
-
-//===----------------------------------------------------------------------===//
-//                    Fast Calling Convention implementation
-//===----------------------------------------------------------------------===//
-//
-// The X86 'fast' calling convention passes up to two integer arguments in
-// registers (an appropriate portion of EAX/EDX), passes arguments in C order,
-// and requires that the callee pop its arguments off the stack (allowing proper
-// tail calls), and has the same return value conventions as C calling convs.
-//
-// This calling convention always arranges for the callee pop value to be 8n+4
-// bytes, which is needed for tail recursion elimination and stack alignment
-// reasons.
-//
-// Note that this can be enhanced in the future to pass fp vals in registers
-// (when we have a global fp allocator) and do other tricks.
-//
-
-/// AddLiveIn - This helper function adds the specified physical register to the
-/// MachineFunction as a live in value.  It also creates a corresponding virtual
-/// register for it.
-static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg,
-                          TargetRegisterClass *RC) {
-  assert(RC->contains(PReg) && "Not the correct regclass!");
-  unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC);
-  MF.addLiveIn(PReg, VReg);
-  return VReg;
-}
-
-
-std::vector<SDOperand>
-X86TargetLowering::LowerFastCCArguments(Function &F, SelectionDAG &DAG) {
-  std::vector<SDOperand> ArgValues;
-
-  MachineFunction &MF = DAG.getMachineFunction();
-  MachineFrameInfo *MFI = MF.getFrameInfo();
-
-  // Add DAG nodes to load the arguments...  On entry to a function the stack
-  // frame looks like this:
-  //
-  // [ESP] -- return address
-  // [ESP + 4] -- first nonreg argument (leftmost lexically)
-  // [ESP + 8] -- second nonreg argument, if first argument is 4 bytes in size
-  //    ...
-  unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
-
-  // Keep track of the number of integer regs passed so far.  This can be either
-  // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both
-  // used).
-  unsigned NumIntRegs = 0;
-
-  for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
-    MVT::ValueType ObjectVT = getValueType(I->getType());
-    unsigned ArgIncrement = 4;
-    unsigned ObjSize = 0;
-    SDOperand ArgValue;
-
-    switch (ObjectVT) {
-    default: assert(0 && "Unhandled argument type!");
-    case MVT::i1:
-    case MVT::i8:
-      if (NumIntRegs < 2) {
-        if (!I->use_empty()) {
-          unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DL : X86::AL,
-                                    X86::R8RegisterClass);
-          ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i8);
-          DAG.setRoot(ArgValue.getValue(1));
-        }
-        ++NumIntRegs;
-        break;
-      }
-
-      ObjSize = 1;
-      break;
-    case MVT::i16:
-      if (NumIntRegs < 2) {
-        if (!I->use_empty()) {
-          unsigned VReg = AddLiveIn(MF, NumIntRegs ? X86::DX : X86::AX,
-                                    X86::R16RegisterClass);
-          ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i16);
-          DAG.setRoot(ArgValue.getValue(1));
-        }
-        ++NumIntRegs;
-        break;
-      }
-      ObjSize = 2;
-      break;
-    case MVT::i32:
-      if (NumIntRegs < 2) {
-        if (!I->use_empty()) {
-          unsigned VReg = AddLiveIn(MF,NumIntRegs ? X86::EDX : X86::EAX,
-                                    X86::R32RegisterClass);
-          ArgValue = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32);
-          DAG.setRoot(ArgValue.getValue(1));
-        }
-        ++NumIntRegs;
-        break;
-      }
-      ObjSize = 4;
-      break;
-    case MVT::i64:
-      if (NumIntRegs == 0) {
-        if (!I->use_empty()) {
-          unsigned BotReg = AddLiveIn(MF, X86::EAX, X86::R32RegisterClass);
-          unsigned TopReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass);
-
-          SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32);
-          SDOperand Hi  = DAG.getCopyFromReg(Low.getValue(1), TopReg, MVT::i32);
-          DAG.setRoot(Hi.getValue(1));
-
-          ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi);
-        }
-        NumIntRegs = 2;
-        break;
-      } else if (NumIntRegs == 1) {
-        if (!I->use_empty()) {
-          unsigned BotReg = AddLiveIn(MF, X86::EDX, X86::R32RegisterClass);
-          SDOperand Low = DAG.getCopyFromReg(DAG.getRoot(), BotReg, MVT::i32);
-          DAG.setRoot(Low.getValue(1));
-
-          // Load the high part from memory.
-          // Create the frame index object for this incoming parameter...
-          int FI = MFI->CreateFixedObject(4, ArgOffset);
-          SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
-          SDOperand Hi = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN,
-                                     DAG.getSrcValue(NULL));
-          ArgValue = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Low, Hi);
-        }
-        ArgOffset += 4;
-        NumIntRegs = 2;
-        break;
-      }
-      ObjSize = ArgIncrement = 8;
-      break;
-    case MVT::f32: ObjSize = 4;                break;
-    case MVT::f64: ObjSize = ArgIncrement = 8; break;
-    }
-
-    // Don't codegen dead arguments.  FIXME: remove this check when we can nuke
-    // dead loads.
-    if (ObjSize && !I->use_empty()) {
-      // Create the frame index object for this incoming parameter...
-      int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
-
-      // Create the SelectionDAG nodes corresponding to a load from this
-      // parameter.
-      SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
-
-      ArgValue = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN,
-                             DAG.getSrcValue(NULL));
-    } else if (ArgValue.Val == 0) {
-      if (MVT::isInteger(ObjectVT))
-        ArgValue = DAG.getConstant(0, ObjectVT);
-      else
-        ArgValue = DAG.getConstantFP(0, ObjectVT);
-    }
-    ArgValues.push_back(ArgValue);
-
-    if (ObjSize)
-      ArgOffset += ArgIncrement;   // Move on to the next argument.
-  }
-
-  // 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 ((ArgOffset & 7) == 0)
-    ArgOffset += 4;
-
-  VarArgsFrameIndex = 0xAAAAAAA;   // fastcc functions can't have varargs.
-  ReturnAddrIndex = 0;             // No return address slot generated yet.
-  BytesToPopOnReturn = ArgOffset;  // Callee pops all stack arguments.
-  BytesCallerReserves = 0;
-
-  // Finally, inform the code generator which regs we return values in.
-  switch (getValueType(F.getReturnType())) {
-  default: assert(0 && "Unknown type!");
-  case MVT::isVoid: break;
-  case MVT::i1:
-  case MVT::i8:
-  case MVT::i16:
-  case MVT::i32:
-    MF.addLiveOut(X86::EAX);
-    break;
-  case MVT::i64:
-    MF.addLiveOut(X86::EAX);
-    MF.addLiveOut(X86::EDX);
-    break;
-  case MVT::f32:
-  case MVT::f64:
-    MF.addLiveOut(X86::ST0);
-    break;
-  }
-  return ArgValues;
-}
-
-std::pair<SDOperand, SDOperand>
-X86TargetLowering::LowerFastCCCallTo(SDOperand Chain, const Type *RetTy,
-                                     bool isTailCall, SDOperand Callee,
-                                     ArgListTy &Args, SelectionDAG &DAG) {
-  // Count how many bytes are to be pushed on the stack.
-  unsigned NumBytes = 0;
-
-  // Keep track of the number of integer regs passed so far.  This can be either
-  // 0 (neither EAX or EDX used), 1 (EAX is used) or 2 (EAX and EDX are both
-  // used).
-  unsigned NumIntRegs = 0;
-
-  for (unsigned i = 0, e = Args.size(); i != e; ++i)
-    switch (getValueType(Args[i].second)) {
-    default: assert(0 && "Unknown value type!");
-    case MVT::i1:
-    case MVT::i8:
-    case MVT::i16:
-    case MVT::i32:
-      if (NumIntRegs < 2) {
-        ++NumIntRegs;
-        break;
-      }
-      // fall through
-    case MVT::f32:
-      NumBytes += 4;
-      break;
-    case MVT::i64:
-      if (NumIntRegs == 0) {
-        NumIntRegs = 2;
-        break;
-      } else if (NumIntRegs == 1) {
-        NumIntRegs = 2;
-        NumBytes += 4;
-        break;
-      }
-
-      // fall through
-    case MVT::f64:
-      NumBytes += 8;
-      break;
-    }
-
-  // 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 ((NumBytes & 7) == 0)
-    NumBytes += 4;
-
-  Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
-                      DAG.getConstant(NumBytes, getPointerTy()));
-
-  // Arguments go on the stack in reverse order, as specified by the ABI.
-  unsigned ArgOffset = 0;
-  SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(),
-                                          X86::ESP, MVT::i32);
-  NumIntRegs = 0;
-  std::vector<SDOperand> Stores;
-  std::vector<SDOperand> RegValuesToPass;
-  for (unsigned i = 0, e = Args.size(); i != e; ++i) {
-    switch (getValueType(Args[i].second)) {
-    default: assert(0 && "Unexpected ValueType for argument!");
-    case MVT::i1:
-    case MVT::i8:
-    case MVT::i16:
-    case MVT::i32:
-      if (NumIntRegs < 2) {
-        RegValuesToPass.push_back(Args[i].first);
-        ++NumIntRegs;
-        break;
-      }
-      // Fall through
-    case MVT::f32: {
-      SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
-      PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
-      Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                   Args[i].first, PtrOff,
-                                   DAG.getSrcValue(NULL)));
-      ArgOffset += 4;
-      break;
-    }
-    case MVT::i64:
-      if (NumIntRegs < 2) {    // Can pass part of it in regs?
-        SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
-                                   Args[i].first, DAG.getConstant(1, MVT::i32));
-        SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
-                                   Args[i].first, DAG.getConstant(0, MVT::i32));
-        RegValuesToPass.push_back(Lo);
-        ++NumIntRegs;
-        if (NumIntRegs < 2) {   // Pass both parts in regs?
-          RegValuesToPass.push_back(Hi);
-          ++NumIntRegs;
-        } else {
-          // Pass the high part in memory.
-          SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
-          PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
-          Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                       Hi, PtrOff, DAG.getSrcValue(NULL)));
-          ArgOffset += 4;
-        }
-        break;
-      }
-      // Fall through
-    case MVT::f64:
-      SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
-      PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
-      Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
-                                   Args[i].first, PtrOff,
-                                   DAG.getSrcValue(NULL)));
-      ArgOffset += 8;
-      break;
-    }
-  }
-  if (!Stores.empty())
-    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
-
-  // 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 ((ArgOffset & 7) == 0)
-    ArgOffset += 4;
-
-  std::vector<MVT::ValueType> RetVals;
-  MVT::ValueType RetTyVT = getValueType(RetTy);
-
-  RetVals.push_back(MVT::Other);
-
-  // The result values produced have to be legal.  Promote the result.
-  switch (RetTyVT) {
-  case MVT::isVoid: break;
-  default:
-    RetVals.push_back(RetTyVT);
-    break;
-  case MVT::i1:
-  case MVT::i8:
-  case MVT::i16:
-    RetVals.push_back(MVT::i32);
-    break;
-  case MVT::f32:
-    if (X86ScalarSSE)
-      RetVals.push_back(MVT::f32);
-    else
-      RetVals.push_back(MVT::f64);
-    break;
-  case MVT::i64:
-    RetVals.push_back(MVT::i32);
-    RetVals.push_back(MVT::i32);
-    break;
-  }
-
-  std::vector<SDOperand> Ops;
-  Ops.push_back(Chain);
-  Ops.push_back(Callee);
-  Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy()));
-  // Callee pops all arg values on the stack.
-  Ops.push_back(DAG.getConstant(ArgOffset, getPointerTy()));
-
-  // Pass register arguments as needed.
-  Ops.insert(Ops.end(), RegValuesToPass.begin(), RegValuesToPass.end());
-
-  SDOperand TheCall = DAG.getNode(isTailCall ? X86ISD::TAILCALL : X86ISD::CALL,
-                                  RetVals, Ops);
-  Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, TheCall);
-
-  SDOperand ResultVal;
-  switch (RetTyVT) {
-  case MVT::isVoid: break;
-  default:
-    ResultVal = TheCall.getValue(1);
-    break;
-  case MVT::i1:
-  case MVT::i8:
-  case MVT::i16:
-    ResultVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, TheCall.getValue(1));
-    break;
-  case MVT::f32:
-    // FIXME: we would really like to remember that this FP_ROUND operation is
-    // okay to eliminate if we allow excess FP precision.
-    ResultVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, TheCall.getValue(1));
-    break;
-  case MVT::i64:
-    ResultVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, TheCall.getValue(1),
-                            TheCall.getValue(2));
-    break;
-  }
-
-  return std::make_pair(ResultVal, Chain);
-}
-
-SDOperand X86TargetLowering::getReturnAddressFrameIndex(SelectionDAG &DAG) {
-  if (ReturnAddrIndex == 0) {
-    // Set up a frame object for the return address.
-    MachineFunction &MF = DAG.getMachineFunction();
-    ReturnAddrIndex = MF.getFrameInfo()->CreateFixedObject(4, -4);
-  }
-
-  return DAG.getFrameIndex(ReturnAddrIndex, MVT::i32);
-}
-
-
-
-std::pair<SDOperand, SDOperand> X86TargetLowering::
-LowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
-                        SelectionDAG &DAG) {
-  SDOperand Result;
-  if (Depth)        // Depths > 0 not supported yet!
-    Result = DAG.getConstant(0, getPointerTy());
-  else {
-    SDOperand RetAddrFI = getReturnAddressFrameIndex(DAG);
-    if (!isFrameAddress)
-      // Just load the return address
-      Result = DAG.getLoad(MVT::i32, DAG.getEntryNode(), RetAddrFI,
-                           DAG.getSrcValue(NULL));
-    else
-      Result = DAG.getNode(ISD::SUB, MVT::i32, RetAddrFI,
-                           DAG.getConstant(4, MVT::i32));
-  }
-  return std::make_pair(Result, Chain);
-}
-
-//===----------------------------------------------------------------------===//
-//                           X86 Custom Lowering Hooks
-//===----------------------------------------------------------------------===//
-
-/// LowerOperation - Provide custom lowering hooks for some operations.
-///
-SDOperand X86TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
-  switch (Op.getOpcode()) {
-  default: assert(0 && "Should not custom lower this!");
-  case ISD::SINT_TO_FP: {
-    assert(Op.getValueType() == MVT::f64 &&
-           Op.getOperand(0).getValueType() == MVT::i64 &&
-           "Unknown SINT_TO_FP to lower!");
-    // We lower sint64->FP into a store to a temporary stack slot, followed by a
-    // FILD64m node.
-    MachineFunction &MF = DAG.getMachineFunction();
-    int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
-    SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
-    SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
-                           Op.getOperand(0), StackSlot, DAG.getSrcValue(NULL));
-    std::vector<MVT::ValueType> RTs;
-    RTs.push_back(MVT::f64);
-    RTs.push_back(MVT::Other);
-    std::vector<SDOperand> Ops;
-    Ops.push_back(Store);
-    Ops.push_back(StackSlot);
-    return DAG.getNode(X86ISD::FILD64m, RTs, Ops);
-  }
-  case ISD::FP_TO_SINT: {
-    assert(Op.getValueType() <= MVT::i64 && Op.getValueType() >= MVT::i16 &&
-           Op.getOperand(0).getValueType() == MVT::f64 &&
-           "Unknown FP_TO_SINT to lower!");
-    // We lower FP->sint64 into FISTP64, followed by a load, all to a temporary
-    // stack slot.
-    MachineFunction &MF = DAG.getMachineFunction();
-    unsigned MemSize = MVT::getSizeInBits(Op.getValueType())/8;
-    int SSFI = MF.getFrameInfo()->CreateStackObject(MemSize, MemSize);
-    SDOperand StackSlot = DAG.getFrameIndex(SSFI, getPointerTy());
-
-    unsigned Opc;
-    switch (Op.getValueType()) {
-    default: assert(0 && "Invalid FP_TO_SINT to lower!");
-    case MVT::i16: Opc = X86ISD::FP_TO_INT16_IN_MEM; break;
-    case MVT::i32: Opc = X86ISD::FP_TO_INT32_IN_MEM; break;
-    case MVT::i64: Opc = X86ISD::FP_TO_INT64_IN_MEM; break;
-    }
-
-    // Build the FP_TO_INT*_IN_MEM
-    std::vector<SDOperand> Ops;
-    Ops.push_back(DAG.getEntryNode());
-    Ops.push_back(Op.getOperand(0));
-    Ops.push_back(StackSlot);
-    SDOperand FIST = DAG.getNode(Opc, MVT::Other, Ops);
-
-    // Load the result.
-    return DAG.getLoad(Op.getValueType(), FIST, StackSlot,
-                       DAG.getSrcValue(NULL));
-  }
-  }
-}
-
-
 //===----------------------------------------------------------------------===//
 //                      Pattern Matcher Implementation
 //===----------------------------------------------------------------------===//
@@ -4635,10 +3636,10 @@
 }
 
 
-/// createX86PatternInstructionSelector - This pass converts an LLVM function
+/// createX86ISelPattern - This pass converts an LLVM function
 /// into a machine code representation using pattern matching and a machine
 /// description file.
 ///
-FunctionPass *llvm::createX86PatternInstructionSelector(TargetMachine &TM) {
+FunctionPass *llvm::createX86ISelPattern(TargetMachine &TM) {
   return new ISel(TM);
 }
diff --git a/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index 3d33cc2..4862a23 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -124,7 +124,7 @@
   PM.add(createUnreachableBlockEliminationPass());
 
   // Install an instruction selector.
-  PM.add(createX86PatternInstructionSelector(*this));
+  PM.add(createX86ISelPattern(*this));
 
   // Run optional SSA-based machine code optimizations next...
   if (!NoSSAPeephole)
@@ -192,7 +192,7 @@
   PM.add(createUnreachableBlockEliminationPass());
 
   // Install an instruction selector.
-  PM.add(createX86PatternInstructionSelector(TM));
+  PM.add(createX86ISelPattern(TM));
 
   // Run optional SSA-based machine code optimizations next...
   if (!NoSSAPeephole)
