Clean up.
[oota-llvm.git] / lib / Target / X86 / X86ISelDAGToDAG.cpp
index f58ca60ed9f125993d2a1d744c236efe0aa7d2c2..09f07d01caa539852a0e386528556f0c4fe015c4 100644 (file)
@@ -12,7 +12,7 @@
 //
 //===----------------------------------------------------------------------===//
 
-#define DEBUG_TYPE "isel"
+#define DEBUG_TYPE "x86-isel"
 #include "X86.h"
 #include "X86InstrBuilder.h"
 #include "X86ISelLowering.h"
 #include "llvm/CodeGen/SSARegMap.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/Debug.h"
+#include "llvm/Support/MathExtras.h"
 #include "llvm/ADT/Statistic.h"
 #include <iostream>
+#include <queue>
 #include <set>
 using namespace llvm;
 
@@ -55,16 +58,19 @@ namespace {
       int FrameIndex;
     } Base;
 
+    bool isRIPRel;     // RIP relative?
     unsigned Scale;
     SDOperand IndexReg; 
     unsigned Disp;
     GlobalValue *GV;
     Constant *CP;
+    const char *ES;
+    int JT;
     unsigned Align;    // CP alignment.
 
     X86ISelAddressMode()
-      : BaseType(RegBase), Scale(1), IndexReg(), Disp(0), GV(0),
-        CP(0), Align(0) {
+      : BaseType(RegBase), isRIPRel(false), Scale(1), IndexReg(), Disp(0),
+        GV(0), CP(0), ES(0), JT(-1), Align(0) {
     }
   };
 }
@@ -73,15 +79,26 @@ namespace {
   Statistic<>
   NumFPKill("x86-codegen", "Number of FP_REG_KILL instructions added");
 
+  Statistic<>
+  NumLoadMoved("x86-codegen", "Number of loads moved below TokenFactor");
+
   //===--------------------------------------------------------------------===//
   /// ISel - X86 specific code to select X86 machine instructions for
   /// SelectionDAG operations.
   ///
-  class X86DAGToDAGISel : public SelectionDAGISel {
+  class VISIBILITY_HIDDEN X86DAGToDAGISel : public SelectionDAGISel {
     /// ContainsFPCode - Every instruction we select that uses or defines a FP
     /// register should set this to true.
     bool ContainsFPCode;
 
+    /// FastISel - Enable fast(er) instruction selection.
+    ///
+    bool FastISel;
+
+    /// TM - Keep a reference to X86TargetMachine.
+    ///
+    X86TargetMachine &TM;
+
     /// X86Lowering - This object fully describes how to lower LLVM code to an
     /// X86-specific SelectionDAG.
     X86TargetLowering X86Lowering;
@@ -90,13 +107,16 @@ namespace {
     /// make the right decision when generating code for different targets.
     const X86Subtarget *Subtarget;
 
+    /// GlobalBaseReg - keeps track of the virtual register mapped onto global
+    /// base register.
     unsigned GlobalBaseReg;
+
   public:
-    X86DAGToDAGISel(X86TargetMachine &TM)
+    X86DAGToDAGISel(X86TargetMachine &tm, bool fast)
       : SelectionDAGISel(X86Lowering),
-        X86Lowering(*TM.getTargetLowering()) {
-      Subtarget = &TM.getSubtarget<X86Subtarget>();
-    }
+        ContainsFPCode(false), FastISel(fast), TM(tm),
+        X86Lowering(*TM.getTargetLowering()),
+        Subtarget(&TM.getSubtarget<X86Subtarget>()) {}
 
     virtual bool runOnFunction(Function &Fn) {
       // Make sure we re-emit a set of the global base reg if necessary
@@ -114,32 +134,57 @@ namespace {
 
     virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF);
 
+    virtual bool CanBeFoldedBy(SDNode *N, SDNode *U, SDNode *Root);
+
 // Include the pieces autogenerated from the target description.
 #include "X86GenDAGISel.inc"
 
   private:
-    void Select(SDOperand &Result, SDOperand N);
+    SDNode *Select(SDOperand N);
 
     bool MatchAddress(SDOperand N, X86ISelAddressMode &AM, bool isRoot = true);
-    bool SelectAddr(SDOperand N, SDOperand &Base, SDOperand &Scale,
-                    SDOperand &Index, SDOperand &Disp);
-    bool SelectLEAAddr(SDOperand N, SDOperand &Base, SDOperand &Scale,
-                       SDOperand &Index, SDOperand &Disp);
+    bool SelectAddr(SDOperand Op, SDOperand N, SDOperand &Base,
+                    SDOperand &Scale, SDOperand &Index, SDOperand &Disp);
+    bool SelectLEAAddr(SDOperand Op, SDOperand N, SDOperand &Base,
+                       SDOperand &Scale, SDOperand &Index, SDOperand &Disp);
+    bool SelectScalarSSELoad(SDOperand Op, SDOperand Pred,
+                             SDOperand N, SDOperand &Base, SDOperand &Scale,
+                             SDOperand &Index, SDOperand &Disp,
+                             SDOperand &InChain, SDOperand &OutChain);
     bool TryFoldLoad(SDOperand P, SDOperand N,
                      SDOperand &Base, SDOperand &Scale,
                      SDOperand &Index, SDOperand &Disp);
+    void InstructionSelectPreprocess(SelectionDAG &DAG);
+
+    /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
+    /// inline asm expressions.
+    virtual bool SelectInlineAsmMemoryOperand(const SDOperand &Op,
+                                              char ConstraintCode,
+                                              std::vector<SDOperand> &OutOps,
+                                              SelectionDAG &DAG);
+    
+    void EmitSpecialCodeForMain(MachineBasicBlock *BB, MachineFrameInfo *MFI);
 
     inline void getAddressOperands(X86ISelAddressMode &AM, SDOperand &Base, 
                                    SDOperand &Scale, SDOperand &Index,
                                    SDOperand &Disp) {
       Base  = (AM.BaseType == X86ISelAddressMode::FrameIndexBase) ?
-        CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, MVT::i32) : AM.Base.Reg;
+        CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, TLI.getPointerTy()) :
+        AM.Base.Reg;
       Scale = getI8Imm(AM.Scale);
       Index = AM.IndexReg;
-      Disp  = AM.GV ? CurDAG->getTargetGlobalAddress(AM.GV, MVT::i32, AM.Disp)
-        : (AM.CP ?
-           CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Align, AM.Disp)
-           : getI32Imm(AM.Disp));
+      // These are 32-bit even in 64-bit mode since RIP relative offset
+      // is 32-bit.
+      if (AM.GV)
+        Disp = CurDAG->getTargetGlobalAddress(AM.GV, MVT::i32, AM.Disp);
+      else if (AM.CP)
+        Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32, AM.Align, AM.Disp);
+      else if (AM.ES)
+        Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32);
+      else if (AM.JT != -1)
+        Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32);
+      else
+        Disp = getI32Imm(AM.Disp);
     }
 
     /// getI8Imm - Return a target constant with the specified value, of type
