Two changes:
[oota-llvm.git] / lib / Target / X86 / InstSelectSimple.cpp
index 862a385300e914017e86a7c6d0479d00e9409306..8dbf61ed7c530ee85ac47723b201d69e50edf0f7 100644 (file)
@@ -35,6 +35,43 @@ using namespace llvm;
 namespace {
   Statistic<>
   NumFPKill("x86-codegen", "Number of FP_REG_KILL instructions added");
+
+  /// TypeClass - Used by the X86 backend to group LLVM types by their basic X86
+  /// Representation.
+  ///
+  enum TypeClass {
+    cByte, cShort, cInt, cFP, cLong
+  };
+}
+
+/// getClass - Turn a primitive type into a "class" number which is based on the
+/// size of the type, and whether or not it is floating point.
+///
+static inline TypeClass getClass(const Type *Ty) {
+  switch (Ty->getPrimitiveID()) {
+  case Type::SByteTyID:
+  case Type::UByteTyID:   return cByte;      // Byte operands are class #0
+  case Type::ShortTyID:
+  case Type::UShortTyID:  return cShort;     // Short operands are class #1
+  case Type::IntTyID:
+  case Type::UIntTyID:
+  case Type::PointerTyID: return cInt;       // Int's and pointers are class #2
+
+  case Type::FloatTyID:
+  case Type::DoubleTyID:  return cFP;        // Floating Point is #3
+
+  case Type::LongTyID:
+  case Type::ULongTyID:   return cLong;      // Longs are class #4
+  default:
+    assert(0 && "Invalid type to getClass!");
+    return cByte;  // not reached
+  }
+}
+
+// getClassB - Just like getClass, but treat boolean values as bytes.
+static inline TypeClass getClassB(const Type *Ty) {
+  if (Ty == Type::BoolTy) return cByte;
+  return getClass(Ty);
 }
 
 namespace {
@@ -315,22 +352,28 @@ namespace {
     }
     unsigned getReg(Value *V, MachineBasicBlock *MBB,
                     MachineBasicBlock::iterator IPt) {
-      unsigned &Reg = RegMap[V];
-      if (Reg == 0) {
-        Reg = makeAnotherReg(V->getType());
-        RegMap[V] = Reg;
-      }
-
       // If this operand is a constant, emit the code to copy the constant into
       // the register here...
       //
       if (Constant *C = dyn_cast<Constant>(V)) {
+        unsigned Reg = makeAnotherReg(V->getType());
         copyConstantToRegister(MBB, IPt, C, Reg);
-        RegMap.erase(V);  // Assign a new name to this constant if ref'd again
+        return Reg;
       } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
+        unsigned Reg = makeAnotherReg(V->getType());
         // Move the address of the global into the register
         BuildMI(*MBB, IPt, X86::MOV32ri, 1, Reg).addGlobalAddress(GV);
-        RegMap.erase(V);  // Assign a new name to this address if ref'd again
+        return Reg;
+      } else if (CastInst *CI = dyn_cast<CastInst>(V)) {
+        // Do not emit noop casts at all.
+        if (getClassB(CI->getType()) == getClassB(CI->getOperand(0)->getType()))
+          return getReg(CI->getOperand(0), MBB, IPt);
+      }
+
+      unsigned &Reg = RegMap[V];
+      if (Reg == 0) {
+        Reg = makeAnotherReg(V->getType());
+        RegMap[V] = Reg;
       }
 
       return Reg;
@@ -338,44 +381,6 @@ namespace {
   };
 }
 
-/// TypeClass - Used by the X86 backend to group LLVM types by their basic X86
-/// Representation.
-///
-enum TypeClass {
-  cByte, cShort, cInt, cFP, cLong
-};
-
-/// getClass - Turn a primitive type into a "class" number which is based on the
-/// size of the type, and whether or not it is floating point.
-///
-static inline TypeClass getClass(const Type *Ty) {
-  switch (Ty->getPrimitiveID()) {
-  case Type::SByteTyID:
-  case Type::UByteTyID:   return cByte;      // Byte operands are class #0
-  case Type::ShortTyID:
-  case Type::UShortTyID:  return cShort;     // Short operands are class #1
-  case Type::IntTyID:
-  case Type::UIntTyID:
-  case Type::PointerTyID: return cInt;       // Int's and pointers are class #2
-
-  case Type::FloatTyID:
-  case Type::DoubleTyID:  return cFP;        // Floating Point is #3
-
-  case Type::LongTyID:
-  case Type::ULongTyID:   return cLong;      // Longs are class #4
-  default:
-    assert(0 && "Invalid type to getClass!");
-    return cByte;  // not reached
-  }
-}
-
-// getClassB - Just like getClass, but treat boolean values as bytes.
-static inline TypeClass getClassB(const Type *Ty) {
-  if (Ty == Type::BoolTy) return cByte;
-  return getClass(Ty);
-}
-
-
 /// copyConstantToRegister - Output the instructions required to put the
 /// specified constant into the specified register.
 ///
