no need to expand ISD::TRAP to X86ISD::TRAP, just match ISD::TRAP.
[oota-llvm.git] / lib / Target / X86 / X86ISelDAGToDAG.cpp
index 62216ca527758a3dcd6fd4ba6934be4fe4acf088..9887bcccef41b52ff0435ed1871ba4d20f195adb 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the Evan Cheng and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
@@ -16,6 +16,7 @@
 #include "X86.h"
 #include "X86InstrBuilder.h"
 #include "X86ISelLowering.h"
+#include "X86MachineFunctionInfo.h"
 #include "X86RegisterInfo.h"
 #include "X86Subtarget.h"
 #include "X86TargetMachine.h"
@@ -28,7 +29,7 @@
 #include "llvm/CodeGen/MachineFunction.h"
 #include "llvm/CodeGen/MachineFrameInfo.h"
 #include "llvm/CodeGen/MachineInstrBuilder.h"
-#include "llvm/CodeGen/SSARegMap.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/CodeGen/SelectionDAGISel.h"
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Support/Compiler.h"
@@ -142,6 +143,8 @@ namespace {
 
     bool MatchAddress(SDOperand N, X86ISelAddressMode &AM,
                       bool isRoot = true, unsigned Depth = 0);
+    bool MatchAddressBase(SDOperand N, X86ISelAddressMode &AM,
+                          bool isRoot, unsigned Depth);
     bool SelectAddr(SDOperand Op, SDOperand N, SDOperand &Base,
                     SDOperand &Scale, SDOperand &Index, SDOperand &Disp);
     bool SelectLEAAddr(SDOperand Op, SDOperand N, SDOperand &Base,
@@ -208,6 +211,10 @@ namespace {
     /// base register.  Return the virtual register that holds this value.
     SDNode *getGlobalBaseReg();
 
+    /// getTruncate - return an SDNode that implements a subreg based truncate
+    /// of the specified operand to the the specified value type.
+    SDNode *getTruncate(SDOperand N0, MVT::ValueType VT);
+
 #ifndef NDEBUG
     unsigned Indent;
 #endif
@@ -479,37 +486,38 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
   // If we are emitting FP stack code, scan the basic block to determine if this
   // block defines any FP values.  If so, put an FP_REG_KILL instruction before
   // the terminator of the block.
-  if (!Subtarget->hasSSE2()) {
-    // Note that FP stack instructions *are* used in SSE code when returning
-    // values, but these are not live out of the basic block, so we don't need
-    // an FP_REG_KILL in this case either.
+
+  // Note that FP stack instructions are used in all modes for long double,
+  // so we always need to do this check.
+  // Also note that it's possible for an FP stack register to be live across
+  // an instruction that produces multiple basic blocks (SSE CMOV) so we
+  // must check all the generated basic blocks.
+
+  // Scan all of the machine instructions in these MBBs, checking for FP
+  // stores.  (RFP32 and RFP64 will not exist in SSE mode, but RFP80 might.)
+  MachineFunction::iterator MBBI = FirstMBB;
+  do {
     bool ContainsFPCode = false;
-    
-    // Scan all of the machine instructions in these MBBs, checking for FP
-    // stores.
-    MachineFunction::iterator MBBI = FirstMBB;
-    do {
-      for (MachineBasicBlock::iterator I = MBBI->begin(), E = MBBI->end();
-           !ContainsFPCode && I != E; ++I) {
-        if (I->getNumOperands() != 0 && I->getOperand(0).isRegister()) {
-          const TargetRegisterClass *clas;
-          for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) {
-            if (I->getOperand(op).isRegister() && I->getOperand(op).isDef() &&
-                MRegisterInfo::isVirtualRegister(I->getOperand(op).getReg()) &&
-                ((clas = RegMap->getRegClass(I->getOperand(0).getReg())) == 
-                   X86::RFP32RegisterClass ||
-                 clas == X86::RFP64RegisterClass ||
-                 clas == X86::RFP80RegisterClass)) {
-              ContainsFPCode = true;
-              break;
-            }
+    for (MachineBasicBlock::iterator I = MBBI->begin(), E = MBBI->end();
+         !ContainsFPCode && I != E; ++I) {
+      if (I->getNumOperands() != 0 && I->getOperand(0).isRegister()) {
+        const TargetRegisterClass *clas;
+        for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op) {
+          if (I->getOperand(op).isRegister() && I->getOperand(op).isDef() &&
+              MRegisterInfo::isVirtualRegister(I->getOperand(op).getReg()) &&
+              ((clas = RegInfo->getRegClass(I->getOperand(0).getReg())) == 
+                 X86::RFP32RegisterClass ||
+               clas == X86::RFP64RegisterClass ||
+               clas == X86::RFP80RegisterClass)) {
+            ContainsFPCode = true;
+            break;
           }
         }
       }
-    } while (!ContainsFPCode && &*(MBBI++) != BB);
-    
+    }
     // Check PHI nodes in successor blocks.  These PHI's will be lowered to have
-    // a copy of the input value in this block.
+    // a copy of the input value in this block.  In SSE mode, we only care about
+    // 80-bit values.
     if (!ContainsFPCode) {
       // Final check, check LLVM BB's that are successors to the LLVM BB
       // corresponding to BB for FP PHI nodes.
@@ -519,21 +527,22 @@ void X86DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
            !ContainsFPCode && SI != E; ++SI) {
         for (BasicBlock::const_iterator II = SI->begin();
              (PN = dyn_cast<PHINode>(II)); ++II) {
-          if (PN->getType()->isFloatingPoint()) {
+          if (PN->getType()==Type::X86_FP80Ty ||
+              (!Subtarget->hasSSE1() && PN->getType()->isFloatingPoint()) ||
+              (!Subtarget->hasSSE2() && PN->getType()==Type::DoubleTy)) {
             ContainsFPCode = true;
             break;
           }
         }
       }
     }
-
     // Finally, if we found any FP code, emit the FP_REG_KILL instruction.
     if (ContainsFPCode) {
-      BuildMI(*BB, BB->getFirstTerminator(),
+      BuildMI(*MBBI, MBBI->getFirstTerminator(),
               TM.getInstrInfo()->get(X86::FP_REG_KILL));
       ++NumFPKill;
     }
-  }
+  } while (&*(MBBI++) != BB);
 }
 
 /// EmitSpecialCodeForMain - Emit any code that needs to be executed only in
@@ -543,17 +552,6 @@ void X86DAGToDAGISel::EmitSpecialCodeForMain(MachineBasicBlock *BB,
   const TargetInstrInfo *TII = TM.getInstrInfo();
   if (Subtarget->isTargetCygMing())
     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, TII->get(X86::FNSTCW16m)), CWFrameIdx);
-
-  // Set the high part to be 64-bit precision.
-  addFrameReference(BuildMI(BB, TII->get(X86::MOV8mi)),
-                    CWFrameIdx, 1).addImm(2);
-
-  // Reload the modified control word now.
-  addFrameReference(BuildMI(BB, TII->get(X86::FLDCW16m)), CWFrameIdx);
 }
 
 void X86DAGToDAGISel::EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {
@@ -565,15 +563,12 @@ void X86DAGToDAGISel::EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {
 
 /// MatchAddress - Add the specified node to the specified addressing mode,
 /// returning true if it cannot be done.  This just pattern matches for the
-/// addressing mode
+/// addressing mode.
 bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
                                    bool isRoot, unsigned Depth) {
-  if (Depth > 5) {
-    // Default, generate it as a register.
-    AM.BaseType = X86ISelAddressMode::RegBase;
-    AM.Base.Reg = N;
-    return false;
-  }
+  // Limit recursion.
+  if (Depth > 5)
+    return MatchAddressBase(N, AM, isRoot, Depth);
   
   // RIP relative addressing: %rip + 32-bit displacement!
   if (AM.isRIPRel) {
@@ -588,7 +583,7 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
   }
 
   int id = N.Val->getNodeId();
-  bool Available = isSelected(id);
+  bool AlreadySelected = isSelected(id); // Already selected, not yet replaced.
 
   switch (N.getOpcode()) {
   default: break;
@@ -611,7 +606,7 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
     // 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.
-    if (!Available || (AM.Base.Reg.Val && AM.IndexReg.Val)) {
+    if (!AlreadySelected || (AM.Base.Reg.Val && AM.IndexReg.Val)) {
       bool isStatic = TM.getRelocationModel() == Reloc::Static;
       SDOperand N0 = N.getOperand(0);
       // Mac OS X X86-64 lower 4G address is not available.
@@ -659,37 +654,44 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
     break;
 
   case ISD::SHL:
-    if (!Available && AM.IndexReg.Val == 0 && AM.Scale == 1)
-      if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.Val->getOperand(1))) {
-        unsigned Val = CN->getValue();
-        if (Val == 1 || Val == 2 || Val == 3) {
-          AM.Scale = 1 << Val;
-          SDOperand ShVal = N.Val->getOperand(0);
-
-          // Okay, we know that we have a scale by now.  However, if the scaled
-          // value is an add of something and a constant, we can fold the
-          // constant into the disp field here.
-          if (ShVal.Val->getOpcode() == ISD::ADD && ShVal.hasOneUse() &&
-              isa<ConstantSDNode>(ShVal.Val->getOperand(1))) {
-            AM.IndexReg = ShVal.Val->getOperand(0);
-            ConstantSDNode *AddVal =
-              cast<ConstantSDNode>(ShVal.Val->getOperand(1));
-            uint64_t Disp = AM.Disp + (AddVal->getValue() << Val);
-            if (isInt32(Disp))
-              AM.Disp = Disp;
-            else
-              AM.IndexReg = ShVal;
-          } else {
+    if (AlreadySelected || AM.IndexReg.Val != 0 || AM.Scale != 1)
+      break;
+      
+    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.Val->getOperand(1))) {
+      unsigned Val = CN->getValue();
+      if (Val == 1 || Val == 2 || Val == 3) {
+        AM.Scale = 1 << Val;
+        SDOperand ShVal = N.Val->getOperand(0);
+
+        // Okay, we know that we have a scale by now.  However, if the scaled
+        // value is an add of something and a constant, we can fold the
+        // constant into the disp field here.
+        if (ShVal.Val->getOpcode() == ISD::ADD && ShVal.hasOneUse() &&
+            isa<ConstantSDNode>(ShVal.Val->getOperand(1))) {
+          AM.IndexReg = ShVal.Val->getOperand(0);
+          ConstantSDNode *AddVal =
+            cast<ConstantSDNode>(ShVal.Val->getOperand(1));
+          uint64_t Disp = AM.Disp + (AddVal->getValue() << Val);
+          if (isInt32(Disp))
+            AM.Disp = Disp;
+          else
             AM.IndexReg = ShVal;
-          }
-          return false;
+        } else {
+          AM.IndexReg = ShVal;
         }
+        return false;
       }
     break;
+    }
 
+  case ISD::SMUL_LOHI:
+  case ISD::UMUL_LOHI:
+    // A mul_lohi where we need the low part can be folded as a plain multiply.
+    if (N.ResNo != 0) break;
+    // FALL THROUGH
   case ISD::MUL:
     // X*[3,5,9] -> X+X*[2,4,8]
-    if (!Available &&
+    if (!AlreadySelected &&
         AM.BaseType == X86ISelAddressMode::RegBase &&
         AM.Base.Reg.Val == 0 &&
         AM.IndexReg.Val == 0) {
@@ -724,7 +726,7 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
     break;
 
   case ISD::ADD:
-    if (!Available) {
+    if (!AlreadySelected) {
       X86ISelAddressMode Backup = AM;
       if (!MatchAddress(N.Val->getOperand(0), AM, false, Depth+1) &&
           !MatchAddress(N.Val->getOperand(1), AM, false, Depth+1))
@@ -739,26 +741,71 @@ bool X86DAGToDAGISel::MatchAddress(SDOperand N, X86ISelAddressMode &AM,
 
   case ISD::OR:
     // Handle "X | C" as "X + C" iff X is known to have C bits clear.
-    if (!Available) {
-      if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
-        X86ISelAddressMode Backup = AM;
-        // Start with the LHS as an addr mode.
-        if (!MatchAddress(N.getOperand(0), AM, false) &&
-            // Address could not have picked a GV address for the displacement.
-            AM.GV == NULL &&
-            // On x86-64, the resultant disp must fit in 32-bits.
-            isInt32(AM.Disp + CN->getSignExtended()) &&
-            // Check to see if the LHS & C is zero.
-            CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getValue())) {
-          AM.Disp += CN->getValue();
-          return false;
-        }
-        AM = Backup;
+    if (AlreadySelected) break;
+      
+    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) {
+      X86ISelAddressMode Backup = AM;
+      // Start with the LHS as an addr mode.
+      if (!MatchAddress(N.getOperand(0), AM, false) &&
+          // Address could not have picked a GV address for the displacement.
+          AM.GV == NULL &&
+          // On x86-64, the resultant disp must fit in 32-bits.
+          isInt32(AM.Disp + CN->getSignExtended()) &&
+          // Check to see if the LHS & C is zero.
+          CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getValue())) {
+        AM.Disp += CN->getValue();
+        return false;
       }
+      AM = Backup;
     }
     break;
+      
+  case ISD::AND: {
+    // Handle "(x << C1) & C2" as "(X & (C2>>C1)) << C1" if safe and if this
+    // allows us to fold the shift into this addressing mode.
+    if (AlreadySelected) break;
+    SDOperand Shift = N.getOperand(0);
+    if (Shift.getOpcode() != ISD::SHL) break;
+    
+    // Scale must not be used already.
+    if (AM.IndexReg.Val != 0 || AM.Scale != 1) break;
+      
+    ConstantSDNode *C2 = dyn_cast<ConstantSDNode>(N.getOperand(1));
+    ConstantSDNode *C1 = dyn_cast<ConstantSDNode>(Shift.getOperand(1));
+    if (!C1 || !C2) break;
+
+    // Not likely to be profitable if either the AND or SHIFT node has more
+    // than one use (unless all uses are for address computation). Besides,
+    // isel mechanism requires their node ids to be reused.
+    if (!N.hasOneUse() || !Shift.hasOneUse())
+      break;
+    
+    // Verify that the shift amount is something we can fold.
+    unsigned ShiftCst = C1->getValue();
+    if (ShiftCst != 1 && ShiftCst != 2 && ShiftCst != 3)
+      break;
+    
+    // Get the new AND mask, this folds to a constant.
+    SDOperand NewANDMask = CurDAG->getNode(ISD::SRL, N.getValueType(),
+                                           SDOperand(C2, 0), SDOperand(C1, 0));
+    SDOperand NewAND = CurDAG->getNode(ISD::AND, N.getValueType(),
+                                       Shift.getOperand(0), NewANDMask);
+    NewANDMask.Val->setNodeId(Shift.Val->getNodeId());
+    NewAND.Val->setNodeId(N.Val->getNodeId());
+    
+    AM.Scale = 1 << ShiftCst;
+    AM.IndexReg = NewAND;
+    return false;
+  }
   }
 
+  return MatchAddressBase(N, AM, isRoot, Depth);
+}
+
+/// MatchAddressBase - Helper for MatchAddress. Add the specified node to the
+/// specified addressing mode without any further recursion.
+bool X86DAGToDAGISel::MatchAddressBase(SDOperand N, X86ISelAddressMode &AM,
+                                       bool isRoot, unsigned Depth) {
   // Is the base register already occupied?
   if (AM.BaseType != X86ISelAddressMode::RegBase || AM.Base.Reg.Val) {
     // If so, check to see if the scale index register is set.
@@ -807,7 +854,7 @@ static inline bool isZeroNode(SDOperand Elt) {
   return ((isa<ConstantSDNode>(Elt) &&
   cast<ConstantSDNode>(Elt)->getValue() == 0) ||
   (isa<ConstantFPSDNode>(Elt) &&
-  cast<ConstantFPSDNode>(Elt)->isExactlyValue(0.0)));
+  cast<ConstantFPSDNode>(Elt)->getValueAPF().isPosZero()));
 }
 
 
@@ -836,20 +883,15 @@ bool X86DAGToDAGISel::SelectScalarSSELoad(SDOperand Op, SDOperand Pred,
   // 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 &&
+      // Check to see if the top elements are all zeros (or bitcast of zeros).
+      ISD::isBuildVectorAllZeros(N.getOperand(0).Val) &&
       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();
+    unsigned VecWidth=MVT::getVectorNumElements(N.getOperand(0).getValueType());
     SDOperand ShufMask = N.getOperand(2);
     assert(ShufMask.getOpcode() == ISD::BUILD_VECTOR && "Invalid shuf mask!");
     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(ShufMask.getOperand(0))) {
@@ -947,23 +989,24 @@ 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();
+    MachineFunction *MF = BB->getParent();
+    MachineBasicBlock &FirstMBB = MF->front();
     MachineBasicBlock::iterator MBBI = FirstMBB.begin();
-    SSARegMap *RegMap = BB->getParent()->getSSARegMap();
-    unsigned PC = RegMap->createVirtualRegister(X86::GR32RegisterClass);
+    MachineRegisterInfo &RegInfo = MF->getRegInfo();
+    unsigned PC = RegInfo.createVirtualRegister(X86::GR32RegisterClass);
     
     const TargetInstrInfo *TII = TM.getInstrInfo();
-    BuildMI(FirstMBB, MBBI, TII->get(X86::MovePCtoStack));
-    BuildMI(FirstMBB, MBBI, TII->get(X86::POP32r), PC);
+    // Operand of MovePCtoStack is completely ignored by asm printer. It's
+    // only used in JIT code emission as displacement to pc.
+    BuildMI(FirstMBB, MBBI, TII->get(X86::MOVPC32r), PC).addImm(0);
     
     // If we're using vanilla 'GOT' PIC style, we should use relative addressing
     // not to pc, but to _GLOBAL_ADDRESS_TABLE_ external
     if (TM.getRelocationModel() == Reloc::PIC_ &&
         Subtarget->isPICStyleGOT()) {
-      GlobalBaseReg = RegMap->createVirtualRegister(X86::GR32RegisterClass);
-      BuildMI(FirstMBB, MBBI, TII->get(X86::ADD32ri), GlobalBaseReg).
-        addReg(PC).
-        addExternalSymbol("_GLOBAL_OFFSET_TABLE_");
+      GlobalBaseReg = RegInfo.createVirtualRegister(X86::GR32RegisterClass);
+      BuildMI(FirstMBB, MBBI, TII->get(X86::ADD32ri), GlobalBaseReg)
+        .addReg(PC).addExternalSymbol("_GLOBAL_OFFSET_TABLE_");
     } else {
       GlobalBaseReg = PC;
     }
@@ -979,6 +1022,43 @@ static SDNode *FindCallStartFromCall(SDNode *Node) {
   return FindCallStartFromCall(Node->getOperand(0).Val);
 }
 
+SDNode *X86DAGToDAGISel::getTruncate(SDOperand N0, MVT::ValueType VT) {
+    SDOperand SRIdx;
+    switch (VT) {
+    case MVT::i8:
+      SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
+      // Ensure that the source register has an 8-bit subreg on 32-bit targets
+      if (!Subtarget->is64Bit()) { 
+        unsigned Opc;
+        MVT::ValueType VT;
+        switch (N0.getValueType()) {
+        default: assert(0 && "Unknown truncate!");
+        case MVT::i16:
+          Opc = X86::MOV16to16_;
+          VT = MVT::i16;
+          break;
+        case MVT::i32:
+          Opc = X86::MOV32to32_;
+          VT = MVT::i32;
+          break;
+        }
+        N0 = SDOperand(CurDAG->getTargetNode(Opc, VT, MVT::Flag, N0), 0);
+        return CurDAG->getTargetNode(X86::EXTRACT_SUBREG,
+                                     VT, N0, SRIdx, N0.getValue(1));
+      }
+      break;
+    case MVT::i16:
+      SRIdx = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2
+      break;
+    case MVT::i32:
+      SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
+      break;
+    default: assert(0 && "Unknown truncate!"); break;
+    }
+    return CurDAG->getTargetNode(X86::EXTRACT_SUBREG, VT, N0, SRIdx);
+}
+
+
 SDNode *X86DAGToDAGISel::Select(SDOperand N) {
   SDNode *Node = N.Val;
   MVT::ValueType NVT = Node->getValueType(0);
@@ -1011,7 +1091,10 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
       // 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.
+      // In 64-bit small code size mode, use LEA to take advantage of
+      // RIP-relative addressing.
+      if (TM.getCodeModel() != CodeModel::Small)
+        break;
       MVT::ValueType PtrVT = TLI.getPointerTy();
       SDOperand N0 = N.getOperand(0);
       SDOperand N1 = N.getOperand(1);
@@ -1046,53 +1129,22 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
       break;
     }
 
-    case ISD::MUL: {
-      if (NVT == MVT::i8) {
-        SDOperand N0 = Node->getOperand(0);
-        SDOperand N1 = Node->getOperand(1);
-        SDOperand Tmp0, Tmp1, Tmp2, Tmp3;
-        bool foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3);
-        if (!foldedLoad) {
-          foldedLoad = TryFoldLoad(N, N0, Tmp0, Tmp1, Tmp2, Tmp3);
-          if (foldedLoad)
-            std::swap(N0, N1);
-        }
-
-        SDNode *ResNode;
-        if (foldedLoad) {
-          SDOperand Chain = N1.getOperand(0);
-          AddToISelQueue(N0);
-          AddToISelQueue(Chain);
-          AddToISelQueue(Tmp0);
-          AddToISelQueue(Tmp1);
-          AddToISelQueue(Tmp2);
-          AddToISelQueue(Tmp3);
-          SDOperand InFlag(0, 0);
-          Chain = CurDAG->getCopyToReg(Chain, X86::AL, N0, InFlag);
-          InFlag = Chain.getValue(1);
-          SDOperand Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Chain, InFlag };
-          ResNode = CurDAG->getTargetNode(X86::MUL8m, MVT::i8, MVT::i8,
-                                          MVT::Other, Ops, 6);
-          ReplaceUses(N1.getValue(1), SDOperand(ResNode, 2));
-        } else {
-          SDOperand Chain = CurDAG->getEntryNode();
-          AddToISelQueue(N0);
-          AddToISelQueue(N1);
-          SDOperand InFlag(0, 0);
-          InFlag = CurDAG->getCopyToReg(Chain, X86::AL, N0, InFlag).getValue(1);
-          ResNode = CurDAG->getTargetNode(X86::MUL8r, MVT::i8, MVT::i8,
-                                          N1, InFlag);
-        }
+    case ISD::SMUL_LOHI:
+    case ISD::UMUL_LOHI: {
+      SDOperand N0 = Node->getOperand(0);
+      SDOperand N1 = Node->getOperand(1);
 
-        ReplaceUses(N.getValue(0), SDOperand(ResNode, 0));
-        return NULL;
+      // There are several forms of IMUL that just return the low part and
+      // don't have fixed-register operands. If we don't need the high part,
+      // use these instead. They can be selected with the generated ISel code.
+      if (NVT != MVT::i8 &&
+          N.getValue(1).use_empty()) {
+        N = CurDAG->getNode(ISD::MUL, NVT, N0, N1);
+        break;
       }
-      break;
-    }
 
-    case ISD::MULHU:
-    case ISD::MULHS: {
-      if (Opcode == ISD::MULHU)
+      bool isSigned = Opcode == ISD::SMUL_LOHI;
+      if (!isSigned)
         switch (NVT) {
         default: assert(0 && "Unsupported VT!");
         case MVT::i8:  Opc = X86::MUL8r;  MOpc = X86::MUL8m;  break;
@@ -1118,67 +1170,90 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
       case MVT::i64: LoReg = X86::RAX; HiReg = X86::RDX; break;
       }
 
-      SDOperand N0 = Node->getOperand(0);
-      SDOperand N1 = Node->getOperand(1);
-
       SDOperand Tmp0, Tmp1, Tmp2, Tmp3;
       bool foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3);
-      // MULHU and MULHS are commmutative
+      // multiplty is commmutative
       if (!foldedLoad) {
         foldedLoad = TryFoldLoad(N, N0, Tmp0, Tmp1, Tmp2, Tmp3);
         if (foldedLoad)
           std::swap(N0, N1);
       }
 
-      SDOperand Chain;
-      if (foldedLoad) {
-        Chain = N1.getOperand(0);
-        AddToISelQueue(Chain);
-      } else
-        Chain = CurDAG->getEntryNode();
-
-      SDOperand InFlag(0, 0);
       AddToISelQueue(N0);
-      Chain  = CurDAG->getCopyToReg(Chain, CurDAG->getRegister(LoReg, NVT),
-                                    N0, InFlag);
-      InFlag = Chain.getValue(1);
+      SDOperand InFlag = CurDAG->getCopyToReg(CurDAG->getEntryNode(), LoReg,
+                                              N0, SDOperand()).getValue(1);
 
       if (foldedLoad) {
+        AddToISelQueue(N1.getOperand(0));
         AddToISelQueue(Tmp0);
         AddToISelQueue(Tmp1);
         AddToISelQueue(Tmp2);
         AddToISelQueue(Tmp3);
-        SDOperand Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, Chain, InFlag };
+        SDOperand Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, N1.getOperand(0), InFlag };
         SDNode *CNode =
           CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Ops, 6);
-        Chain  = SDOperand(CNode, 0);
         InFlag = SDOperand(CNode, 1);
+        // Update the chain.
+        ReplaceUses(N1.getValue(1), SDOperand(CNode, 0));
       } else {
         AddToISelQueue(N1);
         InFlag =
           SDOperand(CurDAG->getTargetNode(Opc, MVT::Flag, N1, InFlag), 0);
       }
 
-      SDOperand Result = CurDAG->getCopyFromReg(Chain, HiReg, NVT, InFlag);
-      ReplaceUses(N.getValue(0), Result);
-      if (foldedLoad)
-        ReplaceUses(N1.getValue(1), Result.getValue(1));
+      // Copy the low half of the result, if it is needed.
+      if (!N.getValue(0).use_empty()) {
+        SDOperand Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
+                                                  LoReg, NVT, InFlag);
+        InFlag = Result.getValue(2);
+        ReplaceUses(N.getValue(0), Result);
+#ifndef NDEBUG
+        DOUT << std::string(Indent-2, ' ') << "=> ";
+        DEBUG(Result.Val->dump(CurDAG));
+        DOUT << "\n";
+#endif
+      }
+      // Copy the high half of the result, if it is needed.
+      if (!N.getValue(1).use_empty()) {
+        SDOperand Result;
+        if (HiReg == X86::AH && Subtarget->is64Bit()) {
+          // Prevent use of AH in a REX instruction by referencing AX instead.
+          // Shift it down 8 bits.
+          Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
+                                          X86::AX, MVT::i16, InFlag);
+          InFlag = Result.getValue(2);
+          Result = SDOperand(CurDAG->getTargetNode(X86::SHR16ri, MVT::i16, Result,
+                                       CurDAG->getTargetConstant(8, MVT::i8)), 0);
+          // Then truncate it down to i8.
+          SDOperand SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
+          Result = SDOperand(CurDAG->getTargetNode(X86::EXTRACT_SUBREG,
+                                                   MVT::i8, Result, SRIdx), 0);
+        } else {
+          Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
+                                          HiReg, NVT, InFlag);
+          InFlag = Result.getValue(2);
+        }
+        ReplaceUses(N.getValue(1), Result);
+#ifndef NDEBUG
+        DOUT << std::string(Indent-2, ' ') << "=> ";
+        DEBUG(Result.Val->dump(CurDAG));
+        DOUT << "\n";
+#endif
+      }
 
 #ifndef NDEBUG
-      DOUT << std::string(Indent-2, ' ') << "=> ";
-      DEBUG(Result.Val->dump(CurDAG));
-      DOUT << "\n";
       Indent -= 2;
 #endif
+
       return NULL;
     }
       