@@ -162,7 +207,7 @@ namespace {
 
     /// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC
     /// base register.  Return the virtual register that holds this value.
-    SDOperand getGlobalBaseReg();
+    SDNode *getGlobalBaseReg();
 
 #ifndef NDEBUG
     unsigned Indent;
@@ -170,25 +215,263 @@ namespace {
   };
 }
 
+static SDNode *findFlagUse(SDNode *N) {
+  unsigned FlagResNo = N->getNumValues()-1;
+  for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) {
+    SDNode *User = *I;
+    for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) {
+      SDOperand Op = User->getOperand(i);
+      if (Op.Val == N && Op.ResNo == FlagResNo)
+        return User;
+    }
+  }
+  return NULL;
+}
+
+static void findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse,
+                          SDNode *Root, SDNode *Skip, bool &found,
+                          std::set<SDNode *> &Visited) {
+  if (found ||
+      Use->getNodeId() > Def->getNodeId() ||
+      !Visited.insert(Use).second)
+    return;
+
+  for (unsigned i = 0, e = Use->getNumOperands(); !found && i != e; ++i) {
+    SDNode *N = Use->getOperand(i).Val;
+    if (N == Skip)
+      continue;
+    if (N == Def) {
+      if (Use == ImmedUse)
+        continue; // Immediate use is ok.
+      if (Use == Root) {
+        assert(Use->getOpcode() == ISD::STORE ||
+               Use->getOpcode() == X86ISD::CMP);
+        continue;
+      }
+      found = true;
+      break;
+    }
+    findNonImmUse(N, Def, ImmedUse, Root, Skip, found, Visited);
+  }
+}
+
+/// isNonImmUse - Start searching from Root up the DAG to check is Def can
+/// be reached. Return true if that's the case. However, ignore direct uses
+/// by ImmedUse (which would be U in the example illustrated in
+/// CanBeFoldedBy) and by Root (which can happen in the store case).
+/// FIXME: to be really generic, we should allow direct use by any node
+/// that is being folded. But realisticly since we only fold loads which
+/// have one non-chain use, we only need to watch out for load/op/store
+/// and load/op/cmp case where the root (store / cmp) may reach the load via
+/// its chain operand.
+static inline bool isNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse,
+                               SDNode *Skip = NULL) {
+  std::set<SDNode *> Visited;
+  bool found = false;
+  findNonImmUse(Root, Def, ImmedUse, Root, Skip, found, Visited);
+  return found;
+}
+
+
+bool X86DAGToDAGISel::CanBeFoldedBy(SDNode *N, SDNode *U, SDNode *Root) {
+  if (FastISel) return false;
+
+  // If U use can somehow reach N through another path then U can't fold N or
+  // it will create a cycle. e.g. In the following diagram, U can reach N
+  // through X. If N is folded into into U, then X is both a predecessor and
+  // a successor of U.
+  //
+  //         [ N ]
+  //         ^  ^
+  //         |  |
+  //        /   \---
+  //      /        [X]
+  //      |         ^
+  //     [U]--------|
+
+  if (isNonImmUse(Root, N, U))
+    return false;
+
+  // If U produces a flag, then it gets (even more) interesting. Since it
+  // would have been "glued" together with its flag use, we need to check if
+  // it might reach N:
+  //
+  //       [ N ]
+  //        ^ ^
+  //        | |
+  //       [U] \--
+  //        ^   [TF]
+  //        |    ^
+  //        |    |
+  //         \  /
+  //          [FU]
+  //
+  // If FU (flag use) indirectly reach N (the load), and U fold N (call it
+  // NU), then TF is a predecessor of FU and a successor of NU. But since
+  // NU and FU are flagged together, this effectively creates a cycle.
+  bool HasFlagUse = false;
+  MVT::ValueType VT = Root->getValueType(Root->getNumValues()-1);
+  while ((VT == MVT::Flag && !Root->use_empty())) {
+    SDNode *FU = findFlagUse(Root);
+    if (FU == NULL)
+      break;
+    else {
+      Root = FU;
+      HasFlagUse = true;
+    }
+    VT = Root->getValueType(Root->getNumValues()-1);
+  }
+
+  if (HasFlagUse)
+    return !isNonImmUse(Root, N, Root, U);
+  return true;
+}
+
+/// MoveBelowTokenFactor - Replace TokenFactor operand with load's chain operand
+/// and move load below the TokenFactor. Replace store's chain operand with
+/// load's chain result.
+static void MoveBelowTokenFactor(SelectionDAG &DAG, SDOperand Load,
+                                 SDOperand Store, SDOperand TF) {
+  std::vector<SDOperand> Ops;
+  for (unsigned i = 0, e = TF.Val->getNumOperands(); i != e; ++i)
+    if (Load.Val == TF.Val->getOperand(i).Val)
+      Ops.push_back(Load.Val->getOperand(0));
+    else
+      Ops.push_back(TF.Val->getOperand(i));
+  DAG.UpdateNodeOperands(TF, &Ops[0], Ops.size());
+  DAG.UpdateNodeOperands(Load, TF, Load.getOperand(1), Load.getOperand(2));
+  DAG.UpdateNodeOperands(Store, Load.getValue(1), Store.getOperand(1),
+                         Store.getOperand(2), Store.getOperand(3));
+}
+
+/// InstructionSelectPreprocess - Preprocess the DAG to allow the instruction
+/// selector to pick more load-modify-store instructions. This is a common
+/// case:
+///
+///     [Load chain]
+///         ^
+///         |
+///       [Load]
+///       ^    ^
+///       |    |
+///      /      \-
+///     /         |
+/// [TokenFactor] [Op]
+///     ^          ^
+///     |          |
+///      \        /
+///       \      /
+///       [Store]
+///
+/// The fact the store's chain operand != load's chain will prevent the
+/// (store (op (load))) instruction from being selected. We can transform it to:
+///
+///     [Load chain]
+///         ^
+///         |
+///    [TokenFactor]
+///         ^
+///         |
+///       [Load]
+///       ^    ^
+///       |    |
+///       |     \- 
+///       |       | 
+///       |     [Op]
+///       |       ^
+///       |       |
+///       \      /
+///        \    /
+///       [Store]
+void X86DAGToDAGISel::InstructionSelectPreprocess(SelectionDAG &DAG) {
+  for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
+         E = DAG.allnodes_end(); I != E; ++I) {
+    if (!ISD::isNON_TRUNCStore(I))
+      continue;
+    SDOperand Chain = I->getOperand(0);
+    if (Chain.Val->getOpcode() != ISD::TokenFactor)
+      continue;
+
+    SDOperand N1 = I->getOperand(1);
+    SDOperand N2 = I->getOperand(2);
+    if (MVT::isFloatingPoint(N1.getValueType()) ||
+        MVT::isVector(N1.getValueType()) ||
+        !N1.hasOneUse())
+      continue;
+
+    bool RModW = false;
+    SDOperand Load;
+    unsigned Opcode = N1.Val->getOpcode();
+    switch (Opcode) {
+      case ISD::ADD:
+      case ISD::MUL:
+      case ISD::AND:
+      case ISD::OR:
+      case ISD::XOR:
+      case ISD::ADDC:
+      case ISD::ADDE: {
+        SDOperand N10 = N1.getOperand(0);
+        SDOperand N11 = N1.getOperand(1);
+        if (ISD::isNON_EXTLoad(N10.Val))
+          RModW = true;
+        else if (ISD::isNON_EXTLoad(N11.Val)) {
+          RModW = true;
+          std::swap(N10, N11);
+        }
+        RModW = RModW && N10.Val->isOperand(Chain.Val) && N10.hasOneUse() &&
+          (N10.getOperand(1) == N2) &&
+          (N10.Val->getValueType(0) == N1.getValueType());
+        if (RModW)
+          Load = N10;
+        break;
+      }
+      case ISD::SUB:
+      case ISD::SHL:
+      case ISD::SRA:
+      case ISD::SRL:
+      case ISD::ROTL:
+      case ISD::ROTR:
+      case ISD::SUBC:
+      case ISD::SUBE:
+      case X86ISD::SHLD:
+      case X86ISD::SHRD: {
+        SDOperand N10 = N1.getOperand(0);
+        if (ISD::isNON_EXTLoad(N10.Val))
+          RModW = N10.Val->isOperand(Chain.Val) && N10.hasOneUse() &&
+            (N10.getOperand(1) == N2) &&
+            (N10.Val->getValueType(0) == N1.getValueType());
+        if (RModW)
+          Load = N10;
+        break;
+      }
+    }
+
+    if (RModW) {
+      MoveBelowTokenFactor(DAG, Load, SDOperand(I, 0), Chain);
+      ++NumLoadMoved;
+    }
+  }
+}
+
 /// InstructionSelectBasicBlock - This callback is invoked by SelectionDAGISel
 /// when it has created a SelectionDAG for us to codegen.
 void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
   DEBUG(BB->dump());
   MachineFunction::iterator FirstMBB = BB;
 