@@ -511,39 +516,51 @@ void ISel::LoadArgumentsToVirtualRegs(Function &Fn) {
   MachineFrameInfo *MFI = F->getFrameInfo();
 
   for (Function::aiterator I = Fn.abegin(), E = Fn.aend(); I != E; ++I) {
-    unsigned Reg = getReg(*I);
-    
+    bool ArgLive = !I->use_empty();
+    unsigned Reg = ArgLive ? getReg(*I) : 0;
     int FI;          // Frame object index
+
     switch (getClassB(I->getType())) {
     case cByte:
-      FI = MFI->CreateFixedObject(1, ArgOffset);
-      addFrameReference(BuildMI(BB, X86::MOV8rm, 4, Reg), FI);
+      if (ArgLive) {
+        FI = MFI->CreateFixedObject(1, ArgOffset);
+        addFrameReference(BuildMI(BB, X86::MOV8rm, 4, Reg), FI);
+      }
       break;
     case cShort:
-      FI = MFI->CreateFixedObject(2, ArgOffset);
-      addFrameReference(BuildMI(BB, X86::MOV16rm, 4, Reg), FI);
+      if (ArgLive) {
+        FI = MFI->CreateFixedObject(2, ArgOffset);
+        addFrameReference(BuildMI(BB, X86::MOV16rm, 4, Reg), FI);
+      }
       break;
     case cInt:
-      FI = MFI->CreateFixedObject(4, ArgOffset);
-      addFrameReference(BuildMI(BB, X86::MOV32rm, 4, Reg), FI);
+      if (ArgLive) {
+        FI = MFI->CreateFixedObject(4, ArgOffset);
+        addFrameReference(BuildMI(BB, X86::MOV32rm, 4, Reg), FI);
+      }
       break;
     case cLong:
-      FI = MFI->CreateFixedObject(8, ArgOffset);
-      addFrameReference(BuildMI(BB, X86::MOV32rm, 4, Reg), FI);
-      addFrameReference(BuildMI(BB, X86::MOV32rm, 4, Reg+1), FI, 4);
+      if (ArgLive) {
+        FI = MFI->CreateFixedObject(8, ArgOffset);
+        addFrameReference(BuildMI(BB, X86::MOV32rm, 4, Reg), FI);
+        addFrameReference(BuildMI(BB, X86::MOV32rm, 4, Reg+1), FI, 4);
+      }
       ArgOffset += 4;   // longs require 4 additional bytes
       break;
     case cFP:
-      unsigned Opcode;
-      if (I->getType() == Type::FloatTy) {
-        Opcode = X86::FLD32m;
-        FI = MFI->CreateFixedObject(4, ArgOffset);
-      } else {
-        Opcode = X86::FLD64m;
-        FI = MFI->CreateFixedObject(8, ArgOffset);
-        ArgOffset += 4;   // doubles require 4 additional bytes
+      if (ArgLive) {
+        unsigned Opcode;
+        if (I->getType() == Type::FloatTy) {
+          Opcode = X86::FLD32m;
+          FI = MFI->CreateFixedObject(4, ArgOffset);
+        } else {
+          Opcode = X86::FLD64m;
+          FI = MFI->CreateFixedObject(8, ArgOffset);
+        }
+        addFrameReference(BuildMI(BB, Opcode, 4, Reg), FI);
       }
-      addFrameReference(BuildMI(BB, Opcode, 4, Reg), FI);
+      if (I->getType() == Type::DoubleTy)
+        ArgOffset += 4;   // doubles require 4 additional bytes
       break;
     default:
       assert(0 && "Unhandled argument type!");
@@ -756,7 +773,9 @@ static SetCondInst *canFoldSetCCIntoBranchOrSelect(Value *V) {
       Instruction *User = cast<Instruction>(SCI->use_back());
       if ((isa<BranchInst>(User) || isa<SelectInst>(User)) &&
           SCI->getParent() == User->getParent() &&
-          getClassB(SCI->getOperand(0)->getType()) != cLong)
+          (getClassB(SCI->getOperand(0)->getType()) != cLong ||
+           SCI->getOpcode() == Instruction::SetEQ ||
+           SCI->getOpcode() == Instruction::SetNE))
         return SCI;
     }
   return 0;
@@ -806,9 +825,9 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
   unsigned Op0r = getReg(Op0, MBB, IP);
 
   // Special case handling of: cmp R, i
-  if (Class == cByte || Class == cShort || Class == cInt)
-    if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
-      uint64_t Op1v = cast<ConstantInt>(CI)->getRawValue();
+  if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
+    if (Class == cByte || Class == cShort || Class == cInt) {
+      unsigned Op1v = CI->getRawValue();
 
       // Mask off any upper bits of the constant, if there are any...
       Op1v &= (1ULL << (8 << Class)) - 1;
@@ -833,7 +852,52 @@ unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
 
       BuildMI(*MBB, IP, CMPTab[Class], 2).addReg(Op0r).addImm(Op1v);
       return OpNum;
+    } else {
+      assert(Class == cLong && "Unknown integer class!");
+      unsigned LowCst = CI->getRawValue();
+      unsigned HiCst = CI->getRawValue() >> 32;
+      if (OpNum < 2) {    // seteq, setne
+        unsigned LoTmp = Op0r;
+        if (LowCst != 0) {
+          LoTmp = makeAnotherReg(Type::IntTy);
+          BuildMI(*MBB, IP, X86::XOR32ri, 2, LoTmp).addReg(Op0r).addImm(LowCst);
+        }
+        unsigned HiTmp = Op0r+1;
+        if (HiCst != 0) {
+          HiTmp = makeAnotherReg(Type::IntTy);
+          BuildMI(*MBB, IP, X86::XOR32ri, 2,HiTmp).addReg(Op0r+1).addImm(HiCst);
+        }
+        unsigned FinalTmp = makeAnotherReg(Type::IntTy);
+        BuildMI(*MBB, IP, X86::OR32rr, 2, FinalTmp).addReg(LoTmp).addReg(HiTmp);
+        return OpNum;
+      } else {
+        // Emit a sequence of code which compares the high and low parts once
+        // each, then uses a conditional move to handle the overflow case.  For
+        // example, a setlt for long would generate code like this:
+        //
+        // AL = lo(op1) < lo(op2)   // Signedness depends on operands
+        // BL = hi(op1) < hi(op2)   // Always unsigned comparison
+        // dest = hi(op1) == hi(op2) ? AL : BL;
+        //
+
+        // FIXME: This would be much better if we had hierarchical register
+        // classes!  Until then, hardcode registers so that we can deal with
+        // their aliases (because we don't have conditional byte moves).
+        //
+        BuildMI(*MBB, IP, X86::CMP32ri, 2).addReg(Op0r).addImm(LowCst);
+        BuildMI(*MBB, IP, SetCCOpcodeTab[0][OpNum], 0, X86::AL);
+        BuildMI(*MBB, IP, X86::CMP32ri, 2).addReg(Op0r+1).addImm(HiCst);
+        BuildMI(*MBB, IP, SetCCOpcodeTab[CompTy->isSigned()][OpNum], 0,X86::BL);
+        BuildMI(*MBB, IP, X86::IMPLICIT_DEF, 0, X86::BH);
+        BuildMI(*MBB, IP, X86::IMPLICIT_DEF, 0, X86::AH);
+        BuildMI(*MBB, IP, X86::CMOVE16rr, 2, X86::BX).addReg(X86::BX)
+          .addReg(X86::AX);
+        // NOTE: visitSetCondInst knows that the value is dumped into the BL
+        // register at this point for long values...
+        return OpNum;
+      }
     }
+  }
 
   // Special case handling of comparison against +/- 0.0
   if (ConstantFP *CFP = dyn_cast<ConstantFP>(Op1))
@@ -1339,11 +1403,19 @@ void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
         }
         break;
       case cLong:
-        ArgReg = Args[i].Val ? getReg(Args[i].Val) : Args[i].Reg;
-        addRegOffset(BuildMI(BB, X86::MOV32mr, 5),
-                     X86::ESP, ArgOffset).addReg(ArgReg);
-        addRegOffset(BuildMI(BB, X86::MOV32mr, 5),
-                     X86::ESP, ArgOffset+4).addReg(ArgReg+1);
+        if (Args[i].Val && isa<ConstantInt>(Args[i].Val)) {
+          uint64_t Val = cast<ConstantInt>(Args[i].Val)->getRawValue();
+          addRegOffset(BuildMI(BB, X86::MOV32mi, 5),
+                       X86::ESP, ArgOffset).addImm(Val & ~0U);
+          addRegOffset(BuildMI(BB, X86::MOV32mi, 5),
+                       X86::ESP, ArgOffset+4).addImm(Val >> 32ULL);
+        } else {
+          ArgReg = Args[i].Val ? getReg(Args[i].Val) : Args[i].Reg;
+          addRegOffset(BuildMI(BB, X86::MOV32mr, 5),
+                       X86::ESP, ArgOffset).addReg(ArgReg);
+          addRegOffset(BuildMI(BB, X86::MOV32mr, 5),
+                       X86::ESP, ArgOffset+4).addReg(ArgReg+1);
+        }
         ArgOffset += 4;        // 8 byte entry, not 4.
         break;
         
@@ -1447,6 +1519,8 @@ void ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) {
           case Intrinsic::frameaddress:
           case Intrinsic::memcpy:
           case Intrinsic::memset:
+          case Intrinsic::readport:
+          case Intrinsic::writeport:
             // We directly implement these intrinsics
             break;
           default:
@@ -1608,6 +1682,72 @@ void ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) {
     return;
   }
 