-    case ISD::SDIV:
-    case ISD::UDIV:
-    case ISD::SREM:
-    case ISD::UREM: {
-      bool isSigned = Opcode == ISD::SDIV || Opcode == ISD::SREM;
-      bool isDiv    = Opcode == ISD::SDIV || Opcode == ISD::UDIV;
+    case ISD::SDIVREM:
+    case ISD::UDIVREM: {
+      SDOperand N0 = Node->getOperand(0);
+      SDOperand N1 = Node->getOperand(1);
+
+      bool isSigned = Opcode == ISD::SDIVREM;
       if (!isSigned)
         switch (NVT) {
         default: assert(0 && "Unsupported VT!");
@@ -1222,9 +1297,10 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
         break;
       }
 
-      SDOperand N0 = Node->getOperand(0);
-      SDOperand N1 = Node->getOperand(1);
-      SDOperand InFlag(0, 0);
+      SDOperand Tmp0, Tmp1, Tmp2, Tmp3;
+      bool foldedLoad = TryFoldLoad(N, N1, Tmp0, Tmp1, Tmp2, Tmp3);
+
+      SDOperand 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).
@@ -1247,13 +1323,13 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
             SDOperand(CurDAG->getTargetNode(X86::MOVZX16rr8, MVT::i16, N0), 0);
           Chain = CurDAG->getEntryNode();
         }