+  if (!FastISel)
+    InstructionSelectPreprocess(DAG);
+
   // Codegen the basic block.
 #ifndef NDEBUG
-  DEBUG(std::cerr << "===== Instruction selection begins:\n");
+  DOUT << "===== Instruction selection begins:\n";
   Indent = 0;
 #endif
   DAG.setRoot(SelectRoot(DAG.getRoot()));
-  assert(InFlightSet.empty() && "ISel InFlightSet has not been emptied!");
 #ifndef NDEBUG
-  DEBUG(std::cerr << "===== Instruction selection ends:\n");
+  DOUT << "===== Instruction selection ends:\n";
 #endif
-  CodeGenMap.clear();
-  HandleMap.clear();
-  ReplaceMap.clear();
+
   DAG.RemoveDeadNodes();
 
   // Emit machine code to BB. 
@@ -242,7 +525,8 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
 
     // Finally, if we found any FP code, emit the FP_REG_KILL instruction.
     if (ContainsFPCode) {
-      BuildMI(*BB, BB->getFirstTerminator(), X86::FP_REG_KILL, 0);
+      BuildMI(*BB, BB->getFirstTerminator(),
+              TM.getInstrInfo()->get(X86::FP_REG_KILL));
       ++NumFPKill;
     }
   }
@@ -250,18 +534,22 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
 
 /// EmitSpecialCodeForMain - Emit any code that needs to be executed only in
 /// the main function.