+  case Intrinsic::readport:
+    //
+    // First, determine that the size of the operand falls within the
+    // acceptable range for this architecture.
+    //
+    if ((CI.getOperand(1)->getType()->getPrimitiveSize()) != 2) {
+      std::cerr << "llvm.readport: Address size is not 16 bits\n";
+      exit (1);
+    }
+
+    //
+    // Now, move the I/O port address into the DX register and use the IN
+    // instruction to get the input data.
+    //
+    BuildMI(BB, X86::MOV16rr, 1, X86::DX).addReg(getReg(CI.getOperand(1)));
+    switch (CI.getCalledFunction()->getReturnType()->getPrimitiveSize()) {
+      case 1:
+        BuildMI(BB, X86::IN8, 0);
+        break;
+      case 2:
+        BuildMI(BB, X86::IN16, 0);
+        break;
+      case 4:
+        BuildMI(BB, X86::IN32, 0);
+        break;
+      default:
+        std::cerr << "Cannot do input on this data type";
+        exit (1);
+    }
+    return;
+
+  case Intrinsic::writeport:
+    //
+    // First, determine that the size of the operand falls within the
+    // acceptable range for this architecture.
+    //
+    //
+    if ((CI.getOperand(2)->getType()->getPrimitiveSize()) != 2) {
+      std::cerr << "llvm.writeport: Address size is not 16 bits\n";
+      exit (1);
+    }
+
+    //
+    // Now, move the I/O port address into the DX register and the value to
+    // write into the AL/AX/EAX register.
+    //
+    BuildMI(BB, X86::MOV16rr, 1, X86::DX).addReg(getReg(CI.getOperand(2)));
+    switch (CI.getOperand(1)->getType()->getPrimitiveSize()) {
+      case 1:
+        BuildMI(BB, X86::MOV8rr, 1, X86::AL).addReg(getReg(CI.getOperand(1)));
+        BuildMI(BB, X86::OUT8, 0);
+        break;
+      case 2:
+        BuildMI(BB, X86::MOV16rr, 1, X86::AX).addReg(getReg(CI.getOperand(1)));
+        BuildMI(BB, X86::OUT16, 0);
+        break;
+      case 4:
+        BuildMI(BB, X86::MOV32rr, 1, X86::EAX).addReg(getReg(CI.getOperand(1)));
+        BuildMI(BB, X86::OUT32, 0);
+        break;
+      default:
+        std::cerr << "Cannot do output on this data type";
+        exit (1);
+    }
+    return;
+
   default: assert(0 && "Error: unknown intrinsics should have been lowered!");
   }
 }