-        Chain  = CurDAG->getCopyToReg(Chain, X86::AX, Move, InFlag);
+        Chain  = CurDAG->getCopyToReg(Chain, X86::AX, Move, SDOperand());
         InFlag = Chain.getValue(1);
       } else {
         AddToISelQueue(N0);
         InFlag =
-          CurDAG->getCopyToReg(CurDAG->getEntryNode(), LoReg, N0,
-                               InFlag).getValue(1);
+          CurDAG->getCopyToReg(CurDAG->getEntryNode(),
+                               LoReg, N0, SDOperand()).getValue(1);
         if (isSigned) {
           // Sign extend the low part into the high part.
           InFlag =
@@ -1261,13 +1337,11 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
         } 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);
+          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) {
         AddToISelQueue(N1.getOperand(0));
         AddToISelQueue(Tmp0);
@@ -1277,68 +1351,146 @@ SDNode *X86DAGToDAGISel::Select(SDOperand N) {
         SDOperand Ops[] = { Tmp0, Tmp1, Tmp2, Tmp3, N1.getOperand(0), InFlag };
         SDNode *CNode =
           CurDAG->getTargetNode(MOpc, MVT::Other, MVT::Flag, Ops, 6);
-        Chain  = SDOperand(CNode, 0);
         InFlag = SDOperand(CNode, 1);
+        // Update the chain.
+        ReplaceUses(N1.getValue(1), SDOperand(CNode, 0));
       } else {
         AddToISelQueue(N1);
-        Chain = CurDAG->getEntryNode();
         InFlag =
           SDOperand(CurDAG->getTargetNode(Opc, MVT::Flag, N1, InFlag), 0);
       }
 
-      SDOperand Result =
-        CurDAG->getCopyFromReg(Chain, isDiv ? LoReg : HiReg, NVT, InFlag);
-      ReplaceUses(N.getValue(0), Result);
-      if (foldedLoad)
-        ReplaceUses(N1.getValue(1), Result.getValue(1));
+      // Copy the division (low) result, if it is needed.
+      if (!N.getValue(0).use_empty()) {
+        SDOperand Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
+                                                  LoReg, NVT, InFlag);
+        InFlag = Result.getValue(2);
+        ReplaceUses(N.getValue(0), Result);
+#ifndef NDEBUG
+        DOUT << std::string(Indent-2, ' ') << "=> ";
+        DEBUG(Result.Val->dump(CurDAG));
+        DOUT << "\n";
+#endif
+      }
+      // Copy the remainder (high) result, if it is needed.
+      if (!N.getValue(1).use_empty()) {
+        SDOperand Result;
+        if (HiReg == X86::AH && Subtarget->is64Bit()) {
+          // Prevent use of AH in a REX instruction by referencing AX instead.
+          // Shift it down 8 bits.
+          Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
+                                          X86::AX, MVT::i16, InFlag);
+          InFlag = Result.getValue(2);
+          Result = SDOperand(CurDAG->getTargetNode(X86::SHR16ri, MVT::i16, Result,
+                                       CurDAG->getTargetConstant(8, MVT::i8)), 0);
+          // Then truncate it down to i8.
+          SDOperand SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
+          Result = SDOperand(CurDAG->getTargetNode(X86::EXTRACT_SUBREG,
+                                                   MVT::i8, Result, SRIdx), 0);
+        } else {
+          Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
+                                          HiReg, NVT, InFlag);
+          InFlag = Result.getValue(2);
+        }
+        ReplaceUses(N.getValue(1), Result);
+#ifndef NDEBUG
+        DOUT << std::string(Indent-2, ' ') << "=> ";
+        DEBUG(Result.Val->dump(CurDAG));
+        DOUT << "\n";
+#endif
+      }
 
 #ifndef NDEBUG