-static void EmitSpecialCodeForMain(MachineBasicBlock *BB,
-                                   MachineFrameInfo *MFI) {
+void X86DAGToDAGISel::EmitSpecialCodeForMain(MachineBasicBlock *BB,
+                                             MachineFrameInfo *MFI) {
+  const TargetInstrInfo *TII = TM.getInstrInfo();
+  if (Subtarget->isTargetCygwin())
+    BuildMI(BB, TII->get(X86::CALLpcrel32)).addExternalSymbol("__main");
+
   // Switch the FPU to 64-bit precision mode for better compatibility and speed.
   int CWFrameIdx = MFI->CreateStackObject(2, 2);
-  addFrameReference(BuildMI(BB, X86::FNSTCW16m, 4), CWFrameIdx);
+  addFrameReference(BuildMI(BB, TII->get(X86::FNSTCW16m)), CWFrameIdx);
 
   // Set the high part to be 64-bit precision.
-  addFrameReference(BuildMI(BB, X86::MOV8mi, 5),
+  addFrameReference(BuildMI(BB, TII->get(X86::MOV8mi)),
                     CWFrameIdx, 1).addImm(2);
 
   // Reload the modified control word now.
-  addFrameReference(BuildMI(BB, X86::FLDCW16m, 4), CWFrameIdx);
+  addFrameReference(BuildMI(BB, TII->get(X86::FLDCW16m)), CWFrameIdx);
 }
 
 void X86DAGToDAGISel::EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {
@@ -276,31 +564,100 @@ void X86DAGToDAGISel::EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {
 /// addressing mode
 bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
                                    bool isRoot) {
-  bool Available = false;
-  // If N has already been selected, reuse the result unless in some very
-  // specific cases.
-  std::map<SDOperand, SDOperand>::iterator CGMI= CodeGenMap.find(N.getValue(0));
-  if (CGMI != CodeGenMap.end()) {
-    Available = true;
+  // RIP relative addressing: %rip + 32-bit displacement!
+  if (AM.isRIPRel) {
+    if (!AM.ES && AM.JT != -1 && N.getOpcode() == ISD::Constant) {
+      int64_t Val = cast<ConstantSDNode>(N)->getSignExtended();
+      if (isInt32(AM.Disp + Val)) {
+        AM.Disp += Val;
+        return false;
+      }
+    }
+    return true;
   }
 
+  int id = N.Val->getNodeId();
+  bool Available = isSelected(id);
+
   switch (N.getOpcode()) {
   default: break;
-  case ISD::Constant:
-    AM.Disp += cast<ConstantSDNode>(N)->getValue();
-    return false;
+  case ISD::Constant: {
+    int64_t Val = cast<ConstantSDNode>(N)->getSignExtended();
+    if (isInt32(AM.Disp + Val)) {
+      AM.Disp += Val;
+      return false;
+    }
+    break;
+  }
+
+  case ISD::TargetConstantPool:
+    if (AM.BaseType == X86ISelAddressMode::RegBase &&
+        AM.Base.Reg.Val == 0 &&
+        AM.CP == 0) {
+      ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(N);
+      AM.CP = CP->getConstVal();
+      AM.Align = CP->getAlignment();
+      AM.Disp += CP->getOffset();
+      return false;
+    }
+    break;
+
+  case ISD::TargetGlobalAddress:
+    if (AM.BaseType == X86ISelAddressMode::RegBase &&
+        AM.Base.Reg.Val == 0 &&
+        AM.GV == 0) {
+      GlobalAddressSDNode *G = cast<GlobalAddressSDNode>(N);
+      AM.GV = G->getGlobal();
+      AM.Disp += G->getOffset();
+      return false;
+    }
+    break;
+
+  case ISD::TargetExternalSymbol:
+    if (isRoot &&
+        AM.BaseType == X86ISelAddressMode::RegBase &&
+        AM.Base.Reg.Val == 0) {
+      ExternalSymbolSDNode *S = cast<ExternalSymbolSDNode>(N.getOperand(0));
+      AM.ES = S->getSymbol();
+      return false;
+    }
+    break;
+
+  case ISD::TargetJumpTable:
+    if (isRoot &&
+        AM.BaseType == X86ISelAddressMode::RegBase &&
+        AM.Base.Reg.Val == 0) {
+      JumpTableSDNode *J = cast<JumpTableSDNode>(N.getOperand(0));
+      AM.JT = J->getIndex();
+      return false;
+    }
+    break;
 
   case X86ISD::Wrapper:
-    // If both base and index components have been picked, we can't fit
-    // the result available in the register in the addressing mode. Duplicate
-    // GlobalAddress or ConstantPool as displacement.
+    // If value is available in a register both base and index components have
+    // been picked, we can't fit the result available in the register in the
+    // addressing mode. Duplicate GlobalAddress or ConstantPool as displacement.
+
+    // Can't fit GV or CP in addressing mode for X86-64 medium or large code
+    // model since the displacement field is 32-bit. Ok for small code model.
+
+    // For X86-64 PIC code, only allow GV / CP + displacement so we can use RIP
+    // relative addressing mode.
+    if (Subtarget->is64Bit() && TM.getCodeModel() != CodeModel::Small)
+      break;
     if (!Available || (AM.Base.Reg.Val && AM.IndexReg.Val)) {
+      bool isRIP = Subtarget->is64Bit();
+      if (isRIP &&
+          (AM.Base.Reg.Val || AM.Scale > 1 || AM.IndexReg.Val ||
+           AM.BaseType == X86ISelAddressMode::FrameIndexBase))
+        break;
       if (ConstantPoolSDNode *CP =
           dyn_cast<ConstantPoolSDNode>(N.getOperand(0))) {
         if (AM.CP == 0) {
-          AM.CP = CP->get();
+          AM.CP = CP->getConstVal();
           AM.Align = CP->getAlignment();
           AM.Disp += CP->getOffset();
+          AM.isRIPRel = isRIP;
           return false;
         }
       } else if (GlobalAddressSDNode *G =
@@ -308,6 +665,19 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
         if (AM.GV == 0) {
           AM.GV = G->getGlobal();
           AM.Disp += G->getOffset();
+          AM.isRIPRel = isRIP;
+          return false;
+        }
+      } else if (isRoot && isRIP) {
+        if (ExternalSymbolSDNode *S =
+            dyn_cast<ExternalSymbolSDNode>(N.getOperand(0))) {
+          AM.ES = S->getSymbol();
+          AM.isRIPRel = true;
+          return false;
+        } else if (JumpTableSDNode *J =
+                   dyn_cast<JumpTableSDNode>(N.getOperand(0))) {
+          AM.JT = J->getIndex();
+          AM.isRIPRel = true;
           return false;
         }
       }
@@ -338,7 +708,11 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
             AM.IndexReg = ShVal.Val->getOperand(0);
             ConstantSDNode *AddVal =
               cast<ConstantSDNode>(ShVal.Val->getOperand(1));
-            AM.Disp += AddVal->getValue() << Val;
+            uint64_t Disp = AM.Disp + (AddVal->getValue() << Val);
+            if (isInt32(Disp))
+              AM.Disp = Disp;
+            else
+              AM.IndexReg = ShVal;
           } else {
             AM.IndexReg = ShVal;
           }
@@ -368,7 +742,11 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
             Reg = MulVal.Val->getOperand(0);
             ConstantSDNode *AddVal =
               cast<ConstantSDNode>(MulVal.Val->getOperand(1));
-            AM.Disp += AddVal->getValue() * CN->getValue();
+            uint64_t Disp = AM.Disp + AddVal->getValue() * CN->getValue();
+            if (isInt32(Disp))
+              AM.Disp = Disp;
+            else
+              Reg = N.Val->getOperand(0);
           } else {
             Reg = N.Val->getOperand(0);
           }
@@ -392,6 +770,30 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
     }
     break;
   }
+
+  case ISD::OR: {
+    if (!Available) {
+      X86ISelAddressMode Backup = AM;
+      // Look for (x << c1) | c2 where (c2 < c1)
+      ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.Val->getOperand(0));
+      if (CN && !MatchAddress(N.Val->getOperand(1), AM, false)) {
+        if (AM.GV == NULL && AM.Disp == 0 && CN->getValue() < AM.Scale) {
+          AM.Disp = CN->getValue();
+          return false;
+        }
+      }
+      AM = Backup;
+      CN = dyn_cast<ConstantSDNode>(N.Val->getOperand(1));
+      if (CN && !MatchAddress(N.Val->getOperand(0), AM, false)) {
+        if (AM.GV == NULL && AM.Disp == 0 && CN->getValue() < AM.Scale) {
+          AM.Disp = CN->getValue();
+          return false;
+        }
+      }
+      AM = Backup;
+    }
+    break;
+  }
   }
 
   // Is the base register already occupied?
@@ -416,48 +818,125 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
 /// SelectAddr - returns true if it is able pattern match an addressing mode.
 /// It returns the operands which make up the maximal addressing mode it can
 /// match by reference.
-bool X86DAGToDAGISel::SelectAddr(SDOperand N, SDOperand &Base, SDOperand &Scale,
-                                 SDOperand &Index, SDOperand &Disp) {
+bool X86DAGToDAGISel::SelectAddr(SDOperand Op, SDOperand N, SDOperand &Base,
+                                 SDOperand &Scale, SDOperand &Index,
+                                 SDOperand &Disp) {
   X86ISelAddressMode AM;
   if (MatchAddress(N, AM))
     return false;
 
+  MVT::ValueType VT = N.getValueType();
   if (AM.BaseType == X86ISelAddressMode::RegBase) {
     if (!AM.Base.Reg.Val)
-      AM.Base.Reg = CurDAG->getRegister(0, MVT::i32);
+      AM.Base.Reg = CurDAG->getRegister(0, VT);
   }
 
   if (!AM.IndexReg.Val)
-    AM.IndexReg = CurDAG->getRegister(0, MVT::i32);
+    AM.IndexReg = CurDAG->getRegister(0, VT);
 
   getAddressOperands(AM, Base, Scale, Index, Disp);
-
   return true;
 }
 
+/// isZeroNode - Returns true if Elt is a constant zero or a floating point
+/// constant +0.0.
+static inline bool isZeroNode(SDOperand Elt) {
+  return ((isa<ConstantSDNode>(Elt) &&
+  cast<ConstantSDNode>(Elt)->getValue() == 0) ||
+  (isa<ConstantFPSDNode>(Elt) &&
+  cast<ConstantFPSDNode>(Elt)->isExactlyValue(0.0)));
+}
+
+
+/// SelectScalarSSELoad - Match a scalar SSE load.  In particular, we want to
+/// match a load whose top elements are either undef or zeros.  The load flavor
+/// is derived from the type of N, which is either v4f32 or v2f64.
+bool X86DAGToDAGISel::SelectScalarSSELoad(SDOperand Op, SDOperand Pred,
+                                          SDOperand N, SDOperand &Base,
+                                          SDOperand &Scale, SDOperand &Index,
+                                          SDOperand &Disp, SDOperand &InChain,
+                                          SDOperand &OutChain) {
+  if (N.getOpcode() == ISD::SCALAR_TO_VECTOR) {
+    InChain = N.getOperand(0).getValue(1);
+    if (ISD::isNON_EXTLoad(InChain.Val) &&
+        InChain.getValue(0).hasOneUse() &&
+        N.hasOneUse() &&
+        CanBeFoldedBy(N.Val, Pred.Val, Op.Val)) {
+      LoadSDNode *LD = cast<LoadSDNode>(InChain);
+      if (!SelectAddr(Op, LD->getBasePtr(), Base, Scale, Index, Disp))
+        return false;
+      OutChain = LD->getChain();
+      return true;
+    }
+  }
+
+  // Also handle the case where we explicitly require zeros in the top
+  // elements.  This is a vector shuffle from the zero vector.
+  if (N.getOpcode() == ISD::VECTOR_SHUFFLE && N.Val->hasOneUse() &&
+      N.getOperand(0).getOpcode() == ISD::BUILD_VECTOR &&
+      N.getOperand(1).getOpcode() == ISD::SCALAR_TO_VECTOR && 
+      N.getOperand(1).Val->hasOneUse() &&
+      ISD::isNON_EXTLoad(N.getOperand(1).getOperand(0).Val) &&
+      N.getOperand(1).getOperand(0).hasOneUse()) {
+    // Check to see if the BUILD_VECTOR is building a zero vector.
+    SDOperand BV = N.getOperand(0);
+    for (unsigned i = 0, e = BV.getNumOperands(); i != e; ++i)
+      if (!isZeroNode(BV.getOperand(i)) &&
+          BV.getOperand(i).getOpcode() != ISD::UNDEF)
+        return false;  // Not a zero/undef vector.
+    // Check to see if the shuffle mask is 4/L/L/L or 2/L, where L is something
+    // from the LHS.
+    unsigned VecWidth = BV.getNumOperands();
+    SDOperand ShufMask = N.getOperand(2);
+    assert(ShufMask.getOpcode() == ISD::BUILD_VECTOR && "Invalid shuf mask!");
+    if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(ShufMask.getOperand(0))) {
+      if (C->getValue() == VecWidth) {
+        for (unsigned i = 1; i != VecWidth; ++i) {
+          if (ShufMask.getOperand(i).getOpcode() == ISD::UNDEF) {
+            // ok.
+          } else {
+            ConstantSDNode *C = cast<ConstantSDNode>(ShufMask.getOperand(i));
+            if (C->getValue() >= VecWidth) return false;
+          }
+        }
+      }
+      
+      // Okay, this is a zero extending load.  Fold it.
+      LoadSDNode *LD = cast<LoadSDNode>(N.getOperand(1).getOperand(0));
+      if (!SelectAddr(Op, LD->getBasePtr(), Base, Scale, Index, Disp))
+        return false;
+      OutChain = LD->getChain();
+      InChain = SDOperand(LD, 1);
+      return true;
+    }
+  }
+  return false;
+}
+
+
 /// SelectLEAAddr - it calls SelectAddr and determines if the maximal addressing
 /// mode it matches can be cost effectively emitted as an LEA instruction.
-/// For X86, it always is unless it's just a (Reg + const).
-bool X86DAGToDAGISel::SelectLEAAddr(SDOperand N, SDOperand &Base,
-                                    SDOperand &Scale,
+bool X86DAGToDAGISel::SelectLEAAddr(SDOperand Op, SDOperand N,
+                                    SDOperand &Base, SDOperand &Scale,
                                     SDOperand &Index, SDOperand &Disp) {
   X86ISelAddressMode AM;
   if (MatchAddress(N, AM))
     return false;
 
+  MVT::ValueType VT = N.getValueType();
   unsigned Complexity = 0;
   if (AM.BaseType == X86ISelAddressMode::RegBase)
     if (AM.Base.Reg.Val)
       Complexity = 1;
     else
-      AM.Base.Reg = CurDAG->getRegister(0, MVT::i32);
+      AM.Base.Reg = CurDAG->getRegister(0, VT);
   else if (AM.BaseType == X86ISelAddressMode::FrameIndexBase)
     Complexity = 4;
 
   if (AM.IndexReg.Val)
     Complexity++;
   else
-    AM.IndexReg = CurDAG->getRegister(0, MVT::i32);
+    AM.IndexReg = CurDAG->getRegister(0, VT);
 
   if (AM.Scale > 2) 
     Complexity += 2;
@@ -470,8 +949,14 @@ bool X86DAGToDAGISel::SelectLEAAddr(SDOperand N, SDOperand &Base,
   // optimal (especially for code size consideration). LEA is nice because of
   // its three-address nature. Tweak the cost function again when we can run
   // convertToThreeAddress() at register allocation time.
-  if (AM.GV || AM.CP)
-    Complexity += 2;
+  if (AM.GV || AM.CP || AM.ES || AM.JT != -1) {
+    // For X86-64, we should always use lea to materialize RIP relative
+    // addresses.
+    if (Subtarget->is64Bit())
+      Complexity = 4;
+    else
+      Complexity += 2;
+  }
 
   if (AM.Disp && (AM.Base.Reg.Val || AM.IndexReg.Val))
     Complexity++;
@@ -480,43 +965,35 @@ bool X86DAGToDAGISel::SelectLEAAddr(SDOperand N, SDOperand &Base,
     getAddressOperands(AM, Base, Scale, Index, Disp);
     return true;
   }
-
   return false;
 }
 
 bool X86DAGToDAGISel::TryFoldLoad(SDOperand P, SDOperand N,
                                   SDOperand &Base, SDOperand &Scale,
                                   SDOperand &Index, SDOperand &Disp) {
-  if (N.getOpcode() == ISD::LOAD &&
+  if (ISD::isNON_EXTLoad(N.Val) &&
       N.hasOneUse() &&
-      !CodeGenMap.count(N.getValue(0)) &&
-      (P.getNumOperands() == 1 || !isNonImmUse(P.Val, N.Val)))
-    return SelectAddr(N.getOperand(1), Base, Scale, Index, Disp);
-  return false;
-}
-
-static bool isRegister0(SDOperand Op) {
-  if (RegisterSDNode *R = dyn_cast<RegisterSDNode>(Op))
-    return (R->getReg() == 0);
+      CanBeFoldedBy(N.Val, P.Val, P.Val))
+    return SelectAddr(P, N.getOperand(1), Base, Scale, Index, Disp);
   return false;
 }
 
 /// getGlobalBaseReg - Output the instructions required to put the
 /// base address to use for accessing globals into a register.
 ///
-SDOperand X86DAGToDAGISel::getGlobalBaseReg() {
+SDNode *X86DAGToDAGISel::getGlobalBaseReg() {
+  assert(!Subtarget->is64Bit() && "X86-64 PIC uses RIP relative addressing");
   if (!GlobalBaseReg) {
     // Insert the set of GlobalBaseReg into the first MBB of the function
     MachineBasicBlock &FirstMBB = BB->getParent()->front();
     MachineBasicBlock::iterator MBBI = FirstMBB.begin();
     SSARegMap *RegMap = BB->getParent()->getSSARegMap();
-    // FIXME: when we get to LP64, we will need to create the appropriate
-    // type of register here.
     GlobalBaseReg = RegMap->createVirtualRegister(X86::GR32RegisterClass);
-    BuildMI(FirstMBB, MBBI, X86::MovePCtoStack, 0);
-    BuildMI(FirstMBB, MBBI, X86::POP32r, 1, GlobalBaseReg);
+    const TargetInstrInfo *TII = TM.getInstrInfo();
+    BuildMI(FirstMBB, MBBI, TII->get(X86::MovePCtoStack));
+    BuildMI(FirstMBB, MBBI, TII->get(X86::POP32r), GlobalBaseReg);
   }
-  return CurDAG->getRegister(GlobalBaseReg, MVT::i32);
+  return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).Val;
 }
 
 static SDNode *FindCallStartFromCall(SDNode *Node) {
@@ -526,58 +1003,43 @@ static SDNode *FindCallStartFromCall(SDNode *Node) {
   return FindCallStartFromCall(Node->getOperand(0).Val);
 }
 
-void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
+SDNode *X86DAGToDAGISel::Select(SDOperand N) {
   SDNode *Node = N.Val;
   MVT::ValueType NVT = Node->getValueType(0);
   unsigned Opc, MOpc;
   unsigned Opcode = Node->getOpcode();
 
 #ifndef NDEBUG
-  DEBUG(std::cerr << std::string(Indent, ' '));
-  DEBUG(std::cerr << "Selecting: ");
+  DOUT << std::string(Indent, ' ') << "Selecting: ";
   DEBUG(Node->dump(CurDAG));
-  DEBUG(std::cerr << "\n");
+  DOUT << "\n";
   Indent += 2;
 #endif
 
   if (Opcode >= ISD::BUILTIN_OP_END && Opcode < X86ISD::FIRST_NUMBER) {
-    Result = N;
 #ifndef NDEBUG
-    DEBUG(std::cerr << std::string(Indent-2, ' '));
-    DEBUG(std::cerr << "== ");
+    DOUT << std::string(Indent-2, ' ') << "== ";
     DEBUG(Node->dump(CurDAG));
-    DEBUG(std::cerr << "\n");
+    DOUT << "\n";
     Indent -= 2;
 #endif
-    return;   // Already selected.
+    return NULL;   // Already selected.
   }
 
-  std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(N);
-  if (CGMI != CodeGenMap.end()) {
-    Result = CGMI->second;
-#ifndef NDEBUG
-    DEBUG(std::cerr << std::string(Indent-2, ' '));
-    DEBUG(std::cerr << "== ");
-    DEBUG(Result.Val->dump(CurDAG));
-    DEBUG(std::cerr << "\n");
-    Indent -= 2;
-#endif
-    return;
-  }
-  
   switch (Opcode) {
     default: break;
     case X86ISD::GlobalBaseReg: 
-      Result = getGlobalBaseReg();
-      return;
+      return getGlobalBaseReg();
 
     case ISD::ADD: {
       // Turn ADD X, c to MOV32ri X+c. This cannot be done with tblgen'd
       // code and is matched first so to prevent it from being turned into
       // LEA32r X+c.
+      // In 64-bit mode, use LEA to take advantage of RIP-relative addressing.
+      MVT::ValueType PtrVT = TLI.getPointerTy();
       SDOperand N0 = N.getOperand(0);
       SDOperand N1 = N.getOperand(1);
-      if (N.Val->getValueType(0) == MVT::i32 &&
+      if (N.Val->getValueType(0) == PtrVT &&
           N0.getOpcode() == X86ISD::Wrapper &&
           N1.getOpcode() == ISD::Constant) {
         unsigned Offset = (unsigned)cast<ConstantSDNode>(N1)->getValue();
@@ -585,23 +1047,22 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
         // TODO: handle ExternalSymbolSDNode.
         if (GlobalAddressSDNode *G =
             dyn_cast<GlobalAddressSDNode>(N0.getOperand(0))) {
-          C = CurDAG->getTargetGlobalAddress(G->getGlobal(), MVT::i32,
+          C = CurDAG->getTargetGlobalAddress(G->getGlobal(), PtrVT,
                                              G->getOffset() + Offset);
         } else if (ConstantPoolSDNode *CP =
                    dyn_cast<ConstantPoolSDNode>(N0.getOperand(0))) {
-          C = CurDAG->getTargetConstantPool(CP->get(), MVT::i32,
+          C = CurDAG->getTargetConstantPool(CP->getConstVal(), PtrVT,
                                             CP->getAlignment(),
                                             CP->getOffset()+Offset);
         }
 
         if (C.Val) {
-          if (N.Val->hasOneUse()) {
-            Result = CurDAG->SelectNodeTo(N.Val, X86::MOV32ri, MVT::i32, C);
-          } else {
-            SDNode *ResNode = CurDAG->getTargetNode(X86::MOV32ri, MVT::i32, C);
-            Result = CodeGenMap[N] = SDOperand(ResNode, 0);
-          }
-          return;
+          if (Subtarget->is64Bit()) {
+            SDOperand Ops[] = { CurDAG->getRegister(0, PtrVT), getI8Imm(1),
+                                CurDAG->getRegister(0, PtrVT), C };
+            return CurDAG->SelectNodeTo(N.Val, X86::LEA64r, MVT::i64, Ops, 4);
+          } else
+            return CurDAG->SelectNodeTo(N.Val, X86::MOV32ri, PtrVT, C);
         }
       }
 
@@ -617,6 +1078,7 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
         case MVT::i8:  Opc = X86::MUL8r;  MOpc = X86::MUL8m;  break;
         case MVT::i16: Opc = X86::MUL16r; MOpc = X86::MUL16m; break;
         case MVT::i32: Opc = X86::MUL32r; MOpc = X86::MUL32m; break;
+        case MVT::i64: Opc = X86::MUL64r; MOpc = X86::MUL64m; break;
         }
       else
         switch (NVT) {
@@ -624,6 +1086,7 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
         case MVT::i8:  Opc = X86::IMUL8r;  MOpc = X86::IMUL8m;  break;
         case MVT::i16: Opc = X86::IMUL16r; MOpc = X86::IMUL16m; break;
         case MVT::i32: Opc = X86::IMUL32r; MOpc = X86::IMUL32m; break;
+        case MVT::i64: Opc = X86::IMUL64r; MOpc = X86::IMUL64m; break;
         }
 
       unsigned LoReg, HiReg;
@@ -632,6 +1095,7 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
       case MVT::i8:  LoReg = X86::AL;  HiReg = X86::AH;  break;
       case MVT::i16: LoReg = X86::AX;  HiReg = X86::DX;  break;
       case MVT::i32: LoReg = X86::EAX; HiReg = X86::EDX; break;
+      case MVT::i64: LoReg = X86::RAX; HiReg = X86::RDX; break;
       }
 
       SDOperand N0 = Node->getOperand(0);
@@ -650,48 +1114,46 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
       }
 
       SDOperand Chain;
-      if (foldedLoad)
-        Select(Chain, N1.getOperand(0));
-      else
+      if (foldedLoad) {
+        Chain = N1.getOperand(0);
+        AddToISelQueue(Chain);
+      } else
         Chain = CurDAG->getEntryNode();
 
       SDOperand InFlag(0, 0);
-      Select(N0, N0);
+      AddToISelQueue(N0);
       Chain  = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(LoReg, NVT),
                                     N0, InFlag);
       InFlag = Chain.getValue(1);
 
       if (foldedLoad) {
-        Select(Tmp0, Tmp0);
-        Select(Tmp1, Tmp1);
-        Select(Tmp2, Tmp2);
-        Select(Tmp3, Tmp3);
+        AddToISelQueue(Tmp0);
+        AddToISelQueue(Tmp1);
+        AddToISelQueue(Tmp2);
+        AddToISelQueue(Tmp3);
+        SDOperand Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Chain, InFlag };
         SDNode *CNode =
-          CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Tmp0, Tmp1,
-                                Tmp2, Tmp3, Chain, InFlag);
+          CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Ops, 6);
         Chain  = SDOperand(CNode, 0);
         InFlag = SDOperand(CNode, 1);
       } else {
-        Select(N1, N1);
+        AddToISelQueue(N1);
         InFlag =
           SDOperand(CurDAG->getTargetNode(Opc, MVT::Flag, N1, InFlag), 0);
       }
 
-      Result = CurDAG->getCopyFromReg(Chain, HiReg, NVT, InFlag);
-      CodeGenMap[N.getValue(0)] = Result;
-      if (foldedLoad) {
-        CodeGenMap[N1.getValue(1)] = Result.getValue(1);
-        AddHandleReplacement(N1.Val, 1, Result.Val, 1);
-      }
+      SDOperand Result = CurDAG->getCopyFromReg(Chain, HiReg, NVT, InFlag);
+      ReplaceUses(N.getValue(0), Result);
+      if (foldedLoad)
+        ReplaceUses(N1.getValue(1), Result.getValue(1));
 
 #ifndef NDEBUG
-      DEBUG(std::cerr << std::string(Indent-2, ' '));
-      DEBUG(std::cerr << "== ");
+      DOUT << std::string(Indent-2, ' ') << "=> ";
       DEBUG(Result.Val->dump(CurDAG));
-      DEBUG(std::cerr << "\n");
+      DOUT << "\n";
       Indent -= 2;
 #endif
-      return;
+      return NULL;
     }
       
     case ISD::SDIV:
@@ -706,6 +1168,7 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
         case MVT::i8:  Opc = X86::DIV8r;  MOpc = X86::DIV8m;  break;
         case MVT::i16: Opc = X86::DIV16r; MOpc = X86::DIV16m; break;
         case MVT::i32: Opc = X86::DIV32r; MOpc = X86::DIV32m; break;
+        case MVT::i64: Opc = X86::DIV64r; MOpc = X86::DIV64m; break;
         }
       else
         switch (NVT) {
@@ -713,6 +1176,7 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
         case MVT::i8:  Opc = X86::IDIV8r;  MOpc = X86::IDIV8m;  break;
         case MVT::i16: Opc = X86::IDIV16r; MOpc = X86::IDIV16m; break;
         case MVT::i32: Opc = X86::IDIV32r; MOpc = X86::IDIV32m; break;
+        case MVT::i64: Opc = X86::IDIV64r; MOpc = X86::IDIV64m; break;
         }
 
       unsigned LoReg, HiReg;
@@ -721,89 +1185,108 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
       default: assert(0 && "Unsupported VT!");
       case MVT::i8:
         LoReg = X86::AL;  HiReg = X86::AH;
-        ClrOpcode  = X86::MOV8ri;
+        ClrOpcode  = 0;
         SExtOpcode = X86::CBW;
         break;
       case MVT::i16:
         LoReg = X86::AX;  HiReg = X86::DX;
-        ClrOpcode  = X86::MOV16ri;
+        ClrOpcode  = X86::MOV16r0;
         SExtOpcode = X86::CWD;
         break;
       case MVT::i32:
         LoReg = X86::EAX; HiReg = X86::EDX;
-        ClrOpcode  = X86::MOV32ri;
+        ClrOpcode  = X86::MOV32r0;
         SExtOpcode = X86::CDQ;
         break;
+      case MVT::i64:
+        LoReg = X86::RAX; HiReg = X86::RDX;
+        ClrOpcode  = X86::MOV64r0;
+        SExtOpcode = X86::CQO;
+        break;
       }
 
       SDOperand N0 = Node->getOperand(0);
       SDOperand N1 = Node->getOperand(1);