@@ -1734,24 +1874,20 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
     }
 
     // add X, -1 -> dec X
-    if (OperatorClass == 0 && Op1C->isAllOnesValue()) {
-      static unsigned const DECTab[] = {
-        X86::DEC8r, X86::DEC16r, X86::DEC32r, 0, X86::DEC32r
-      };
+    if (OperatorClass == 0 && Op1C->isAllOnesValue() && Class != cLong) {
+      // Note that we can't use dec for 64-bit decrements, because it does not
+      // set the carry flag!
+      static unsigned const DECTab[] = { X86::DEC8r, X86::DEC16r, X86::DEC32r };
       BuildMI(*MBB, IP, DECTab[Class], 1, DestReg).addReg(Op0r);
-      if (Class == cLong)  // Dh = sbb Sh, 0
-        BuildMI(*MBB, IP, X86::SBB32ri, 2, DestReg+1).addReg(Op0r+1).addImm(0);
       return;
     }
 
     // add X, 1 -> inc X
-    if (OperatorClass == 0 && Op1C->equalsInt(1)) {
-      static unsigned const INCTab[] = {
-        X86::INC8r, X86::INC16r, X86::INC32r, 0, X86::INC32r
-      };
+    if (OperatorClass == 0 && Op1C->equalsInt(1) && Class != cLong) {
+      // Note that we can't use inc for 64-bit increments, because it does not
+      // set the carry flag!
+      static unsigned const INCTab[] = { X86::INC8r, X86::INC16r, X86::INC32r };
       BuildMI(*MBB, IP, INCTab[Class], 1, DestReg).addReg(Op0r);
-      if (Class == cLong)  // Dh = adc Sh, 0
-        BuildMI(*MBB, IP, X86::ADC32ri, 2, DestReg+1).addReg(Op0r+1).addImm(0);
       return;
     }
   
@@ -1767,22 +1903,58 @@ void ISel::emitSimpleBinaryOperation(MachineBasicBlock *MBB,
     };
   
     unsigned Opcode = OpcodeTab[OperatorClass][Class];
+    unsigned Op1l = cast<ConstantInt>(Op1C)->getRawValue();
 
-    uint64_t Op1v = cast<ConstantInt>(Op1C)->getRawValue();
-    BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addImm(Op1v &0xFFFFFFFF);
+    if (Class != cLong) {
+      BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addImm(Op1l);
+      return;
+    } else {
+      // If this is a long value and the high or low bits have a special
+      // property, emit some special cases.
+      unsigned Op1h = cast<ConstantInt>(Op1C)->getRawValue() >> 32LL;
+
+      // If the constant is zero in the low 32-bits, just copy the low part
+      // across and apply the normal 32-bit operation to the high parts.  There
+      // will be no carry or borrow into the top.
+      if (Op1l == 0) {
+        if (OperatorClass != 2) // All but and...
+          BuildMI(*MBB, IP, X86::MOV32rr, 1, DestReg).addReg(Op0r);
+        else
+          BuildMI(*MBB, IP, X86::MOV32ri, 1, DestReg).addImm(0);
+        BuildMI(*MBB, IP, OpcodeTab[OperatorClass][cLong], 2, DestReg+1)
+          .addReg(Op0r+1).addImm(Op1h);
+        return;
+      }
 
-    if (Class == cLong) {
+      // If this is a logical operation and the top 32-bits are zero, just
+      // operate on the lower 32.
+      if (Op1h == 0 && OperatorClass > 1) {
+        BuildMI(*MBB, IP, OpcodeTab[OperatorClass][cLong], 2, DestReg)
+          .addReg(Op0r).addImm(Op1l);
+        if (OperatorClass != 2)  // All but and
+          BuildMI(*MBB, IP, X86::MOV32rr, 1, DestReg+1).addReg(Op0r+1);
+        else
+          BuildMI(*MBB, IP, X86::MOV32ri, 1, DestReg+1).addImm(0);
+        return;
+      }
+
+      // TODO: We could handle lots of other special cases here, such as AND'ing
+      // with 0xFFFFFFFF00000000 -> noop, etc.
+
+      // Otherwise, code generate the full operation with a constant.
       static const unsigned TopTab[] = {
         X86::ADC32ri, X86::SBB32ri, X86::AND32ri, X86::OR32ri, X86::XOR32ri
       };
+
+      BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(Op0r).addImm(Op1l);
       BuildMI(*MBB, IP, TopTab[OperatorClass], 2, DestReg+1)
-          .addReg(Op0r+1).addImm(uint64_t(Op1v) >> 32);
+          .addReg(Op0r+1).addImm(Op1h);
+      return;
     }
-    return;
   }
 
   // Finally, handle the general case now.
-  static const unsigned OpcodeTab[][4] = {
+  static const unsigned OpcodeTab[][5] = {
     // Arithmetic operators
     { X86::ADD8rr, X86::ADD16rr, X86::ADD32rr, X86::FpADD, X86::ADD32rr },// ADD
     { X86::SUB8rr, X86::SUB16rr, X86::SUB32rr, X86::FpSUB, X86::SUB32rr },// SUB
@@ -1853,8 +2025,19 @@ void ISel::doMultiplyConst(MachineBasicBlock *MBB,
                            MachineBasicBlock::iterator IP,
                            unsigned DestReg, const Type *DestTy,
                            unsigned op0Reg, unsigned ConstRHS) {
+  static const unsigned MOVrrTab[] = {X86::MOV8rr, X86::MOV16rr, X86::MOV32rr};
+  static const unsigned MOVriTab[] = {X86::MOV8ri, X86::MOV16ri, X86::MOV32ri};
+
   unsigned Class = getClass(DestTy);
 
+  if (ConstRHS == 0) {
+    BuildMI(*MBB, IP, MOVriTab[Class], 1, DestReg).addImm(0);
+    return;
+  } else if (ConstRHS == 1) {
+    BuildMI(*MBB, IP, MOVrrTab[Class], 1, DestReg).addReg(op0Reg);
+    return;
+  }
+
   // If the element size is exactly a power of 2, use a shift to get it.
   if (unsigned Shift = ExactLog2(ConstRHS)) {
     switch (Class) {
@@ -1880,10 +2063,6 @@ void ISel::doMultiplyConst(MachineBasicBlock *MBB,
   }
 
   // Most general case, emit a normal multiply...
-  static const unsigned MOVriTab[] = {
-    X86::MOV8ri, X86::MOV16ri, X86::MOV32ri
-  };
-
   unsigned TmpReg = makeAnotherReg(DestTy);
   BuildMI(*MBB, IP, MOVriTab[Class], 1, TmpReg).addImm(ConstRHS);
   
@@ -1900,7 +2079,7 @@ void ISel::visitMul(BinaryOperator &I) {
   unsigned DestReg = getReg(I);
 
   // Simple scalar multiply?
-  if (I.getType() != Type::LongTy && I.getType() != Type::ULongTy) {
+  if (getClass(I.getType()) != cLong) {
     if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1))) {
       unsigned Val = (unsigned)CI->getRawValue(); // Cannot be 64-bit constant
       MachineBasicBlock::iterator MBBI = BB->end();
@@ -1911,31 +2090,81 @@ void ISel::visitMul(BinaryOperator &I) {
       doMultiply(BB, MBBI, DestReg, I.getType(), Op0Reg, Op1Reg);
     }
   } else {
-    unsigned Op1Reg  = getReg(I.getOperand(1));
-
     // Long value.  We have to do things the hard way...
-    // Multiply the two low parts... capturing carry into EDX
-    BuildMI(BB, X86::MOV32rr, 1, X86::EAX).addReg(Op0Reg);
-    BuildMI(BB, X86::MUL32r, 1).addReg(Op1Reg);  // AL*BL
-
-    unsigned OverflowReg = makeAnotherReg(Type::UIntTy);
-    BuildMI(BB, X86::MOV32rr, 1, DestReg).addReg(X86::EAX);     // AL*BL
-    BuildMI(BB, X86::MOV32rr, 1, OverflowReg).addReg(X86::EDX); // AL*BL >> 32
+    if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(1))) {
+      unsigned CLow = CI->getRawValue();
+      unsigned CHi  = CI->getRawValue() >> 32;
 
-    MachineBasicBlock::iterator MBBI = BB->end();
-    unsigned AHBLReg = makeAnotherReg(Type::UIntTy);   // AH*BL
-    BuildMI(*BB, MBBI, X86::IMUL32rr,2,AHBLReg).addReg(Op0Reg+1).addReg(Op1Reg);
+      if (CLow == 0) {
+        // If the low part of the constant is all zeros, things are simple.
+        BuildMI(BB, X86::MOV32ri, 1, DestReg).addImm(0);
+        doMultiplyConst(BB, BB->end(), DestReg+1, Type::UIntTy, Op0Reg, CHi);
+        return;
+      }
 
-    unsigned AHBLplusOverflowReg = makeAnotherReg(Type::UIntTy);
-    BuildMI(*BB, MBBI, X86::ADD32rr, 2,                  // AH*BL+(AL*BL >> 32)
-            AHBLplusOverflowReg).addReg(AHBLReg).addReg(OverflowReg);
-    
-    MBBI = BB->end();
-    unsigned ALBHReg = makeAnotherReg(Type::UIntTy); // AL*BH
-    BuildMI(*BB, MBBI, X86::IMUL32rr,2,ALBHReg).addReg(Op0Reg).addReg(Op1Reg+1);
-    
-    BuildMI(*BB, MBBI, X86::ADD32rr, 2,         // AL*BH + AH*BL + (AL*BL >> 32)
-            DestReg+1).addReg(AHBLplusOverflowReg).addReg(ALBHReg);
+      // Multiply the two low parts... capturing carry into EDX
+      unsigned OverflowReg = 0;
+      if (CLow == 1) {
+        BuildMI(BB, X86::MOV32rr, 1, DestReg).addReg(Op0Reg);
+      } else {
+        unsigned Op1RegL = makeAnotherReg(Type::UIntTy);
+        OverflowReg = makeAnotherReg(Type::UIntTy);
+        BuildMI(BB, X86::MOV32ri, 1, Op1RegL).addImm(CLow);
+        BuildMI(BB, X86::MOV32rr, 1, X86::EAX).addReg(Op0Reg);
+        BuildMI(BB, X86::MUL32r, 1).addReg(Op1RegL);  // AL*BL
+      
+        BuildMI(BB, X86::MOV32rr, 1, DestReg).addReg(X86::EAX);   // AL*BL
+        BuildMI(BB, X86::MOV32rr, 1,OverflowReg).addReg(X86::EDX);// AL*BL >> 32
+      }
+      
+      unsigned AHBLReg = makeAnotherReg(Type::UIntTy);   // AH*BL
+      doMultiplyConst(BB, BB->end(), AHBLReg, Type::UIntTy, Op0Reg+1, CLow);
+      
+      unsigned AHBLplusOverflowReg;
+      if (OverflowReg) {
+        AHBLplusOverflowReg = makeAnotherReg(Type::UIntTy);
+        BuildMI(BB, X86::ADD32rr, 2,                // AH*BL+(AL*BL >> 32)
+                AHBLplusOverflowReg).addReg(AHBLReg).addReg(OverflowReg);
+      } else {
+        AHBLplusOverflowReg = AHBLReg;
+      }
+      
+      if (CHi == 0) {
+        BuildMI(BB, X86::MOV32rr, 1, DestReg+1).addReg(AHBLplusOverflowReg);
+      } else {
+        unsigned ALBHReg = makeAnotherReg(Type::UIntTy); // AL*BH
+        doMultiplyConst(BB, BB->end(), ALBHReg, Type::UIntTy, Op0Reg, CHi);
+      
+        BuildMI(BB, X86::ADD32rr, 2,      // AL*BH + AH*BL + (AL*BL >> 32)
+                DestReg+1).addReg(AHBLplusOverflowReg).addReg(ALBHReg);
+      }
+    } else {
+      unsigned Op1Reg  = getReg(I.getOperand(1));
+      // Multiply the two low parts... capturing carry into EDX
+      BuildMI(BB, X86::MOV32rr, 1, X86::EAX).addReg(Op0Reg);
+      BuildMI(BB, X86::MUL32r, 1).addReg(Op1Reg);  // AL*BL
+      
+      unsigned OverflowReg = makeAnotherReg(Type::UIntTy);
+      BuildMI(BB, X86::MOV32rr, 1, DestReg).addReg(X86::EAX);     // AL*BL
+      BuildMI(BB, X86::MOV32rr, 1, OverflowReg).addReg(X86::EDX); // AL*BL >> 32
+      
+      MachineBasicBlock::iterator MBBI = BB->end();
+      unsigned AHBLReg = makeAnotherReg(Type::UIntTy);   // AH*BL
+      BuildMI(*BB, MBBI, X86::IMUL32rr, 2,
+              AHBLReg).addReg(Op0Reg+1).addReg(Op1Reg);
+      
+      unsigned AHBLplusOverflowReg = makeAnotherReg(Type::UIntTy);
+      BuildMI(*BB, MBBI, X86::ADD32rr, 2,                // AH*BL+(AL*BL >> 32)
+              AHBLplusOverflowReg).addReg(AHBLReg).addReg(OverflowReg);
+      
+      MBBI = BB->end();
+      unsigned ALBHReg = makeAnotherReg(Type::UIntTy); // AL*BH
+      BuildMI(*BB, MBBI, X86::IMUL32rr, 2,
+              ALBHReg).addReg(Op0Reg).addReg(Op1Reg+1);
+      
+      BuildMI(*BB, MBBI, X86::ADD32rr, 2,      // AL*BH + AH*BL + (AL*BL >> 32)
+              DestReg+1).addReg(AHBLplusOverflowReg).addReg(ALBHReg);
+    }
   }
 }
 
@@ -2088,13 +2317,20 @@ void ISel::emitShiftOperation(MachineBasicBlock *MBB,
       } else {                 // Shifting more than 32 bits
         Amount -= 32;
         if (isLeftShift) {
-          BuildMI(*MBB, IP, X86::SHL32ri, 2,
-              DestReg + 1).addReg(SrcReg).addImm(Amount);
-          BuildMI(*MBB, IP, X86::MOV32ri, 1,
-              DestReg).addImm(0);
+          if (Amount != 0) {
+            BuildMI(*MBB, IP, X86::SHL32ri, 2,
+                    DestReg + 1).addReg(SrcReg).addImm(Amount);
+          } else {
+            BuildMI(*MBB, IP, X86::MOV32rr, 1, DestReg+1).addReg(SrcReg);
+          }
+          BuildMI(*MBB, IP, X86::MOV32ri, 1, DestReg).addImm(0);
         } else {
-          unsigned Opcode = isSigned ? X86::SAR32ri : X86::SHR32ri;
-          BuildMI(*MBB, IP, Opcode, 2, DestReg).addReg(SrcReg+1).addImm(Amount);
+          if (Amount != 0) {
+            BuildMI(*MBB, IP, isSigned ? X86::SAR32ri : X86::SHR32ri, 2,
+                    DestReg).addReg(SrcReg+1).addImm(Amount);
+          } else {
+            BuildMI(*MBB, IP, X86::MOV32rr, 1, DestReg).addReg(SrcReg+1);
+          }
           BuildMI(*MBB, IP, X86::MOV32ri, 1, DestReg+1).addImm(0);
         }
       }
@@ -2306,6 +2542,11 @@ void ISel::visitStoreInst(StoreInst &I) {
 ///
 void ISel::visitCastInst(CastInst &CI) {
   Value *Op = CI.getOperand(0);
+
+  // Noop casts are not even emitted.
+  if (getClassB(CI.getType()) == getClassB(Op->getType()))
+    return;
+
   // If this is a cast from a 32-bit integer to a Long type, and the only uses
   // of the case are GEP instructions, then the cast does not need to be
   // generated explicitly, it will be folded into the GEP.
@@ -2451,7 +2692,7 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
     // a larger signed value, then use FLD on the larger value.
     //
     const Type *PromoteType = 0;
-    unsigned PromoteOpcode;
+    unsigned PromoteOpcode = 0;
     unsigned RealDestReg = DestReg;
     switch (SrcTy->getPrimitiveID()) {
     case Type::BoolTyID:
@@ -2489,8 +2730,7 @@ void ISel::emitCastOperation(MachineBasicBlock *BB,
     
     if (PromoteType) {
       unsigned TmpReg = makeAnotherReg(PromoteType);
-      unsigned Opc = SrcTy->isSigned() ? X86::MOVSX16rr8 : X86::MOVZX16rr8;
-      BuildMI(*BB, IP, Opc, 1, TmpReg).addReg(SrcReg);
+      BuildMI(*BB, IP, PromoteOpcode, 1, TmpReg).addReg(SrcReg);
       SrcTy = PromoteType;
       SrcClass = getClass(PromoteType);
       SrcReg = TmpReg;