-      DOUT << std::string(Indent-2, ' ') << "=> ";
-      DEBUG(Result.Val->dump(CurDAG));
-      DOUT << "\n";
       Indent -= 2;
 #endif
 
       return NULL;
     }
+
+    case ISD::ANY_EXTEND: {
+      SDOperand N0 = Node->getOperand(0);
+      AddToISelQueue(N0);
+      if (NVT == MVT::i64 || NVT == MVT::i32 || NVT == MVT::i16) {
+        SDOperand SRIdx;
+        switch(N0.getValueType()) {
+        case MVT::i32:
+          SRIdx = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
+          break;
+        case MVT::i16:
+          SRIdx = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2
+          break;
+        case MVT::i8:
+          if (Subtarget->is64Bit())
+            SRIdx = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
+          break;
+        default: assert(0 && "Unknown any_extend!");
+        }
+        if (SRIdx.Val) {
+          SDNode *ResNode = CurDAG->getTargetNode(X86::INSERT_SUBREG,
+                                                  NVT, N0, SRIdx);
+
+#ifndef NDEBUG
+          DOUT << std::string(Indent-2, ' ') << "=> ";
+          DEBUG(ResNode->dump(CurDAG));
+          DOUT << "\n";
+          Indent -= 2;
+#endif
+          return ResNode;
+        } // Otherwise let generated ISel handle it.
+      }
+      break;
+    }
+    
+    case ISD::SIGN_EXTEND_INREG: {
+      SDOperand N0 = Node->getOperand(0);
+      AddToISelQueue(N0);
       
-    case ISD::TRUNCATE: {
-      SDOperand Tmp;
-      SDOperand Input = Node->getOperand(0);
-      AddToISelQueue(Node->getOperand(0));
+      MVT::ValueType SVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
+      SDOperand TruncOp = SDOperand(getTruncate(N0, SVT), 0);
+      unsigned Opc = 0;
       switch (NVT) {
-      case MVT::i8:
-        Tmp = CurDAG->getTargetConstant(1, MVT::i32); // SubRegSet 1
-        // Ensure that the source register has an 8-bit subreg on 32-bit targets
-        if (!Subtarget->is64Bit()) { 
-          unsigned Opc;
-          MVT::ValueType VT;
-          switch (Node->getOperand(0).getValueType()) {
-          default: assert(0 && "Unknown truncate!");
-          case MVT::i16:
-            Opc = X86::MOV16to16_;
-            VT = MVT::i16;
-            break;
-          case MVT::i32:
-            Opc = X86::MOV32to32_;
-            VT = MVT::i32;
-            break;
-          }
-          Input = 
-            SDOperand(CurDAG->getTargetNode(Opc, VT, Node->getOperand(0)), 0);
-        }
-        break;
       case MVT::i16:
-        Tmp = CurDAG->getTargetConstant(2, MVT::i32); // SubRegSet 2
+        if (SVT == MVT::i8) Opc = X86::MOVSX16rr8;
+        else assert(0 && "Unknown sign_extend_inreg!");
         break;
       case MVT::i32:
-        Tmp = CurDAG->getTargetConstant(3, MVT::i32); // SubRegSet 3
+        switch (SVT) {
+        case MVT::i8:  Opc = X86::MOVSX32rr8;  break;
+        case MVT::i16: Opc = X86::MOVSX32rr16; break;
+        default: assert(0 && "Unknown sign_extend_inreg!");
+        }
         break;
-      default: assert(0 && "Unknown truncate!");
+      case MVT::i64:
+        switch (SVT) {
+        case MVT::i8:  Opc = X86::MOVSX64rr8;  break;
+        case MVT::i16: Opc = X86::MOVSX64rr16; break;
+        case MVT::i32: Opc = X86::MOVSX64rr32; break;
+        default: assert(0 && "Unknown sign_extend_inreg!");
+        }
+        break;
+      default: assert(0 && "Unknown sign_extend_inreg!");
       }
-      SDNode *ResNode = CurDAG->getTargetNode(X86::EXTRACT_SUBREG, 
-                                              NVT, 
-                                              Input, Tmp);
+      
+      SDNode *ResNode = CurDAG->getTargetNode(Opc, NVT, TruncOp);
+      
+#ifndef NDEBUG
+      DOUT << std::string(Indent-2, ' ') << "=> ";
+      DEBUG(TruncOp.Val->dump(CurDAG));
+      DOUT << "\n";
+      DOUT << std::string(Indent-2, ' ') << "=> ";
+      DEBUG(ResNode->dump(CurDAG));
+      DOUT << "\n";
+      Indent -= 2;
+#endif
+      return ResNode;
+      break;
+    }
+    
+    case ISD::TRUNCATE: {
+      SDOperand Input = Node->getOperand(0);
+      AddToISelQueue(Node->getOperand(0));
+      SDNode *ResNode = getTruncate(Input, NVT);
+      
 #ifndef NDEBUG
         DOUT << std::string(Indent-2, ' ') << "=> ";
         DEBUG(ResNode->dump(CurDAG));