-
-      bool foldedLoad = false;
-      SDOperand Tmp0, Tmp1, Tmp2, Tmp3;
-      foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3);
-      SDOperand Chain;
-      if (foldedLoad)
-        Select(Chain, N1.getOperand(0));
-      else
-        Chain = CurDAG->getEntryNode();
-
       SDOperand InFlag(0, 0);
-      Select(N0, N0);
-      Chain  = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(LoReg, NVT),
-                                    N0, InFlag);
-      InFlag = Chain.getValue(1);
-
-      if (isSigned) {
-        // Sign extend the low part into the high part.
-        InFlag =
-          SDOperand(CurDAG->getTargetNode(SExtOpcode, MVT::Flag, InFlag), 0);
-      } else {
-        // Zero out the high part, effectively zero extending the input.
-        SDOperand ClrNode =
-          SDOperand(CurDAG->getTargetNode(ClrOpcode, NVT,
-                                         CurDAG->getTargetConstant(0, NVT)), 0);
-        Chain  = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(HiReg, NVT),
-                                      ClrNode, InFlag);
+      if (NVT == MVT::i8 && !isSigned) {
+        // Special case for div8, just use a move with zero extension to AX to
+        // clear the upper 8 bits (AH).
+        SDOperand Tmp0, Tmp1, Tmp2, Tmp3, Move, Chain;
+        if (TryFoldLoad(N, N0, Tmp0, Tmp1, Tmp2, Tmp3)) {
+          SDOperand Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, N0.getOperand(0) };
+          AddToISelQueue(N0.getOperand(0));
+          AddToISelQueue(Tmp0);
+          AddToISelQueue(Tmp1);
+          AddToISelQueue(Tmp2);
+          AddToISelQueue(Tmp3);
+          Move =
+            SDOperand(CurDAG->getTargetNode(X86::MOVZX16rm8, MVT::i16, MVT::Other,
+                                            Ops, 5), 0);
+          Chain = Move.getValue(1);
+          ReplaceUses(N0.getValue(1), Chain);
+        } else {
+          AddToISelQueue(N0);
+          Move =
+            SDOperand(CurDAG->getTargetNode(X86::MOVZX16rr8, MVT::i16, N0), 0);
+          Chain = CurDAG->getEntryNode();
+        }
+        Chain  = CurDAG->getCopyToReg(Chain, X86::AX, Move, InFlag);
         InFlag = Chain.getValue(1);
