TargetLowering.h #includes SelectionDAGNodes.h, so it doesn't need its
[oota-llvm.git] / lib / CodeGen / SelectionDAG / TargetLowering.cpp
index ae9b917f1bd54b451c28b60f03a9ee1e7db535c4..bbd222285e4cf1fe2a1550cddb07e799d4c6b6ad 100644 (file)
@@ -31,20 +31,28 @@ using namespace llvm;
 static void InitLibcallNames(const char **Names) {
   Names[RTLIB::SHL_I32] = "__ashlsi3";
   Names[RTLIB::SHL_I64] = "__ashldi3";
+  Names[RTLIB::SHL_I128] = "__ashlti3";
   Names[RTLIB::SRL_I32] = "__lshrsi3";
   Names[RTLIB::SRL_I64] = "__lshrdi3";
+  Names[RTLIB::SRL_I128] = "__lshrti3";
   Names[RTLIB::SRA_I32] = "__ashrsi3";
   Names[RTLIB::SRA_I64] = "__ashrdi3";
+  Names[RTLIB::SRA_I128] = "__ashrti3";
   Names[RTLIB::MUL_I32] = "__mulsi3";
   Names[RTLIB::MUL_I64] = "__muldi3";
+  Names[RTLIB::MUL_I128] = "__multi3";
   Names[RTLIB::SDIV_I32] = "__divsi3";
   Names[RTLIB::SDIV_I64] = "__divdi3";
+  Names[RTLIB::SDIV_I128] = "__divti3";
   Names[RTLIB::UDIV_I32] = "__udivsi3";
   Names[RTLIB::UDIV_I64] = "__udivdi3";
+  Names[RTLIB::UDIV_I128] = "__udivti3";
   Names[RTLIB::SREM_I32] = "__modsi3";
   Names[RTLIB::SREM_I64] = "__moddi3";
+  Names[RTLIB::SREM_I128] = "__modti3";
   Names[RTLIB::UREM_I32] = "__umodsi3";
   Names[RTLIB::UREM_I64] = "__umoddi3";
+  Names[RTLIB::UREM_I128] = "__umodti3";
   Names[RTLIB::NEG_I32] = "__negsi2";
   Names[RTLIB::NEG_I64] = "__negdi2";
   Names[RTLIB::ADD_F32] = "__addsf3";
@@ -75,6 +83,26 @@ static void InitLibcallNames(const char **Names) {
   Names[RTLIB::SQRT_F64] = "sqrt";
   Names[RTLIB::SQRT_F80] = "sqrtl";
   Names[RTLIB::SQRT_PPCF128] = "sqrtl";
+  Names[RTLIB::LOG_F32] = "logf";
+  Names[RTLIB::LOG_F64] = "log";
+  Names[RTLIB::LOG_F80] = "logl";
+  Names[RTLIB::LOG_PPCF128] = "logl";
+  Names[RTLIB::LOG2_F32] = "log2f";
+  Names[RTLIB::LOG2_F64] = "log2";
+  Names[RTLIB::LOG2_F80] = "log2l";
+  Names[RTLIB::LOG2_PPCF128] = "log2l";
+  Names[RTLIB::LOG10_F32] = "log10f";
+  Names[RTLIB::LOG10_F64] = "log10";
+  Names[RTLIB::LOG10_F80] = "log10l";
+  Names[RTLIB::LOG10_PPCF128] = "log10l";
+  Names[RTLIB::EXP_F32] = "expf";
+  Names[RTLIB::EXP_F64] = "exp";
+  Names[RTLIB::EXP_F80] = "expl";
+  Names[RTLIB::EXP_PPCF128] = "expl";
+  Names[RTLIB::EXP2_F32] = "exp2f";
+  Names[RTLIB::EXP2_F64] = "exp2";
+  Names[RTLIB::EXP2_F80] = "exp2l";
+  Names[RTLIB::EXP2_PPCF128] = "exp2l";
   Names[RTLIB::SIN_F32] = "sinf";
   Names[RTLIB::SIN_F64] = "sin";
   Names[RTLIB::SIN_F80] = "sinl";
@@ -87,14 +115,39 @@ static void InitLibcallNames(const char **Names) {
   Names[RTLIB::POW_F64] = "pow";
   Names[RTLIB::POW_F80] = "powl";
   Names[RTLIB::POW_PPCF128] = "powl";
+  Names[RTLIB::CEIL_F32] = "ceilf";
+  Names[RTLIB::CEIL_F64] = "ceil";
+  Names[RTLIB::CEIL_F80] = "ceill";
+  Names[RTLIB::CEIL_PPCF128] = "ceill";
+  Names[RTLIB::TRUNC_F32] = "truncf";
+  Names[RTLIB::TRUNC_F64] = "trunc";
+  Names[RTLIB::TRUNC_F80] = "truncl";
+  Names[RTLIB::TRUNC_PPCF128] = "truncl";
+  Names[RTLIB::RINT_F32] = "rintf";
+  Names[RTLIB::RINT_F64] = "rint";
+  Names[RTLIB::RINT_F80] = "rintl";
+  Names[RTLIB::RINT_PPCF128] = "rintl";
+  Names[RTLIB::NEARBYINT_F32] = "nearbyintf";
+  Names[RTLIB::NEARBYINT_F64] = "nearbyint";
+  Names[RTLIB::NEARBYINT_F80] = "nearbyintl";
+  Names[RTLIB::NEARBYINT_PPCF128] = "nearbyintl";
+  Names[RTLIB::FLOOR_F32] = "floorf";
+  Names[RTLIB::FLOOR_F64] = "floor";
+  Names[RTLIB::FLOOR_F80] = "floorl";
+  Names[RTLIB::FLOOR_PPCF128] = "floorl";
   Names[RTLIB::FPEXT_F32_F64] = "__extendsfdf2";
   Names[RTLIB::FPROUND_F64_F32] = "__truncdfsf2";
+  Names[RTLIB::FPROUND_F80_F32] = "__truncxfsf2";
+  Names[RTLIB::FPROUND_PPCF128_F32] = "__trunctfsf2";
+  Names[RTLIB::FPROUND_F80_F64] = "__truncxfdf2";
+  Names[RTLIB::FPROUND_PPCF128_F64] = "__trunctfdf2";
   Names[RTLIB::FPTOSINT_F32_I32] = "__fixsfsi";
   Names[RTLIB::FPTOSINT_F32_I64] = "__fixsfdi";
   Names[RTLIB::FPTOSINT_F32_I128] = "__fixsfti";
   Names[RTLIB::FPTOSINT_F64_I32] = "__fixdfsi";
   Names[RTLIB::FPTOSINT_F64_I64] = "__fixdfdi";
   Names[RTLIB::FPTOSINT_F64_I128] = "__fixdfti";
+  Names[RTLIB::FPTOSINT_F80_I32] = "__fixxfsi";
   Names[RTLIB::FPTOSINT_F80_I64] = "__fixxfdi";
   Names[RTLIB::FPTOSINT_F80_I128] = "__fixxfti";
   Names[RTLIB::FPTOSINT_PPCF128_I32] = "__fixtfsi";
@@ -114,6 +167,8 @@ static void InitLibcallNames(const char **Names) {
   Names[RTLIB::FPTOUINT_PPCF128_I128] = "__fixunstfti";
   Names[RTLIB::SINTTOFP_I32_F32] = "__floatsisf";
   Names[RTLIB::SINTTOFP_I32_F64] = "__floatsidf";
+  Names[RTLIB::SINTTOFP_I32_F80] = "__floatsixf";
+  Names[RTLIB::SINTTOFP_I32_PPCF128] = "__floatsitf";
   Names[RTLIB::SINTTOFP_I64_F32] = "__floatdisf";
   Names[RTLIB::SINTTOFP_I64_F64] = "__floatdidf";
   Names[RTLIB::SINTTOFP_I64_F80] = "__floatdixf";
@@ -124,8 +179,16 @@ static void InitLibcallNames(const char **Names) {
   Names[RTLIB::SINTTOFP_I128_PPCF128] = "__floattitf";
   Names[RTLIB::UINTTOFP_I32_F32] = "__floatunsisf";
   Names[RTLIB::UINTTOFP_I32_F64] = "__floatunsidf";
+  Names[RTLIB::UINTTOFP_I32_F80] = "__floatunsixf";
+  Names[RTLIB::UINTTOFP_I32_PPCF128] = "__floatunsitf";
   Names[RTLIB::UINTTOFP_I64_F32] = "__floatundisf";
   Names[RTLIB::UINTTOFP_I64_F64] = "__floatundidf";
+  Names[RTLIB::UINTTOFP_I64_F80] = "__floatundixf";
+  Names[RTLIB::UINTTOFP_I64_PPCF128] = "__floatunditf";
+  Names[RTLIB::UINTTOFP_I128_F32] = "__floatuntisf";
+  Names[RTLIB::UINTTOFP_I128_F64] = "__floatuntidf";
+  Names[RTLIB::UINTTOFP_I128_F80] = "__floatuntixf";
+  Names[RTLIB::UINTTOFP_I128_PPCF128] = "__floatuntitf";
   Names[RTLIB::OEQ_F32] = "__eqsf2";
   Names[RTLIB::OEQ_F64] = "__eqdf2";
   Names[RTLIB::UNE_F32] = "__nesf2";
@@ -144,6 +207,173 @@ static void InitLibcallNames(const char **Names) {
   Names[RTLIB::O_F64] = "__unorddf2";
 }
 
+/// getFPEXT - Return the FPEXT_*_* value for the given types, or
+/// UNKNOWN_LIBCALL if there is none.
+RTLIB::Libcall RTLIB::getFPEXT(MVT OpVT, MVT RetVT) {
+  if (OpVT == MVT::f32) {
+    if (RetVT == MVT::f64)
+      return FPEXT_F32_F64;
+  }
+  return UNKNOWN_LIBCALL;
+}
+
+/// getFPROUND - Return the FPROUND_*_* value for the given types, or
+/// UNKNOWN_LIBCALL if there is none.
+RTLIB::Libcall RTLIB::getFPROUND(MVT OpVT, MVT RetVT) {
+  if (RetVT == MVT::f32) {
+    if (OpVT == MVT::f64)
+      return FPROUND_F64_F32;
+    if (OpVT == MVT::f80)
+      return FPROUND_F80_F32;
+    if (OpVT == MVT::ppcf128)
+      return FPROUND_PPCF128_F32;
+  } else if (RetVT == MVT::f64) {
+    if (OpVT == MVT::f80)
+      return FPROUND_F80_F64;
+    if (OpVT == MVT::ppcf128)
+      return FPROUND_PPCF128_F64;
+  }
+  return UNKNOWN_LIBCALL;
+}
+
+/// getFPTOSINT - Return the FPTOSINT_*_* value for the given types, or
+/// UNKNOWN_LIBCALL if there is none.
+RTLIB::Libcall RTLIB::getFPTOSINT(MVT OpVT, MVT RetVT) {
+  if (OpVT == MVT::f32) {
+    if (RetVT == MVT::i32)
+      return FPTOSINT_F32_I32;
+    if (RetVT == MVT::i64)
+      return FPTOSINT_F32_I64;
+    if (RetVT == MVT::i128)
+      return FPTOSINT_F32_I128;
+  } else if (OpVT == MVT::f64) {
+    if (RetVT == MVT::i32)
+      return FPTOSINT_F64_I32;
+    if (RetVT == MVT::i64)
+      return FPTOSINT_F64_I64;
+    if (RetVT == MVT::i128)
+      return FPTOSINT_F64_I128;
+  } else if (OpVT == MVT::f80) {
+    if (RetVT == MVT::i32)
+      return FPTOSINT_F80_I32;
+    if (RetVT == MVT::i64)
+      return FPTOSINT_F80_I64;
+    if (RetVT == MVT::i128)
+      return FPTOSINT_F80_I128;
+  } else if (OpVT == MVT::ppcf128) {
+    if (RetVT == MVT::i32)
+      return FPTOSINT_PPCF128_I32;
+    if (RetVT == MVT::i64)
+      return FPTOSINT_PPCF128_I64;
+    if (RetVT == MVT::i128)
+      return FPTOSINT_PPCF128_I128;
+  }
+  return UNKNOWN_LIBCALL;
+}
+
+/// getFPTOUINT - Return the FPTOUINT_*_* value for the given types, or
+/// UNKNOWN_LIBCALL if there is none.
+RTLIB::Libcall RTLIB::getFPTOUINT(MVT OpVT, MVT RetVT) {
+  if (OpVT == MVT::f32) {
+    if (RetVT == MVT::i32)
+      return FPTOUINT_F32_I32;
+    if (RetVT == MVT::i64)
+      return FPTOUINT_F32_I64;
+    if (RetVT == MVT::i128)
+      return FPTOUINT_F32_I128;
+  } else if (OpVT == MVT::f64) {
+    if (RetVT == MVT::i32)
+      return FPTOUINT_F64_I32;
+    if (RetVT == MVT::i64)
+      return FPTOUINT_F64_I64;
+    if (RetVT == MVT::i128)
+      return FPTOUINT_F64_I128;
+  } else if (OpVT == MVT::f80) {
+    if (RetVT == MVT::i32)
+      return FPTOUINT_F80_I32;
+    if (RetVT == MVT::i64)
+      return FPTOUINT_F80_I64;
+    if (RetVT == MVT::i128)
+      return FPTOUINT_F80_I128;
+  } else if (OpVT == MVT::ppcf128) {
+    if (RetVT == MVT::i32)
+      return FPTOUINT_PPCF128_I32;
+    if (RetVT == MVT::i64)
+      return FPTOUINT_PPCF128_I64;
+    if (RetVT == MVT::i128)
+      return FPTOUINT_PPCF128_I128;
+  }
+  return UNKNOWN_LIBCALL;
+}
+
+/// getSINTTOFP - Return the SINTTOFP_*_* value for the given types, or
+/// UNKNOWN_LIBCALL if there is none.
+RTLIB::Libcall RTLIB::getSINTTOFP(MVT OpVT, MVT RetVT) {
+  if (OpVT == MVT::i32) {
+    if (RetVT == MVT::f32)
+      return SINTTOFP_I32_F32;
+    else if (RetVT == MVT::f64)
+      return SINTTOFP_I32_F64;
+    else if (RetVT == MVT::f80)
+      return SINTTOFP_I32_F80;
+    else if (RetVT == MVT::ppcf128)
+      return SINTTOFP_I32_PPCF128;
+  } else if (OpVT == MVT::i64) {
+    if (RetVT == MVT::f32)
+      return SINTTOFP_I64_F32;
+    else if (RetVT == MVT::f64)
+      return SINTTOFP_I64_F64;
+    else if (RetVT == MVT::f80)
+      return SINTTOFP_I64_F80;
+    else if (RetVT == MVT::ppcf128)
+      return SINTTOFP_I64_PPCF128;
+  } else if (OpVT == MVT::i128) {
+    if (RetVT == MVT::f32)
+      return SINTTOFP_I128_F32;
+    else if (RetVT == MVT::f64)
+      return SINTTOFP_I128_F64;
+    else if (RetVT == MVT::f80)
+      return SINTTOFP_I128_F80;
+    else if (RetVT == MVT::ppcf128)
+      return SINTTOFP_I128_PPCF128;
+  }
+  return UNKNOWN_LIBCALL;
+}
+
+/// getUINTTOFP - Return the UINTTOFP_*_* value for the given types, or
+/// UNKNOWN_LIBCALL if there is none.
+RTLIB::Libcall RTLIB::getUINTTOFP(MVT OpVT, MVT RetVT) {
+  if (OpVT == MVT::i32) {
+    if (RetVT == MVT::f32)
+      return UINTTOFP_I32_F32;
+    else if (RetVT == MVT::f64)
+      return UINTTOFP_I32_F64;
+    else if (RetVT == MVT::f80)
+      return UINTTOFP_I32_F80;
+    else if (RetVT == MVT::ppcf128)
+      return UINTTOFP_I32_PPCF128;
+  } else if (OpVT == MVT::i64) {
+    if (RetVT == MVT::f32)
+      return UINTTOFP_I64_F32;
+    else if (RetVT == MVT::f64)
+      return UINTTOFP_I64_F64;
+    else if (RetVT == MVT::f80)
+      return UINTTOFP_I64_F80;
+    else if (RetVT == MVT::ppcf128)
+      return UINTTOFP_I64_PPCF128;
+  } else if (OpVT == MVT::i128) {
+    if (RetVT == MVT::f32)
+      return UINTTOFP_I128_F32;
+    else if (RetVT == MVT::f64)
+      return UINTTOFP_I128_F64;
+    else if (RetVT == MVT::f80)
+      return UINTTOFP_I128_F80;
+    else if (RetVT == MVT::ppcf128)
+      return UINTTOFP_I128_PPCF128;
+  }
+  return UNKNOWN_LIBCALL;
+}
+
 /// InitCmpLibcallCCs - Set default comparison libcall CC.
 ///
 static void InitCmpLibcallCCs(ISD::CondCode *CCs) {
@@ -168,14 +398,13 @@ static void InitCmpLibcallCCs(ISD::CondCode *CCs) {
 
 TargetLowering::TargetLowering(TargetMachine &tm)
   : TM(tm), TD(TM.getTargetData()) {
-  assert(ISD::BUILTIN_OP_END <= OpActionsCapacity &&
-         "Fixed size array in TargetLowering is not large enough!");
   // All operations default to being supported.
   memset(OpActions, 0, sizeof(OpActions));
-  memset(LoadXActions, 0, sizeof(LoadXActions));
+  memset(LoadExtActions, 0, sizeof(LoadExtActions));
   memset(TruncStoreActions, 0, sizeof(TruncStoreActions));
   memset(IndexedModeActions, 0, sizeof(IndexedModeActions));
   memset(ConvertActions, 0, sizeof(ConvertActions));
+  memset(CondCodeActions, 0, sizeof(CondCodeActions));
 
   // Set default actions for various operations.
   for (unsigned VT = 0; VT != (unsigned)MVT::LAST_VALUETYPE; ++VT) {
@@ -200,6 +429,18 @@ TargetLowering::TargetLowering(TargetMachine &tm)
   setOperationAction(ISD::ConstantFP, MVT::f64, Expand);
   setOperationAction(ISD::ConstantFP, MVT::f80, Expand);
 
+  // These library functions default to expand.
+  setOperationAction(ISD::FLOG , MVT::f64, Expand);
+  setOperationAction(ISD::FLOG2, MVT::f64, Expand);
+  setOperationAction(ISD::FLOG10,MVT::f64, Expand);
+  setOperationAction(ISD::FEXP , MVT::f64, Expand);
+  setOperationAction(ISD::FEXP2, MVT::f64, Expand);
+  setOperationAction(ISD::FLOG , MVT::f32, Expand);
+  setOperationAction(ISD::FLOG2, MVT::f32, Expand);
+  setOperationAction(ISD::FLOG10,MVT::f32, Expand);
+  setOperationAction(ISD::FEXP , MVT::f32, Expand);
+  setOperationAction(ISD::FEXP2, MVT::f32, Expand);
+
   // Default ISD::TRAP to expand (which turns it into abort).
   setOperationAction(ISD::TRAP, MVT::Other, Expand);
     
@@ -219,7 +460,7 @@ TargetLowering::TargetLowering(TargetMachine &tm)
   StackPointerRegisterToSaveRestore = 0;
   ExceptionPointerRegister = 0;
   ExceptionSelectorRegister = 0;
-  SetCCResultContents = UndefinedSetCCResult;
+  BooleanContents = UndefinedBooleanContent;
   SchedPreferenceInfo = SchedulingForLatency;
   JumpBufSize = 0;
   JumpBufAlignment = 0;
@@ -231,7 +472,8 @@ TargetLowering::TargetLowering(TargetMachine &tm)
   InitCmpLibcallCCs(CmpLibcallCCs);
 
   // Tell Legalize whether the assembler supports DEBUG_LOC.
-  if (!TM.getTargetAsmInfo()->hasDotLocAndDotFile())
+  const TargetAsmInfo *TASM = TM.getTargetAsmInfo();
+  if (!TASM || !TASM->hasDotLocAndDotFile())
     setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand);
 }
 
@@ -328,8 +570,32 @@ void TargetLowering::computeRegisterProperties() {
                                IntermediateVT, NumIntermediates,
                                RegisterVT);
       RegisterTypeForVT[i] = RegisterVT;
-      TransformToType[i] = MVT::Other; // this isn't actually used
-      ValueTypeActions.setTypeAction(VT, Expand);
+      
+      // Determine if there is a legal wider type.
+      bool IsLegalWiderType = false;
+      MVT EltVT = VT.getVectorElementType();
+      unsigned NElts = VT.getVectorNumElements();
+      for (unsigned nVT = i+1; nVT <= MVT::LAST_VECTOR_VALUETYPE; ++nVT) {
+        MVT SVT = (MVT::SimpleValueType)nVT;
+        if (isTypeLegal(SVT) && SVT.getVectorElementType() == EltVT &&
+            SVT.getVectorNumElements() > NElts) {
+          TransformToType[i] = SVT;
+          ValueTypeActions.setTypeAction(VT, Promote);
+          IsLegalWiderType = true;
+          break;
+        }
+      }
+      if (!IsLegalWiderType) {
+        MVT NVT = VT.getPow2VectorType();
+        if (NVT == VT) {
+          // Type is already a power of 2.  The default action is to split.
+          TransformToType[i] = MVT::Other;
+          ValueTypeActions.setTypeAction(VT, Expand);
+        } else {
+          TransformToType[i] = NVT;
+          ValueTypeActions.setTypeAction(VT, Promote);
+        }
+      }
     }
   }
 }
@@ -339,7 +605,7 @@ const char *TargetLowering::getTargetNodeName(unsigned Opcode) const {
 }
 
 
-MVT TargetLowering::getSetCCResultType(const SDOperand &) const {
+MVT TargetLowering::getSetCCResultType(MVT VT) const {
   return getValueType(TD->getIntPtrType());
 }
 
@@ -398,6 +664,20 @@ unsigned TargetLowering::getVectorTypeBreakdown(MVT VT,
   return 1;
 }
 
+/// getWidenVectorType: given a vector type, returns the type to widen to
+/// (e.g., v7i8 to v8i8). If the vector type is legal, it returns itself.
+/// If there is no vector type that we want to widen to, returns MVT::Other
+/// When and where to widen is target dependent based on the cost of
+/// scalarizing vs using the wider vector type.
+MVT TargetLowering::getWidenVectorType(MVT VT) {
+  assert(VT.isVector());
+  if (isTypeLegal(VT))
+    return VT;
+  // Default is not to widen until moved to LegalizeTypes
+  return MVT::Other;
+}
+
 /// getByValTypeAlignment - Return the desired alignment for ByVal aggregate
 /// function arguments in the caller parameter area.  This is the actual
 /// alignment, not its logarithm.
@@ -405,13 +685,30 @@ unsigned TargetLowering::getByValTypeAlignment(const Type *Ty) const {
   return TD->getCallFrameTypeAlignment(Ty);
 }
 
-SDOperand TargetLowering::getPICJumpTableRelocBase(SDOperand Table,
-                                                   SelectionDAG &DAG) const {
+SDValue TargetLowering::getPICJumpTableRelocBase(SDValue Table,
+                                                 SelectionDAG &DAG) const {
   if (usesGlobalOffsetTable())
     return DAG.getNode(ISD::GLOBAL_OFFSET_TABLE, getPointerTy());
   return Table;
 }
 
+bool
+TargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
+  // Assume that everything is safe in static mode.
+  if (getTargetMachine().getRelocationModel() == Reloc::Static)
+    return true;
+
+  // In dynamic-no-pic mode, assume that known defined values are safe.
+  if (getTargetMachine().getRelocationModel() == Reloc::DynamicNoPIC &&
+      GA &&
+      !GA->getGlobal()->isDeclaration() &&
+      !GA->getGlobal()->mayBeOverridden())
+    return true;
+
+  // Otherwise assume nothing is safe.
+  return false;
+}
+
 //===----------------------------------------------------------------------===//
 //  Optimization Methods
 //===----------------------------------------------------------------------===//
@@ -420,7 +717,7 @@ SDOperand TargetLowering::getPICJumpTableRelocBase(SDOperand Table,
 /// specified instruction is a constant integer.  If so, check to see if there
 /// are any bits set in the constant that are not demanded.  If so, shrink the
 /// constant and return true.
-bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(SDOperand Op, 
+bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(SDValue Op, 
                                                         const APInt &Demanded) {
   // FIXME: ISD::SELECT, ISD::SELECT_CC
   switch(Op.getOpcode()) {
@@ -431,7 +728,7 @@ bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(SDOperand Op,
     if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op.getOperand(1)))
       if (C->getAPIntValue().intersects(~Demanded)) {
         MVT VT = Op.getValueType();
-        SDOperand New = DAG.getNode(Op.getOpcode(), VT, Op.getOperand(0),
+        SDValue New = DAG.getNode(Op.getOpcode(), VT, Op.getOperand(0),
                                     DAG.getConstant(Demanded &
                                                       C->getAPIntValue(), 
                                                     VT));
@@ -449,7 +746,7 @@ bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(SDOperand Op,
 /// analyze the expression and return a mask of KnownOne and KnownZero bits for
 /// the expression (used to simplify the caller).  The KnownZero/One bits may
 /// only be accurate for those bits in the DemandedMask.
-bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
+bool TargetLowering::SimplifyDemandedBits(SDValue Op,
                                           const APInt &DemandedMask,
                                           APInt &KnownZero,
                                           APInt &KnownOne,
@@ -464,7 +761,7 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
   KnownZero = KnownOne = APInt(BitWidth, 0);
 
   // Other users may use these bits.
-  if (!Op.Val->hasOneUse()) { 
+  if (!Op.getNode()->hasOneUse()) { 
     if (Depth != 0) {
       // If not at the root, Just compute the KnownZero/KnownOne bits to 
       // simplify things downstream.
@@ -603,7 +900,7 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
     if ((NewMask & (KnownZero|KnownOne)) == NewMask) { // all known
       if ((KnownOne & KnownOne2) == KnownOne) {
         MVT VT = Op.getValueType();
-        SDOperand ANDC = TLO.DAG.getConstant(~KnownOne & NewMask, VT);
+        SDValue ANDC = TLO.DAG.getConstant(~KnownOne & NewMask, VT);
         return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::AND, VT, Op.getOperand(0),
                                                  ANDC));
       }
@@ -618,7 +915,7 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
       if (Expanded.isAllOnesValue()) {
         if (Expanded != C->getAPIntValue()) {
           MVT VT = Op.getValueType();
-          SDOperand New = TLO.DAG.getNode(Op.getOpcode(), VT, Op.getOperand(0),
+          SDValue New = TLO.DAG.getNode(Op.getOpcode(), VT, Op.getOperand(0),
                                           TLO.DAG.getConstant(Expanded, VT));
           return TLO.CombineTo(Op, New);
         }
@@ -670,8 +967,8 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
     break;
   case ISD::SHL:
     if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
-      unsigned ShAmt = SA->getValue();
-      SDOperand InOp = Op.getOperand(0);
+      unsigned ShAmt = SA->getZExtValue();
+      SDValue InOp = Op.getOperand(0);
 
       // If the shift count is an invalid immediate, don't do anything.
       if (ShAmt >= BitWidth)
@@ -683,7 +980,7 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
       if (InOp.getOpcode() == ISD::SRL &&
           isa<ConstantSDNode>(InOp.getOperand(1))) {
         if (ShAmt && (NewMask & APInt::getLowBitsSet(BitWidth, ShAmt)) == 0) {
-          unsigned C1 = cast<ConstantSDNode>(InOp.getOperand(1))->getValue();
+          unsigned C1= cast<ConstantSDNode>(InOp.getOperand(1))->getZExtValue();
           unsigned Opc = ISD::SHL;
           int Diff = ShAmt-C1;
           if (Diff < 0) {
@@ -691,7 +988,7 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
             Opc = ISD::SRL;
           }          
           
-          SDOperand NewSA = 
+          SDValue NewSA = 
             TLO.DAG.getConstant(Diff, Op.getOperand(1).getValueType());
           MVT VT = Op.getValueType();
           return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, VT,
@@ -702,18 +999,18 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
       if (SimplifyDemandedBits(Op.getOperand(0), NewMask.lshr(ShAmt),
                                KnownZero, KnownOne, TLO, Depth+1))
         return true;
-      KnownZero <<= SA->getValue();
-      KnownOne  <<= SA->getValue();
+      KnownZero <<= SA->getZExtValue();
+      KnownOne  <<= SA->getZExtValue();
       // low bits known zero.
-      KnownZero |= APInt::getLowBitsSet(BitWidth, SA->getValue());
+      KnownZero |= APInt::getLowBitsSet(BitWidth, SA->getZExtValue());
     }
     break;
   case ISD::SRL:
     if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
       MVT VT = Op.getValueType();
-      unsigned ShAmt = SA->getValue();
+      unsigned ShAmt = SA->getZExtValue();
       unsigned VTSize = VT.getSizeInBits();
-      SDOperand InOp = Op.getOperand(0);
+      SDValue InOp = Op.getOperand(0);
       
       // If the shift count is an invalid immediate, don't do anything.
       if (ShAmt >= BitWidth)
@@ -725,7 +1022,7 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
       if (InOp.getOpcode() == ISD::SHL &&
           isa<ConstantSDNode>(InOp.getOperand(1))) {
         if (ShAmt && (NewMask & APInt::getHighBitsSet(VTSize, ShAmt)) == 0) {
-          unsigned C1 = cast<ConstantSDNode>(InOp.getOperand(1))->getValue();
+          unsigned C1= cast<ConstantSDNode>(InOp.getOperand(1))->getZExtValue();
           unsigned Opc = ISD::SRL;
           int Diff = ShAmt-C1;
           if (Diff < 0) {
@@ -733,7 +1030,7 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
             Opc = ISD::SHL;
           }          
           
-          SDOperand NewSA =
+          SDValue NewSA =
             TLO.DAG.getConstant(Diff, Op.getOperand(1).getValueType());
           return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, VT,
                                                    InOp.getOperand(0), NewSA));
@@ -755,7 +1052,7 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
   case ISD::SRA:
     if (ConstantSDNode *SA = dyn_cast<ConstantSDNode>(Op.getOperand(1))) {
       MVT VT = Op.getValueType();
-      unsigned ShAmt = SA->getValue();
+      unsigned ShAmt = SA->getZExtValue();
       
       // If the shift count is an invalid immediate, don't do anything.
       if (ShAmt >= BitWidth)
@@ -921,8 +1218,8 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
     
     // If the input is only used by this truncate, see if we can shrink it based
     // on the known demanded bits.
-    if (Op.getOperand(0).Val->hasOneUse()) {
-      SDOperand In = Op.getOperand(0);
+    if (Op.getOperand(0).getNode()->hasOneUse()) {
+      SDValue In = Op.getOperand(0);
       unsigned InBitWidth = In.getValueSizeInBits();
       switch (In.getOpcode()) {
       default: break;
@@ -932,13 +1229,13 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
         if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(In.getOperand(1))){
           APInt HighBits = APInt::getHighBitsSet(InBitWidth,
                                                  InBitWidth - BitWidth);
-          HighBits = HighBits.lshr(ShAmt->getValue());
+          HighBits = HighBits.lshr(ShAmt->getZExtValue());
           HighBits.trunc(BitWidth);
           
-          if (ShAmt->getValue() < BitWidth && !(HighBits & NewMask)) {
+          if (ShAmt->getZExtValue() < BitWidth && !(HighBits & NewMask)) {
             // None of the shifted in bits are needed.  Add a truncate of the
             // shift input, then shift it.
-            SDOperand NewTrunc = TLO.DAG.getNode(ISD::TRUNCATE, 
+            SDValue NewTrunc = TLO.DAG.getNode(ISD::TRUNCATE, 
                                                  Op.getValueType(), 
                                                  In.getOperand(0));
             return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL,Op.getValueType(),
@@ -975,10 +1272,10 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
           isOperationLegal(ISD::FGETSIGN, Op.getValueType())) {
         // Make a FGETSIGN + SHL to move the sign bit into the appropriate
         // place.  We expect the SHL to be eliminated by other optimizations.
-        SDOperand Sign = TLO.DAG.getNode(ISD::FGETSIGN, Op.getValueType(), 
+        SDValue Sign = TLO.DAG.getNode(ISD::FGETSIGN, Op.getValueType(), 
                                          Op.getOperand(0));
         unsigned ShVal = Op.getValueType().getSizeInBits()-1;
-        SDOperand ShAmt = TLO.DAG.getConstant(ShVal, getShiftAmountTy());
+        SDValue ShAmt = TLO.DAG.getConstant(ShVal, getShiftAmountTy());
         return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SHL, Op.getValueType(),
                                                  Sign, ShAmt));
       }
@@ -1002,7 +1299,7 @@ bool TargetLowering::SimplifyDemandedBits(SDOperand Op,
 /// computeMaskedBitsForTargetNode - Determine which of the bits specified 
 /// in Mask are known to be either zero or one and return them in the 
 /// KnownZero/KnownOne bitsets.
-void TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op, 
+void TargetLowering::computeMaskedBitsForTargetNode(const SDValue Op, 
                                                     const APInt &Mask,
                                                     APInt &KnownZero, 
                                                     APInt &KnownOne,
@@ -1020,7 +1317,7 @@ void TargetLowering::computeMaskedBitsForTargetNode(const SDOperand Op,
 /// ComputeNumSignBitsForTargetNode - This method can be implemented by
 /// targets that want to expose additional information about sign bits to the
 /// DAG Combiner.
-unsigned TargetLowering::ComputeNumSignBitsForTargetNode(SDOperand Op,
+unsigned TargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
                                                          unsigned Depth) const {
   assert((Op.getOpcode() >= ISD::BUILTIN_OP_END ||
           Op.getOpcode() == ISD::INTRINSIC_WO_CHAIN ||
@@ -1033,9 +1330,9 @@ unsigned TargetLowering::ComputeNumSignBitsForTargetNode(SDOperand Op,
 
 
 /// SimplifySetCC - Try to simplify a setcc built with the specified operands 
-/// and cc. If it is unable to simplify it, return a null SDOperand.
-SDOperand
-TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
+/// and cc. If it is unable to simplify it, return a null SDValue.
+SDValue
+TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
                               ISD::CondCode Cond, bool foldBooleans,
                               DAGCombinerInfo &DCI) const {
   SelectionDAG &DAG = DCI.DAG;
@@ -1049,9 +1346,9 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
   case ISD::SETTRUE2:  return DAG.getConstant(1, VT);
   }
 
-  if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val)) {
+  if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.getNode())) {
     const APInt &C1 = N1C->getAPIntValue();
-    if (isa<ConstantSDNode>(N0.Val)) {
+    if (isa<ConstantSDNode>(N0.getNode())) {
       return DAG.FoldSetCC(VT, N0, N1, Cond);
     } else {
       // If the LHS is '(srl (ctlz x), 5)', the RHS is 0/1, and this is an
@@ -1060,7 +1357,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
       if (N0.getOpcode() == ISD::SRL && (C1 == 0 || C1 == 1) &&
           N0.getOperand(0).getOpcode() == ISD::CTLZ &&
           N0.getOperand(1).getOpcode() == ISD::Constant) {
-        unsigned ShAmt = cast<ConstantSDNode>(N0.getOperand(1))->getValue();
+        unsigned ShAmt = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
         if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
             ShAmt == Log2_32(N0.getValueType().getSizeInBits())) {
           if ((C1 == 0) == (Cond == ISD::SETEQ)) {
@@ -1072,12 +1369,66 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
             // (srl (ctlz x), 5) == 1  -> X == 0
             Cond = ISD::SETEQ;
           }
-          SDOperand Zero = DAG.getConstant(0, N0.getValueType());
+          SDValue Zero = DAG.getConstant(0, N0.getValueType());
           return DAG.getSetCC(VT, N0.getOperand(0).getOperand(0),
                               Zero, Cond);
         }
       }
-      
+
+      // If the LHS is '(and load, const)', the RHS is 0,
+      // the test is for equality or unsigned, and all 1 bits of the const are
+      // in the same partial word, see if we can shorten the load.
+      if (DCI.isBeforeLegalize() &&
+          N0.getOpcode() == ISD::AND && C1 == 0 &&
+          isa<LoadSDNode>(N0.getOperand(0)) &&
+          N0.getOperand(0).getNode()->hasOneUse() &&
+          isa<ConstantSDNode>(N0.getOperand(1))) {
+        LoadSDNode *Lod = cast<LoadSDNode>(N0.getOperand(0));
+        uint64_t Mask = cast<ConstantSDNode>(N0.getOperand(1))->getZExtValue();
+        uint64_t bestMask = 0;
+        unsigned bestWidth = 0, bestOffset = 0;
+        if (!Lod->isVolatile() && Lod->isUnindexed()) {
+          unsigned origWidth = N0.getValueType().getSizeInBits();
+          // We can narrow (e.g.) 16-bit extending loads on 32-bit target to 
+          // 8 bits, but have to be careful...
+          if (Lod->getExtensionType() != ISD::NON_EXTLOAD)
+            origWidth = Lod->getMemoryVT().getSizeInBits();
+          for (unsigned width = origWidth / 2; width>=8; width /= 2) {
+            uint64_t newMask = (1ULL << width) - 1;
+            for (unsigned offset=0; offset<origWidth/width; offset++) {
+              if ((newMask & Mask)==Mask) {
+                if (!TD->isLittleEndian())
+                  bestOffset = (origWidth/width - offset - 1) * (width/8);
+                else
+                  bestOffset = (uint64_t)offset * (width/8);
+                bestMask = Mask >> (offset * (width/8) * 8);
+                bestWidth = width;
+                break;
+              }
+              newMask = newMask << width;
+            }
+          }
+        }
+        if (bestWidth) {
+          MVT newVT = MVT::getIntegerVT(bestWidth);
+          if (newVT.isRound()) {
+            MVT PtrType = Lod->getOperand(1).getValueType();
+            SDValue Ptr = Lod->getBasePtr();
+            if (bestOffset != 0)
+              Ptr = DAG.getNode(ISD::ADD, PtrType, Lod->getBasePtr(),
+                                DAG.getConstant(bestOffset, PtrType));
+            unsigned NewAlign = MinAlign(Lod->getAlignment(), bestOffset);
+            SDValue NewLoad = DAG.getLoad(newVT, Lod->getChain(), Ptr,
+                                          Lod->getSrcValue(), 
+                                          Lod->getSrcValueOffset() + bestOffset,
+                                          false, NewAlign);
+            return DAG.getSetCC(VT, DAG.getNode(ISD::AND, newVT, NewLoad,
+                                            DAG.getConstant(bestMask, newVT)),
+                                    DAG.getConstant(0LL, newVT), Cond);
+          }
+        }
+      }
+
       // If the LHS is a ZERO_EXTEND, perform the comparison on the input.
       if (N0.getOpcode() == ISD::ZERO_EXTEND) {
         unsigned InSize = N0.getOperand(0).getValueType().getSizeInBits();
@@ -1136,7 +1487,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
         if ((C1 & ExtBits) != 0 && (C1 & ExtBits) != ExtBits)
           return DAG.getConstant(Cond == ISD::SETNE, VT);
         
-        SDOperand ZextOp;
+        SDValue ZextOp;
         MVT Op0Ty = N0.getOperand(0).getValueType();
         if (Op0Ty == ExtSrcTy) {
           ZextOp = N0.getOperand(0);
@@ -1146,7 +1497,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
                                DAG.getConstant(Imm, Op0Ty));
         }
         if (!DCI.isCalledByLegalizer())
-          DCI.AddToWorklist(ZextOp.Val);
+          DCI.AddToWorklist(ZextOp.getNode());
         // Otherwise, make this a use of a zext.
         return DAG.getSetCC(VT, ZextOp, 
                             DAG.getConstant(C1 & APInt::getLowBitsSet(
@@ -1159,7 +1510,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
         
         // SETCC (SETCC), [0|1], [EQ|NE]  -> SETCC
         if (N0.getOpcode() == ISD::SETCC) {
-          bool TrueWhenTrue = (Cond == ISD::SETEQ) ^ (N1C->getValue() != 1);
+          bool TrueWhenTrue = (Cond == ISD::SETEQ) ^ (N1C->getZExtValue() != 1);
           if (TrueWhenTrue)
             return N0;
           
@@ -1183,7 +1534,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
                                     APInt::getHighBitsSet(BitWidth,
                                                           BitWidth-1))) {
             // Okay, get the un-inverted input value.
-            SDOperand Val;
+            SDValue Val;
             if (N0.getOpcode() == ISD::XOR)
               Val = N0.getOperand(0);
             else {
@@ -1254,12 +1605,19 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
       // by changing cc.
 
       // SETUGT X, SINTMAX  -> SETLT X, 0
-      if (Cond == ISD::SETUGT && OperandBitSize != 1 &&
-          C1 == (~0ULL >> (65-OperandBitSize)))
+      if (Cond == ISD::SETUGT && 
+          C1 == APInt::getSignedMaxValue(OperandBitSize))
         return DAG.getSetCC(VT, N0, DAG.getConstant(0, N1.getValueType()),
                             ISD::SETLT);
 
-      // FIXME: Implement the rest of these.
+      // SETULT X, SINTMIN  -> SETGT X, -1
+      if (Cond == ISD::SETULT &&
+          C1 == APInt::getSignedMinValue(OperandBitSize)) {
+        SDValue ConstMinusOne =
+            DAG.getConstant(APInt::getAllOnesValue(OperandBitSize),
+                            N1.getValueType());
+        return DAG.getSetCC(VT, N0, ConstMinusOne, ISD::SETGT);
+      }
 
       // Fold bit comparisons when we can.
       if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
@@ -1268,12 +1626,12 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
                     dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
           if (Cond == ISD::SETNE && C1 == 0) {// (X & 8) != 0  -->  (X & 8) >> 3
             // Perform the xform if the AND RHS is a single bit.
-            if (isPowerOf2_64(AndRHS->getValue())) {
+            if (isPowerOf2_64(AndRHS->getZExtValue())) {
               return DAG.getNode(ISD::SRL, VT, N0,
-                             DAG.getConstant(Log2_64(AndRHS->getValue()),
+                             DAG.getConstant(Log2_64(AndRHS->getZExtValue()),
                                              getShiftAmountTy()));
             }
-          } else if (Cond == ISD::SETEQ && C1 == AndRHS->getValue()) {
+          } else if (Cond == ISD::SETEQ && C1 == AndRHS->getZExtValue()) {
             // (X & 8) == 8  -->  (X & 8) >> 3
             // Perform the xform if C1 is a single bit.
             if (C1.isPowerOf2()) {
@@ -1283,16 +1641,16 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
           }
         }
     }
-  } else if (isa<ConstantSDNode>(N0.Val)) {
+  } else if (isa<ConstantSDNode>(N0.getNode())) {
       // Ensure that the constant occurs on the RHS.
     return DAG.getSetCC(VT, N1, N0, ISD::getSetCCSwappedOperands(Cond));
   }
 
-  if (isa<ConstantFPSDNode>(N0.Val)) {
+  if (isa<ConstantFPSDNode>(N0.getNode())) {
     // Constant fold or commute setcc.
-    SDOperand O = DAG.FoldSetCC(VT, N0, N1, Cond);    
-    if (O.Val) return O;
-  } else if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N1.Val)) {
+    SDValue O = DAG.FoldSetCC(VT, N0, N1, Cond);    
+    if (O.getNode()) return O;
+  } else if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(N1.getNode())) {
     // If the RHS of an FP comparison is a constant, simplify it away in
     // some cases.
     if (CFP->getValueAPF().isNaN()) {
@@ -1354,9 +1712,10 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
       if (ConstantSDNode *RHSC = dyn_cast<ConstantSDNode>(N1)) {
         if (ConstantSDNode *LHSR = dyn_cast<ConstantSDNode>(N0.getOperand(1))) {
           // Turn (X+C1) == C2 --> X == C2-C1
-          if (N0.getOpcode() == ISD::ADD && N0.Val->hasOneUse()) {
+          if (N0.getOpcode() == ISD::ADD && N0.getNode()->hasOneUse()) {
             return DAG.getSetCC(VT, N0.getOperand(0),
-                              DAG.getConstant(RHSC->getValue()-LHSR->getValue(),
+                                DAG.getConstant(RHSC->getAPIntValue()-
+                                                LHSR->getAPIntValue(),
                                 N0.getValueType()), Cond);
           }
           
@@ -1375,7 +1734,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
         
         // Turn (C1-X) == C2 --> X == C1-C2
         if (ConstantSDNode *SUBC = dyn_cast<ConstantSDNode>(N0.getOperand(0))) {
-          if (N0.getOpcode() == ISD::SUB && N0.Val->hasOneUse()) {
+          if (N0.getOpcode() == ISD::SUB && N0.getNode()->hasOneUse()) {
             return
               DAG.getSetCC(VT, N0.getOperand(1),
                            DAG.getConstant(SUBC->getAPIntValue() -
@@ -1394,14 +1753,14 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
         if (DAG.isCommutativeBinOp(N0.getOpcode()))
           return DAG.getSetCC(VT, N0.getOperand(0),
                           DAG.getConstant(0, N0.getValueType()), Cond);
-        else if (N0.Val->hasOneUse()) {
+        else if (N0.getNode()->hasOneUse()) {
           assert(N0.getOpcode() == ISD::SUB && "Unexpected operation!");
           // (Z-X) == X  --> Z == X<<1
-          SDOperand SH = DAG.getNode(ISD::SHL, N1.getValueType(),
+          SDValue SH = DAG.getNode(ISD::SHL, N1.getValueType(),
                                      N1, 
                                      DAG.getConstant(1, getShiftAmountTy()));
           if (!DCI.isCalledByLegalizer())
-            DCI.AddToWorklist(SH.Val);
+            DCI.AddToWorklist(SH.getNode());
           return DAG.getSetCC(VT, N0.getOperand(0), SH, Cond);
         }
       }
@@ -1417,13 +1776,13 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
         if (DAG.isCommutativeBinOp(N1.getOpcode())) {
           return DAG.getSetCC(VT, N1.getOperand(0),
                           DAG.getConstant(0, N1.getValueType()), Cond);
-        } else if (N1.Val->hasOneUse()) {
+        } else if (N1.getNode()->hasOneUse()) {
           assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!");
           // X == (Z-X)  --> X<<1 == Z
-          SDOperand SH = DAG.getNode(ISD::SHL, N1.getValueType(), N0, 
+          SDValue SH = DAG.getNode(ISD::SHL, N1.getValueType(), N0, 
                                      DAG.getConstant(1, getShiftAmountTy()));
           if (!DCI.isCalledByLegalizer())
-            DCI.AddToWorklist(SH.Val);
+            DCI.AddToWorklist(SH.getNode());
           return DAG.getSetCC(VT, SH, N1.getOperand(0), Cond);
         }
       }
@@ -1431,7 +1790,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
   }
 
   // Fold away ALL boolean setcc's.
-  SDOperand Temp;
+  SDValue Temp;
   if (N0.getValueType() == MVT::i1 && foldBooleans) {
     switch (Cond) {
     default: assert(0 && "Unknown integer setcc!");
@@ -1439,7 +1798,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
       Temp = DAG.getNode(ISD::XOR, MVT::i1, N0, N1);
       N0 = DAG.getNode(ISD::XOR, MVT::i1, Temp, DAG.getConstant(1, MVT::i1));
       if (!DCI.isCalledByLegalizer())
-        DCI.AddToWorklist(Temp.Val);
+        DCI.AddToWorklist(Temp.getNode());
       break;
     case ISD::SETNE:  // X != Y   -->  (X^Y)
       N0 = DAG.getNode(ISD::XOR, MVT::i1, N0, N1);
@@ -1449,21 +1808,21 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
       Temp = DAG.getNode(ISD::XOR, MVT::i1, N0, DAG.getConstant(1, MVT::i1));
       N0 = DAG.getNode(ISD::AND, MVT::i1, N1, Temp);
       if (!DCI.isCalledByLegalizer())
-        DCI.AddToWorklist(Temp.Val);
+        DCI.AddToWorklist(Temp.getNode());
       break;
     case ISD::SETLT:  // X <s Y   --> X == 1 & Y == 0  -->  Y^1 & X
     case ISD::SETUGT: // X >u Y   --> X == 1 & Y == 0  -->  Y^1 & X
       Temp = DAG.getNode(ISD::XOR, MVT::i1, N1, DAG.getConstant(1, MVT::i1));
       N0 = DAG.getNode(ISD::AND, MVT::i1, N0, Temp);
       if (!DCI.isCalledByLegalizer())
-        DCI.AddToWorklist(Temp.Val);
+        DCI.AddToWorklist(Temp.getNode());
       break;
     case ISD::SETULE: // X <=u Y  --> X == 0 | Y == 1  -->  X^1 | Y
     case ISD::SETGE:  // X >=s Y  --> X == 0 | Y == 1  -->  X^1 | Y
       Temp = DAG.getNode(ISD::XOR, MVT::i1, N0, DAG.getConstant(1, MVT::i1));
       N0 = DAG.getNode(ISD::OR, MVT::i1, N1, Temp);
       if (!DCI.isCalledByLegalizer())
-        DCI.AddToWorklist(Temp.Val);
+        DCI.AddToWorklist(Temp.getNode());
       break;
     case ISD::SETUGE: // X >=u Y  --> X == 1 | Y == 0  -->  Y^1 | X
     case ISD::SETLE:  // X <=s Y  --> X == 1 | Y == 0  -->  Y^1 | X
@@ -1473,7 +1832,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
     }
     if (VT != MVT::i1) {
       if (!DCI.isCalledByLegalizer())
-        DCI.AddToWorklist(N0.Val);
+        DCI.AddToWorklist(N0.getNode());
       // FIXME: If running after legalize, we probably can't do this.
       N0 = DAG.getNode(ISD::ZERO_EXTEND, VT, N0);
     }
@@ -1481,7 +1840,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDOperand N0, SDOperand N1,
   }
 
   // Could not fold it.
-  return SDOperand();
+  return SDValue();
 }
 
 /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the
@@ -1496,18 +1855,18 @@ bool TargetLowering::isGAPlusOffset(SDNode *N, GlobalValue* &GA,
   }
 
   if (N->getOpcode() == ISD::ADD) {
-    SDOperand N1 = N->getOperand(0);
-    SDOperand N2 = N->getOperand(1);
-    if (isGAPlusOffset(N1.Val, GA, Offset)) {
+    SDValue N1 = N->getOperand(0);
+    SDValue N2 = N->getOperand(1);
+    if (isGAPlusOffset(N1.getNode(), GA, Offset)) {
       ConstantSDNode *V = dyn_cast<ConstantSDNode>(N2);
       if (V) {
-        Offset += V->getSignExtended();
+        Offset += V->getSExtValue();
         return true;
       }
-    } else if (isGAPlusOffset(N2.Val, GA, Offset)) {
+    } else if (isGAPlusOffset(N2.getNode(), GA, Offset)) {
       ConstantSDNode *V = dyn_cast<ConstantSDNode>(N1);
       if (V) {
-        Offset += V->getSignExtended();
+        Offset += V->getSExtValue();
         return true;
       }
     }
@@ -1522,14 +1881,14 @@ bool TargetLowering::isGAPlusOffset(SDNode *N, GlobalValue* &GA,
 bool TargetLowering::isConsecutiveLoad(SDNode *LD, SDNode *Base,
                                        unsigned Bytes, int Dist,
                                        const MachineFrameInfo *MFI) const {
-  if (LD->getOperand(0).Val != Base->getOperand(0).Val)
+  if (LD->getOperand(0).getNode() != Base->getOperand(0).getNode())
     return false;
   MVT VT = LD->getValueType(0);
   if (VT.getSizeInBits() / 8 != Bytes)
     return false;
 
-  SDOperand Loc = LD->getOperand(1);
-  SDOperand BaseLoc = Base->getOperand(1);
+  SDValue Loc = LD->getOperand(1);
+  SDValue BaseLoc = Base->getOperand(1);
   if (Loc.getOpcode() == ISD::FrameIndex) {
     if (BaseLoc.getOpcode() != ISD::FrameIndex)
       return false;
@@ -1545,18 +1904,18 @@ bool TargetLowering::isConsecutiveLoad(SDNode *LD, SDNode *Base,
   GlobalValue *GV2 = NULL;
   int64_t Offset1 = 0;
   int64_t Offset2 = 0;
-  bool isGA1 = isGAPlusOffset(Loc.Val, GV1, Offset1);
-  bool isGA2 = isGAPlusOffset(BaseLoc.Val, GV2, Offset2);
+  bool isGA1 = isGAPlusOffset(Loc.getNode(), GV1, Offset1);
+  bool isGA2 = isGAPlusOffset(BaseLoc.getNode(), GV2, Offset2);
   if (isGA1 && isGA2 && GV1 == GV2)
     return Offset1 == (Offset2 + Dist*Bytes);
   return false;
 }
 
 
-SDOperand TargetLowering::
+SDValue TargetLowering::
 PerformDAGCombine(SDNode *N, DAGCombinerInfo &DCI) const {
   // Default implementation: no optimization.
-  return SDOperand();
+  return SDValue();
 }
 
 //===----------------------------------------------------------------------===//
@@ -1610,9 +1969,10 @@ const char *TargetLowering::LowerXConstraint(MVT ConstraintVT) const{
 
 /// LowerAsmOperandForConstraint - Lower the specified operand into the Ops
 /// vector.  If it is invalid, don't add anything to Ops.
-void TargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
+void TargetLowering::LowerAsmOperandForConstraint(SDValue Op,
                                                   char ConstraintLetter,
-                                                  std::vector<SDOperand> &Ops,
+                                                  bool hasMemory,
+                                                  std::vector<SDValue> &Ops,
                                                   SelectionDAG &DAG) const {
   switch (ConstraintLetter) {
   default: break;
@@ -1648,7 +2008,7 @@ void TargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
     if (GA) {   // Either &GV   or   &GV+C
       if (ConstraintLetter != 'n') {
         int64_t Offs = GA->getOffset();
-        if (C) Offs += C->getValue();
+        if (C) Offs += C->getZExtValue();
         Ops.push_back(DAG.getTargetGlobalAddress(GA->getGlobal(),
                                                  Op.getValueType(), Offs));
         return;
@@ -1657,7 +2017,8 @@ void TargetLowering::LowerAsmOperandForConstraint(SDOperand Op,
     if (C) {   // just C, no GV.
       // Simple constants are not allowed for 's'.
       if (ConstraintLetter != 's') {
-        Ops.push_back(DAG.getTargetConstant(C->getValue(), Op.getValueType()));
+        Ops.push_back(DAG.getTargetConstant(C->getAPIntValue(),
+                                            Op.getValueType()));
         return;
       }
     }
@@ -1715,6 +2076,21 @@ getRegForInlineAsmConstraint(const std::string &Constraint,
 //===----------------------------------------------------------------------===//
 // Constraint Selection.
 
+/// isMatchingInputConstraint - Return true of this is an input operand that is
+/// a matching constraint like "4".
+bool TargetLowering::AsmOperandInfo::isMatchingInputConstraint() const {
+  assert(!ConstraintCode.empty() && "No known constraint!");
+  return isdigit(ConstraintCode[0]);
+}
+
+/// getMatchedOperand - If this is an input matching constraint, this method
+/// returns the output operand it matches.
+unsigned TargetLowering::AsmOperandInfo::getMatchedOperand() const {
+  assert(!ConstraintCode.empty() && "No known constraint!");
+  return atoi(ConstraintCode.c_str());
+}
+
+
 /// getConstraintGenerality - Return an integer indicating how general CT
 /// is.
 static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT) {
@@ -1753,8 +2129,8 @@ static unsigned getConstraintGenerality(TargetLowering::ConstraintType CT) {
 ///     'm' over 'r', for example.
 ///
 static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo,
-                             const TargetLowering &TLI,
-                             SDOperand Op, SelectionDAG *DAG) {
+                             bool hasMemory,  const TargetLowering &TLI,
+                             SDValue Op, SelectionDAG *DAG) {
   assert(OpInfo.Codes.size() > 1 && "Doesn't have multiple constraint options");
   unsigned BestIdx = 0;
   TargetLowering::ConstraintType BestType = TargetLowering::C_Unknown;
@@ -1769,11 +2145,11 @@ static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo,
     // For example, on X86 we might have an 'rI' constraint.  If the operand
     // is an integer in the range [0..31] we want to use I (saving a load
     // of a register), otherwise we must use 'r'.
-    if (CType == TargetLowering::C_Other && Op.Val) {
+    if (CType == TargetLowering::C_Other && Op.getNode()) {
       assert(OpInfo.Codes[i].size() == 1 &&
              "Unhandled multi-letter 'other' constraint");
-      std::vector<SDOperand> ResultOps;
-      TLI.LowerAsmOperandForConstraint(Op, OpInfo.Codes[i][0],
+      std::vector<SDValue> ResultOps;
+      TLI.LowerAsmOperandForConstraint(Op, OpInfo.Codes[i][0], hasMemory,
                                        ResultOps, *DAG);
       if (!ResultOps.empty()) {
         BestType = CType;
@@ -1799,7 +2175,8 @@ static void ChooseConstraint(TargetLowering::AsmOperandInfo &OpInfo,
 /// type to use for the specific AsmOperandInfo, setting
 /// OpInfo.ConstraintCode and OpInfo.ConstraintType.
 void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo,
-                                            SDOperand Op, 
+                                            SDValue Op, 
+                                            bool hasMemory,
                                             SelectionDAG *DAG) const {
   assert(!OpInfo.Codes.empty() && "Must have at least one constraint");
   
@@ -1808,7 +2185,7 @@ void TargetLowering::ComputeConstraintToUse(AsmOperandInfo &OpInfo,
     OpInfo.ConstraintCode = OpInfo.Codes[0];
     OpInfo.ConstraintType = getConstraintType(OpInfo.ConstraintCode);
   } else {
-    ChooseConstraint(OpInfo, *this, Op, DAG);
+    ChooseConstraint(OpInfo, hasMemory, *this, Op, DAG);
   }
   
   // 'X' matches anything.
@@ -1866,231 +2243,158 @@ bool TargetLowering::isLegalAddressingMode(const AddrMode &AM,
   return true;
 }
 
-// Magic for divide replacement
-
-struct ms {
-  int64_t m;  // magic number
-  int64_t s;  // shift amount
-};
-
 struct mu {
-  uint64_t m; // magic number
-  int64_t a;  // add indicator
-  int64_t s;  // shift amount
+  APInt m;     // magic number
+  bool a;      // add indicator
+  unsigned s;  // shift amount
 };
 
-/// magic - calculate the magic numbers required to codegen an integer sdiv as
-/// a sequence of multiply and shifts.  Requires that the divisor not be 0, 1,
-/// or -1.
-static ms magic32(int32_t d) {
-  int32_t p;
-  uint32_t ad, anc, delta, q1, r1, q2, r2, t;
-  const uint32_t two31 = 0x80000000U;
-  struct ms mag;
-  
-  ad = abs(d);
-  t = two31 + ((uint32_t)d >> 31);
-  anc = t - 1 - t%ad;   // absolute value of nc
-  p = 31;               // initialize p
-  q1 = two31/anc;       // initialize q1 = 2p/abs(nc)
-  r1 = two31 - q1*anc;  // initialize r1 = rem(2p,abs(nc))
-  q2 = two31/ad;        // initialize q2 = 2p/abs(d)
-  r2 = two31 - q2*ad;   // initialize r2 = rem(2p,abs(d))
-  do {
-    p = p + 1;
-    q1 = 2*q1;        // update q1 = 2p/abs(nc)
-    r1 = 2*r1;        // update r1 = rem(2p/abs(nc))
-    if (r1 >= anc) {  // must be unsigned comparison
-      q1 = q1 + 1;
-      r1 = r1 - anc;
-    }
-    q2 = 2*q2;        // update q2 = 2p/abs(d)
-    r2 = 2*r2;        // update r2 = rem(2p/abs(d))
-    if (r2 >= ad) {   // must be unsigned comparison
-      q2 = q2 + 1;
-      r2 = r2 - ad;
-    }
-    delta = ad - r2;
-  } while (q1 < delta || (q1 == delta && r1 == 0));
-  
-  mag.m = (int32_t)(q2 + 1); // make sure to sign extend
-  if (d < 0) mag.m = -mag.m; // resulting magic number
-  mag.s = p - 32;            // resulting shift
-  return mag;
-}
-
 /// magicu - calculate the magic numbers required to codegen an integer udiv as
 /// a sequence of multiply, add and shifts.  Requires that the divisor not be 0.
-static mu magicu32(uint32_t d) {
-  int32_t p;
-  uint32_t nc, delta, q1, r1, q2, r2;
+static mu magicu(const APInt& d) {
+  unsigned p;
+  APInt nc, delta, q1, r1, q2, r2;
   struct mu magu;
   magu.a = 0;               // initialize "add" indicator
-  nc = - 1 - (-d)%d;
-  p = 31;                   // initialize p
-  q1 = 0x80000000/nc;       // initialize q1 = 2p/nc
-  r1 = 0x80000000 - q1*nc;  // initialize r1 = rem(2p,nc)
-  q2 = 0x7FFFFFFF/d;        // initialize q2 = (2p-1)/d
-  r2 = 0x7FFFFFFF - q2*d;   // initialize r2 = rem((2p-1),d)
+  APInt allOnes = APInt::getAllOnesValue(d.getBitWidth());
+  APInt signedMin = APInt::getSignedMinValue(d.getBitWidth());
+  APInt signedMax = APInt::getSignedMaxValue(d.getBitWidth());
+
+  nc = allOnes - (-d).urem(d);
+  p = d.getBitWidth() - 1;  // initialize p
+  q1 = signedMin.udiv(nc);  // initialize q1 = 2p/nc
+  r1 = signedMin - q1*nc;   // initialize r1 = rem(2p,nc)
+  q2 = signedMax.udiv(d);   // initialize q2 = (2p-1)/d
+  r2 = signedMax - q2*d;    // initialize r2 = rem((2p-1),d)
   do {
     p = p + 1;
-    if (r1 >= nc - r1 ) {
-      q1 = 2*q1 + 1;  // update q1
-      r1 = 2*r1 - nc; // update r1
+    if (r1.uge(nc - r1)) {
+      q1 = q1 + q1 + 1;  // update q1
+      r1 = r1 + r1 - nc; // update r1
     }
     else {
-      q1 = 2*q1; // update q1
-      r1 = 2*r1; // update r1
+      q1 = q1+q1; // update q1
+      r1 = r1+r1; // update r1
     }
-    if (r2 + 1 >= d - r2) {
-      if (q2 >= 0x7FFFFFFF) magu.a = 1;
-      q2 = 2*q2 + 1;     // update q2
-      r2 = 2*r2 + 1 - d; // update r2
+    if ((r2 + 1).uge(d - r2)) {
+      if (q2.uge(signedMax)) magu.a = 1;
+      q2 = q2+q2 + 1;     // update q2
+      r2 = r2+r2 + 1 - d; // update r2
     }
     else {
-      if (q2 >= 0x80000000) magu.a = 1;
-      q2 = 2*q2;     // update q2
-      r2 = 2*r2 + 1; // update r2
+      if (q2.uge(signedMin)) magu.a = 1;
+      q2 = q2+q2;     // update q2
+      r2 = r2+r2 + 1; // update r2
     }
     delta = d - 1 - r2;
-  } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0)));
+  } while (p < d.getBitWidth()*2 &&
+           (q1.ult(delta) || (q1 == delta && r1 == 0)));
   magu.m = q2 + 1; // resulting magic number
-  magu.s = p - 32;  // resulting shift
+  magu.s = p - d.getBitWidth();  // resulting shift
   return magu;
 }
 
+// Magic for divide replacement
+struct ms {
+  APInt m;  // magic number
+  unsigned s;  // shift amount
+};
+
 /// magic - calculate the magic numbers required to codegen an integer sdiv as
 /// a sequence of multiply and shifts.  Requires that the divisor not be 0, 1,
 /// or -1.
-static ms magic64(int64_t d) {
-  int64_t p;
-  uint64_t ad, anc, delta, q1, r1, q2, r2, t;
-  const uint64_t two63 = 9223372036854775808ULL; // 2^63
+static ms magic(const APInt& d) {
+  unsigned p;
+  APInt ad, anc, delta, q1, r1, q2, r2, t;
+  APInt allOnes = APInt::getAllOnesValue(d.getBitWidth());
+  APInt signedMin = APInt::getSignedMinValue(d.getBitWidth());
+  APInt signedMax = APInt::getSignedMaxValue(d.getBitWidth());
   struct ms mag;
   
-  ad = d >= 0 ? d : -d;
-  t = two63 + ((uint64_t)d >> 63);
-  anc = t - 1 - t%ad;   // absolute value of nc
-  p = 63;               // initialize p
-  q1 = two63/anc;       // initialize q1 = 2p/abs(nc)
-  r1 = two63 - q1*anc;  // initialize r1 = rem(2p,abs(nc))
-  q2 = two63/ad;        // initialize q2 = 2p/abs(d)
-  r2 = two63 - q2*ad;   // initialize r2 = rem(2p,abs(d))
+  ad = d.abs();
+  t = signedMin + (d.lshr(d.getBitWidth() - 1));
+  anc = t - 1 - t.urem(ad);   // absolute value of nc
+  p = d.getBitWidth() - 1;    // initialize p
+  q1 = signedMin.udiv(anc);   // initialize q1 = 2p/abs(nc)
+  r1 = signedMin - q1*anc;    // initialize r1 = rem(2p,abs(nc))
+  q2 = signedMin.udiv(ad);    // initialize q2 = 2p/abs(d)
+  r2 = signedMin - q2*ad;     // initialize r2 = rem(2p,abs(d))
   do {
     p = p + 1;
-    q1 = 2*q1;        // update q1 = 2p/abs(nc)
-    r1 = 2*r1;        // update r1 = rem(2p/abs(nc))
-    if (r1 >= anc) {  // must be unsigned comparison
+    q1 = q1<<1;          // update q1 = 2p/abs(nc)
+    r1 = r1<<1;          // update r1 = rem(2p/abs(nc))
+    if (r1.uge(anc)) {  // must be unsigned comparison
       q1 = q1 + 1;
       r1 = r1 - anc;
     }
-    q2 = 2*q2;        // update q2 = 2p/abs(d)
-    r2 = 2*r2;        // update r2 = rem(2p/abs(d))
-    if (r2 >= ad) {   // must be unsigned comparison
+    q2 = q2<<1;          // update q2 = 2p/abs(d)
+    r2 = r2<<1;          // update r2 = rem(2p/abs(d))
+    if (r2.uge(ad)) {   // must be unsigned comparison
       q2 = q2 + 1;
       r2 = r2 - ad;
     }
     delta = ad - r2;
-  } while (q1 < delta || (q1 == delta && r1 == 0));
+  } while (q1.ule(delta) || (q1 == delta && r1 == 0));
   
   mag.m = q2 + 1;
-  if (d < 0) mag.m = -mag.m; // resulting magic number
-  mag.s = p - 64;            // resulting shift
+  if (d.isNegative()) mag.m = -mag.m;   // resulting magic number
+  mag.s = p - d.getBitWidth();          // resulting shift
   return mag;
 }
 
-/// magicu - calculate the magic numbers required to codegen an integer udiv as
-/// a sequence of multiply, add and shifts.  Requires that the divisor not be 0.
-static mu magicu64(uint64_t d)
-{
-  int64_t p;
-  uint64_t nc, delta, q1, r1, q2, r2;
-  struct mu magu;
-  magu.a = 0;               // initialize "add" indicator
-  nc = - 1 - (-d)%d;
-  p = 63;                   // initialize p
-  q1 = 0x8000000000000000ull/nc;       // initialize q1 = 2p/nc
-  r1 = 0x8000000000000000ull - q1*nc;  // initialize r1 = rem(2p,nc)
-  q2 = 0x7FFFFFFFFFFFFFFFull/d;        // initialize q2 = (2p-1)/d
-  r2 = 0x7FFFFFFFFFFFFFFFull - q2*d;   // initialize r2 = rem((2p-1),d)
-  do {
-    p = p + 1;
-    if (r1 >= nc - r1 ) {
-      q1 = 2*q1 + 1;  // update q1
-      r1 = 2*r1 - nc; // update r1
-    }
-    else {
-      q1 = 2*q1; // update q1
-      r1 = 2*r1; // update r1
-    }
-    if (r2 + 1 >= d - r2) {
-      if (q2 >= 0x7FFFFFFFFFFFFFFFull) magu.a = 1;
-      q2 = 2*q2 + 1;     // update q2
-      r2 = 2*r2 + 1 - d; // update r2
-    }
-    else {
-      if (q2 >= 0x8000000000000000ull) magu.a = 1;
-      q2 = 2*q2;     // update q2
-      r2 = 2*r2 + 1; // update r2
-    }
-    delta = d - 1 - r2;
-  } while (p < 128 && (q1 < delta || (q1 == delta && r1 == 0)));
-  magu.m = q2 + 1; // resulting magic number
-  magu.s = p - 64;  // resulting shift
-  return magu;
-}
-
 /// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant,
 /// return a DAG expression to select that will generate the same value by
 /// multiplying by a magic number.  See:
 /// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
-SDOperand TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG, 
-                                    std::vector<SDNode*>* Created) const {
+SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG, 
+                                  std::vector<SDNode*>* Created) const {
   MVT VT = N->getValueType(0);
   
   // Check to see if we can do this.
-  if (!isTypeLegal(VT) || (VT != MVT::i32 && VT != MVT::i64))
-    return SDOperand();       // BuildSDIV only operates on i32 or i64
+  // FIXME: We should be more aggressive here.
+  if (!isTypeLegal(VT))
+    return SDValue();
   
-  int64_t d = cast<ConstantSDNode>(N->getOperand(1))->getSignExtended();
-  ms magics = (VT == MVT::i32) ? magic32(d) : magic64(d);
+  APInt d = cast<ConstantSDNode>(N->getOperand(1))->getAPIntValue();
+  ms magics = magic(d);
   
   // Multiply the numerator (operand 0) by the magic value
-  SDOperand Q;
+  // FIXME: We should support doing a MUL in a wider type
+  SDValue Q;
   if (isOperationLegal(ISD::MULHS, VT))
     Q = DAG.getNode(ISD::MULHS, VT, N->getOperand(0),
                     DAG.getConstant(magics.m, VT));
   else if (isOperationLegal(ISD::SMUL_LOHI, VT))
-    Q = SDOperand(DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(VT, VT),
+    Q = SDValue(DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(VT, VT),
                               N->getOperand(0),
-                              DAG.getConstant(magics.m, VT)).Val, 1);
+                              DAG.getConstant(magics.m, VT)).getNode(), 1);
   else
-    return SDOperand();       // No mulhs or equvialent
+    return SDValue();       // No mulhs or equvialent
   // If d > 0 and m < 0, add the numerator
-  if (d > 0 && magics.m < 0) { 
+  if (d.isStrictlyPositive() && magics.m.isNegative()) { 
     Q = DAG.getNode(ISD::ADD, VT, Q, N->getOperand(0));
     if (Created)
-      Created->push_back(Q.Val);
+      Created->push_back(Q.getNode());
   }
   // If d < 0 and m > 0, subtract the numerator.
-  if (d < 0 && magics.m > 0) {
+  if (d.isNegative() && magics.m.isStrictlyPositive()) {
     Q = DAG.getNode(ISD::SUB, VT, Q, N->getOperand(0));
     if (Created)
-      Created->push_back(Q.Val);
+      Created->push_back(Q.getNode());
   }
   // Shift right algebraic if shift value is nonzero
   if (magics.s > 0) {
     Q = DAG.getNode(ISD::SRA, VT, Q, 
                     DAG.getConstant(magics.s, getShiftAmountTy()));
     if (Created)
-      Created->push_back(Q.Val);
+      Created->push_back(Q.getNode());
   }
   // Extract the sign bit and add it to the quotient
-  SDOperand T =
+  SDValue T =
     DAG.getNode(ISD::SRL, VT, Q, DAG.getConstant(VT.getSizeInBits()-1,
                                                  getShiftAmountTy()));
   if (Created)
-    Created->push_back(T.Val);
+    Created->push_back(T.getNode());
   return DAG.getNode(ISD::ADD, VT, Q, T);
 }
 
@@ -2098,45 +2402,51 @@ SDOperand TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG,
 /// return a DAG expression to select that will generate the same value by
 /// multiplying by a magic number.  See:
 /// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html>
-SDOperand TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
-                                    std::vector<SDNode*>* Created) const {
+SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG,
+                                  std::vector<SDNode*>* Created) const {
   MVT VT = N->getValueType(0);
-  
+
   // Check to see if we can do this.
-  if (!isTypeLegal(VT) || (VT != MVT::i32 && VT != MVT::i64))
-    return SDOperand();       // BuildUDIV only operates on i32 or i64
-  
-  uint64_t d = cast<ConstantSDNode>(N->getOperand(1))->getValue();
-  mu magics = (VT == MVT::i32) ? magicu32(d) : magicu64(d);
-  
+  // FIXME: We should be more aggressive here.
+  if (!isTypeLegal(VT))
+    return SDValue();
+
+  // FIXME: We should use a narrower constant when the upper
+  // bits are known to be zero.
+  ConstantSDNode *N1C = cast<ConstantSDNode>(N->getOperand(1));
+  mu magics = magicu(N1C->getAPIntValue());
+
   // Multiply the numerator (operand 0) by the magic value
-  SDOperand Q;
+  // FIXME: We should support doing a MUL in a wider type
+  SDValue Q;
   if (isOperationLegal(ISD::MULHU, VT))
     Q = DAG.getNode(ISD::MULHU, VT, N->getOperand(0),
                     DAG.getConstant(magics.m, VT));
   else if (isOperationLegal(ISD::UMUL_LOHI, VT))
-    Q = SDOperand(DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(VT, VT),
+    Q = SDValue(DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(VT, VT),
                               N->getOperand(0),
-                              DAG.getConstant(magics.m, VT)).Val, 1);
+                              DAG.getConstant(magics.m, VT)).getNode(), 1);
   else
-    return SDOperand();       // No mulhu or equvialent
+    return SDValue();       // No mulhu or equvialent
   if (Created)
-    Created->push_back(Q.Val);
+    Created->push_back(Q.getNode());
 
   if (magics.a == 0) {
+    assert(magics.s < N1C->getAPIntValue().getBitWidth() &&
+           "We shouldn't generate an undefined shift!");
     return DAG.getNode(ISD::SRL, VT, Q, 
                        DAG.getConstant(magics.s, getShiftAmountTy()));
   } else {
-    SDOperand NPQ = DAG.getNode(ISD::SUB, VT, N->getOperand(0), Q);
+    SDValue NPQ = DAG.getNode(ISD::SUB, VT, N->getOperand(0), Q);
     if (Created)
-      Created->push_back(NPQ.Val);
+      Created->push_back(NPQ.getNode());
     NPQ = DAG.getNode(ISD::SRL, VT, NPQ, 
                       DAG.getConstant(1, getShiftAmountTy()));
     if (Created)
-      Created->push_back(NPQ.Val);
+      Created->push_back(NPQ.getNode());
     NPQ = DAG.getNode(ISD::ADD, VT, NPQ, Q);
     if (Created)
-      Created->push_back(NPQ.Val);
+      Created->push_back(NPQ.getNode());
     return DAG.getNode(ISD::SRL, VT, NPQ, 
                        DAG.getConstant(magics.s-1, getShiftAmountTy()));
   }