+      } else {
+        AddToISelQueue(N0);
+        InFlag =
+          CurDAG->getCopyToReg(CurDAG->getEntryNode(), LoReg, N0,
+                               InFlag).getValue(1);
+        if (isSigned) {
+          // Sign extend the low part into the high part.
+          InFlag =
+            SDOperand(CurDAG->getTargetNode(SExtOpcode, MVT::Flag, InFlag), 0);
+        } else {
+          // Zero out the high part, effectively zero extending the input.
+          SDOperand ClrNode = SDOperand(CurDAG->getTargetNode(ClrOpcode, NVT), 0);
+          InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), HiReg, ClrNode,
+                                        InFlag).getValue(1);
+        }
       }
 
+      SDOperand Tmp0, Tmp1, Tmp2, Tmp3, Chain;
+      bool foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3);
       if (foldedLoad) {
-        Select(Tmp0, Tmp0);
-        Select(Tmp1, Tmp1);
-        Select(Tmp2, Tmp2);
-        Select(Tmp3, Tmp3);
+        AddToISelQueue(N1.getOperand(0));
+        AddToISelQueue(Tmp0);
+        AddToISelQueue(Tmp1);
+        AddToISelQueue(Tmp2);
+        AddToISelQueue(Tmp3);
+        SDOperand Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, N1.getOperand(0), InFlag };
         SDNode *CNode =
-          CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Tmp0, Tmp1,
-                                Tmp2, Tmp3, Chain, InFlag);
+          CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Ops, 6);
         Chain  = SDOperand(CNode, 0);
         InFlag = SDOperand(CNode, 1);
       } else {
-        Select(N1, N1);
+        AddToISelQueue(N1);
+        Chain = CurDAG->getEntryNode();
         InFlag =
           SDOperand(CurDAG->getTargetNode(Opc, MVT::Flag, N1, InFlag), 0);
       }
 
-      Result = CurDAG->getCopyFromReg(Chain, isDiv ? LoReg : HiReg,
-                                      NVT, InFlag);
-      CodeGenMap[N.getValue(0)] = Result;
-      if (foldedLoad) {
-        CodeGenMap[N1.getValue(1)] = Result.getValue(1);
-        AddHandleReplacement(N1.Val, 1, Result.Val, 1);
-      }
+      SDOperand Result =
+        CurDAG->getCopyFromReg(Chain, isDiv ? LoReg : HiReg, NVT, InFlag);
+      ReplaceUses(N.getValue(0), Result);
+      if (foldedLoad)
+        ReplaceUses(N1.getValue(1), Result.getValue(1));
 
 #ifndef NDEBUG
-      DEBUG(std::cerr << std::string(Indent-2, ' '));
-      DEBUG(std::cerr << "== ");
+      DOUT << std::string(Indent-2, ' ') << "=> ";
       DEBUG(Result.Val->dump(CurDAG));
-      DEBUG(std::cerr << "\n");
+      DOUT << "\n";
       Indent -= 2;
 #endif
-      return;
+
+      return NULL;
     }
 
     case ISD::TRUNCATE: {
-      if (NVT == MVT::i8) {
+      if (!Subtarget->is64Bit() && NVT == MVT::i8) {
         unsigned Opc2;
         MVT::ValueType VT;
         switch (Node->getOperand(0).getValueType()) {
@@ -811,48 +1294,76 @@ void X86DAGToDAGISel::Select(SDOperand &Result, SDOperand N) {
         case MVT::i16:
           Opc = X86::MOV16to16_;
           VT = MVT::i16;
-          Opc2 = X86::TRUNC_GR16_GR8;
+          Opc2 = X86::TRUNC_16_to8;
           break;
         case MVT::i32:
           Opc = X86::MOV32to32_;
           VT = MVT::i32;
-          Opc2 = X86::TRUNC_GR32_GR8;
+          Opc2 = X86::TRUNC_32_to8;
           break;
         }
 
-        SDOperand Tmp0, Tmp1;
-        Select(Tmp0, Node->getOperand(0));
-        Tmp1 = SDOperand(CurDAG->getTargetNode(Opc, VT, Tmp0), 0);
-        Result = CodeGenMap[N] =
-          SDOperand(CurDAG->getTargetNode(Opc2, NVT, Tmp1), 0);
+        AddToISelQueue(Node->getOperand(0));
+        SDOperand Tmp =
+          SDOperand(CurDAG->getTargetNode(Opc, VT, Node->getOperand(0)), 0);
+        SDNode *ResNode = CurDAG->getTargetNode(Opc2, NVT, Tmp);
       
 #ifndef NDEBUG
-        DEBUG(std::cerr << std::string(Indent-2, ' '));
-        DEBUG(std::cerr << "== ");
-        DEBUG(Result.Val->dump(CurDAG));
-        DEBUG(std::cerr << "\n");
+        DOUT << std::string(Indent-2, ' ') << "=> ";
+        DEBUG(ResNode->dump(CurDAG));
+        DOUT << "\n";
         Indent -= 2;
 #endif
-        return;
+        return ResNode;
       }
 
       break;
     }
   }
 
-  SelectCode(Result, N);
+  SDNode *ResNode = SelectCode(N);
+
 #ifndef NDEBUG
-  DEBUG(std::cerr << std::string(Indent-2, ' '));
-  DEBUG(std::cerr << "=> ");
-  DEBUG(Result.Val->dump(CurDAG));
-  DEBUG(std::cerr << "\n");
+  DOUT << std::string(Indent-2, ' ') << "=> ";
+  if (ResNode == NULL || ResNode == N.Val)
+    DEBUG(N.Val->dump(CurDAG));
+  else
+    DEBUG(ResNode->dump(CurDAG));
+  DOUT << "\n";
   Indent -= 2;
 #endif
+
+  return ResNode;
+}
+
+bool X86DAGToDAGISel::
+SelectInlineAsmMemoryOperand(const SDOperand &Op, char ConstraintCode,
+                             std::vector<SDOperand> &OutOps, SelectionDAG &DAG){
+  SDOperand Op0, Op1, Op2, Op3;
+  switch (ConstraintCode) {
+  case 'o':   // offsetable        ??
+  case 'v':   // not offsetable    ??
+  default: return true;
+  case 'm':   // memory
+    if (!SelectAddr(Op, Op, Op0, Op1, Op2, Op3))
+      return true;
+    break;
+  }
+  
+  OutOps.push_back(Op0);
+  OutOps.push_back(Op1);
+  OutOps.push_back(Op2);
+  OutOps.push_back(Op3);
+  AddToISelQueue(Op0);
+  AddToISelQueue(Op1);
+  AddToISelQueue(Op2);
+  AddToISelQueue(Op3);
+  return false;
 }
 
 /// createX86ISelDag - This pass converts a legalized DAG into a 
 /// X86-specific DAG, ready for instruction scheduling.
 ///
-FunctionPass *llvm::createX86ISelDag(X86TargetMachine &TM) {
-  return new X86DAGToDAGISel(TM);
+FunctionPass *llvm::createX86ISelDag(X86TargetMachine &TM, bool Fast) {
+  return new X86DAGToDAGISel(TM, Fast);
 }