add expand support for extractelement
[oota-llvm.git] / lib / CodeGen / SelectionDAG / LegalizeDAG.cpp
index 1d6841912197e587f1d168d59d680454888625d1..6c2b188b38f18f093a5cd4d24e7e8d8b776c7463 100644 (file)
@@ -41,24 +41,28 @@ class SelectionDAGLegalize {
   TargetLowering &TLI;
   SelectionDAG &DAG;
 
-  /// LegalizeAction - This enum indicates what action we should take for each
-  /// value type the can occur in the program.
+  // Libcall insertion helpers.
+  
+  /// LastCALLSEQ_END - This keeps track of the CALLSEQ_END node that has been
+  /// legalized.  We use this to ensure that calls are properly serialized
+  /// against each other, including inserted libcalls.
+  SDOperand LastCALLSEQ_END;
+  
+  /// IsLegalizingCall - This member is used *only* for purposes of providing
+  /// helpful assertions that a libcall isn't created while another call is 
+  /// being legalized (which could lead to non-serialized call sequences).
+  bool IsLegalizingCall;
+  
   enum LegalizeAction {
-    Legal,            // The target natively supports this value type.
-    Promote,          // This should be promoted to the next larger type.
-    Expand,           // This integer type should be broken into smaller pieces.
+    Legal,      // The target natively supports this operation.
+    Promote,    // This operation should be executed in a larger type.
+    Expand,     // Try to expand this to other ops, otherwise use a libcall.
   };
-
+  
   /// ValueTypeActions - This is a bitvector that contains two bits for each
   /// value type, where the two bits correspond to the LegalizeAction enum.
   /// This can be queried with "getTypeAction(VT)".
-  unsigned long long ValueTypeActions;
-
-  /// NeedsAnotherIteration - This is set when we expand a large integer
-  /// operation into smaller integer operations, but the smaller operations are
-  /// not set.  This occurs only rarely in practice, for targets that don't have
-  /// 32-bit or larger integer registers.
-  bool NeedsAnotherIteration;
+  TargetLowering::ValueTypeActionImpl ValueTypeActions;
 
   /// LegalizedNodes - For nodes that are of legal width, and that have more
   /// than one use, this map indicates what regularized operand to use.  This
@@ -70,12 +74,21 @@ class SelectionDAGLegalize {
   /// us to avoid promoting the same thing more than once.
   std::map<SDOperand, SDOperand> PromotedNodes;
 
-  /// ExpandedNodes - For nodes that need to be expanded, and which have more
-  /// than one use, this map indicates which which operands are the expanded
-  /// version of the input.  This allows us to avoid expanding the same node
-  /// more than once.
+  /// ExpandedNodes - For nodes that need to be expanded this map indicates
+  /// which which operands are the expanded version of the input.  This allows
+  /// us to avoid expanding the same node more than once.
   std::map<SDOperand, std::pair<SDOperand, SDOperand> > ExpandedNodes;
 
+  /// SplitNodes - For vector nodes that need to be split, this map indicates
+  /// which which operands are the split version of the input.  This allows us
+  /// to avoid splitting the same node more than once.
+  std::map<SDOperand, std::pair<SDOperand, SDOperand> > SplitNodes;
+  
+  /// PackedNodes - For nodes that need to be packed from MVT::Vector types to
+  /// concrete packed types, this contains the mapping of ones we have already
+  /// processed to the result.
+  std::map<SDOperand, SDOperand> PackedNodes;
+  
   void AddLegalizedOperand(SDOperand From, SDOperand To) {
     LegalizedNodes.insert(std::make_pair(From, To));
     // If someone requests legalization of the new node, return itself.
@@ -93,23 +106,11 @@ public:
 
   SelectionDAGLegalize(SelectionDAG &DAG);
 
-  /// Run - While there is still lowering to do, perform a pass over the DAG.
-  /// Most regularization can be done in a single pass, but targets that require
-  /// large values to be split into registers multiple times (e.g. i64 -> 4x
-  /// i16) require iteration for these values (the first iteration will demote
-  /// to i32, the second will demote to i16).
-  void Run() {
-    do {
-      NeedsAnotherIteration = false;
-      LegalizeDAG();
-    } while (NeedsAnotherIteration);
-  }
-
   /// getTypeAction - Return how we should legalize values of this type, either
   /// it is already legal or we need to expand it into multiple registers of
   /// smaller integer type, or we need to promote it to a larger type.
   LegalizeAction getTypeAction(MVT::ValueType VT) const {
-    return (LegalizeAction)((ValueTypeActions >> (2*VT)) & 3);
+    return (LegalizeAction)ValueTypeActions.getTypeAction(VT);
   }
 
   /// isTypeLegal - Return true if this type is legal on this target.
@@ -118,19 +119,56 @@ public:
     return getTypeAction(VT) == Legal;
   }
 
-private:
   void LegalizeDAG();
 
+private:
+  /// HandleOp - Legalize, Promote, Expand or Pack the specified operand as
+  /// appropriate for its type.
+  void HandleOp(SDOperand Op);
+    
+  /// LegalizeOp - We know that the specified value has a legal type.
+  /// Recursively ensure that the operands have legal types, then return the
+  /// result.
   SDOperand LegalizeOp(SDOperand O);
-  void ExpandOp(SDOperand O, SDOperand &Lo, SDOperand &Hi);
+  
+  /// PromoteOp - Given an operation that produces a value in an invalid type,
+  /// promote it to compute the value into a larger type.  The produced value
+  /// will have the correct bits for the low portion of the register, but no
+  /// guarantee is made about the top bits: it may be zero, sign-extended, or
+  /// garbage.
   SDOperand PromoteOp(SDOperand O);
 
+  /// ExpandOp - Expand the specified SDOperand into its two component pieces
+  /// Lo&Hi.  Note that the Op MUST be an expanded type.  As a result of this,
+  /// the LegalizeNodes map is filled in for any results that are not expanded,
+  /// the ExpandedNodes map is filled in for any results that are expanded, and
+  /// the Lo/Hi values are returned.   This applies to integer types and Vector
+  /// types.
+  void ExpandOp(SDOperand O, SDOperand &Lo, SDOperand &Hi);
+
+  /// SplitVectorOp - Given an operand of MVT::Vector type, break it down into
+  /// two smaller values of MVT::Vector type.
+  void SplitVectorOp(SDOperand O, SDOperand &Lo, SDOperand &Hi);
+  
+  /// PackVectorOp - Given an operand of MVT::Vector type, convert it into the
+  /// equivalent operation that returns a packed value (e.g. MVT::V4F32).  When
+  /// this is called, we know that PackedVT is the right type for the result and
+  /// we know that this type is legal for the target.
+  SDOperand PackVectorOp(SDOperand O, MVT::ValueType PackedVT);
+  
+  bool LegalizeAllNodesNotLeadingTo(SDNode *N, SDNode *Dest);
+
+  void LegalizeSetCCOperands(SDOperand &LHS, SDOperand &RHS, SDOperand &CC);
+    
+  SDOperand CreateStackTemporary(MVT::ValueType VT);
+
   SDOperand ExpandLibCall(const char *Name, SDNode *Node,
                           SDOperand &Hi);
   SDOperand ExpandIntToFP(bool isSigned, MVT::ValueType DestTy,
                           SDOperand Source);
 
   SDOperand ExpandBIT_CONVERT(MVT::ValueType DestVT, SDOperand SrcOp);
+  SDOperand ExpandBUILD_VECTOR(SDNode *Node);
   SDOperand ExpandLegalINT_TO_FP(bool isSigned,
                                  SDOperand LegalOp,
                                  MVT::ValueType DestVT);
@@ -139,14 +177,12 @@ private:
   SDOperand PromoteLegalFP_TO_INT(SDOperand LegalOp, MVT::ValueType DestVT,
                                   bool isSigned);
 
+  SDOperand ExpandBSWAP(SDOperand Op);
+  SDOperand ExpandBitCount(unsigned Opc, SDOperand Op);
   bool ExpandShift(unsigned Opc, SDOperand Op, SDOperand Amt,
                    SDOperand &Lo, SDOperand &Hi);
   void ExpandShiftParts(unsigned NodeOp, SDOperand Op, SDOperand Amt,
                         SDOperand &Lo, SDOperand &Hi);
-  void ExpandByParts(unsigned NodeOp, SDOperand LHS, SDOperand RHS,
-                     SDOperand &Lo, SDOperand &Hi);
-
-  void SpliceCallInto(const SDOperand &CallResult, SDNode *OutChain);
 
   SDOperand getIntPtrConstant(uint64_t Val) {
     return DAG.getConstant(Val, TLI.getPointerTy());
@@ -154,12 +190,19 @@ private:
 };
 }
 
+/// getScalarizedOpcode - Return the scalar opcode that corresponds to the
+/// specified vector opcode.
 static unsigned getScalarizedOpcode(unsigned VecOp, MVT::ValueType VT) {
   switch (VecOp) {
   default: assert(0 && "Don't know how to scalarize this opcode!");
-  case ISD::VADD: return MVT::isInteger(VT) ? ISD::ADD : ISD::FADD;
-  case ISD::VSUB: return MVT::isInteger(VT) ? ISD::SUB : ISD::FSUB;
-  case ISD::VMUL: return MVT::isInteger(VT) ? ISD::MUL : ISD::FMUL;
+  case ISD::VADD:  return MVT::isInteger(VT) ? ISD::ADD : ISD::FADD;
+  case ISD::VSUB:  return MVT::isInteger(VT) ? ISD::SUB : ISD::FSUB;
+  case ISD::VMUL:  return MVT::isInteger(VT) ? ISD::MUL : ISD::FMUL;
+  case ISD::VSDIV: return MVT::isInteger(VT) ? ISD::SDIV: ISD::FDIV;
+  case ISD::VUDIV: return MVT::isInteger(VT) ? ISD::UDIV: ISD::FDIV;
+  case ISD::VAND:  return MVT::isInteger(VT) ? ISD::AND : 0;
+  case ISD::VOR:   return MVT::isInteger(VT) ? ISD::OR  : 0;
+  case ISD::VXOR:  return MVT::isInteger(VT) ? ISD::XOR : 0;
   }
 }
 
@@ -170,223 +213,6 @@ SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag)
          "Too many value types for ValueTypeActions to hold!");
 }
 
-/// ExpandLegalINT_TO_FP - This function is responsible for legalizing a
-/// INT_TO_FP operation of the specified operand when the target requests that
-/// we expand it.  At this point, we know that the result and operand types are
-/// legal for the target.
-SDOperand SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
-                                                     SDOperand Op0,
-                                                     MVT::ValueType DestVT) {
-  if (Op0.getValueType() == MVT::i32) {
-    // simple 32-bit [signed|unsigned] integer to float/double expansion
-    
-    // get the stack frame index of a 8 byte buffer
-    MachineFunction &MF = DAG.getMachineFunction();
-    int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
-    // get address of 8 byte buffer
-    SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
-    // word offset constant for Hi/Lo address computation
-    SDOperand WordOff = DAG.getConstant(sizeof(int), TLI.getPointerTy());
-    // set up Hi and Lo (into buffer) address based on endian
-    SDOperand Hi, Lo;
-    if (TLI.isLittleEndian()) {
-      Hi = DAG.getNode(ISD::ADD, TLI.getPointerTy(), StackSlot, WordOff);
-      Lo = StackSlot;
-    } else {
-      Hi = StackSlot;
-      Lo = DAG.getNode(ISD::ADD, TLI.getPointerTy(), StackSlot, WordOff);
-    }
-    // if signed map to unsigned space
-    SDOperand Op0Mapped;
-    if (isSigned) {
-      // constant used to invert sign bit (signed to unsigned mapping)
-      SDOperand SignBit = DAG.getConstant(0x80000000u, MVT::i32);
-      Op0Mapped = DAG.getNode(ISD::XOR, MVT::i32, Op0, SignBit);
-    } else {
-      Op0Mapped = Op0;
-    }
-    // store the lo of the constructed double - based on integer input
-    SDOperand Store1 = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
-                                   Op0Mapped, Lo, DAG.getSrcValue(NULL));
-    // initial hi portion of constructed double
-    SDOperand InitialHi = DAG.getConstant(0x43300000u, MVT::i32);
-    // store the hi of the constructed double - biased exponent
-    SDOperand Store2 = DAG.getNode(ISD::STORE, MVT::Other, Store1,
-                                   InitialHi, Hi, DAG.getSrcValue(NULL));
-    // load the constructed double
-    SDOperand Load = DAG.getLoad(MVT::f64, Store2, StackSlot,
-                               DAG.getSrcValue(NULL));
-    // FP constant to bias correct the final result
-    SDOperand Bias = DAG.getConstantFP(isSigned ?
-                                            BitsToDouble(0x4330000080000000ULL)
-                                          : BitsToDouble(0x4330000000000000ULL),
-                                     MVT::f64);
-    // subtract the bias
-    SDOperand Sub = DAG.getNode(ISD::FSUB, MVT::f64, Load, Bias);
-    // final result
-    SDOperand Result;
-    // handle final rounding
-    if (DestVT == MVT::f64) {
-      // do nothing
-      Result = Sub;
-    } else {
-     // if f32 then cast to f32
-      Result = DAG.getNode(ISD::FP_ROUND, MVT::f32, Sub);
-    }
-    return LegalizeOp(Result);
-  }
-  assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet");
-  SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0);
-
-  SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultTy(), Op0,
-                                   DAG.getConstant(0, Op0.getValueType()),
-                                   ISD::SETLT);
-  SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
-  SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
-                                    SignSet, Four, Zero);
-
-  // If the sign bit of the integer is set, the large number will be treated
-  // as a negative number.  To counteract this, the dynamic code adds an
-  // offset depending on the data type.
-  uint64_t FF;
-  switch (Op0.getValueType()) {
-  default: assert(0 && "Unsupported integer type!");
-  case MVT::i8 : FF = 0x43800000ULL; break;  // 2^8  (as a float)
-  case MVT::i16: FF = 0x47800000ULL; break;  // 2^16 (as a float)
-  case MVT::i32: FF = 0x4F800000ULL; break;  // 2^32 (as a float)
-  case MVT::i64: FF = 0x5F800000ULL; break;  // 2^64 (as a float)
-  }
-  if (TLI.isLittleEndian()) FF <<= 32;
-  static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF);
-
-  SDOperand CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy());
-  CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
-  SDOperand FudgeInReg;
-  if (DestVT == MVT::f32)
-    FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx,
-                             DAG.getSrcValue(NULL));
-  else {
-    assert(DestVT == MVT::f64 && "Unexpected conversion");
-    FudgeInReg = LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64,
-                                           DAG.getEntryNode(), CPIdx,
-                                           DAG.getSrcValue(NULL), MVT::f32));
-  }
-
-  return LegalizeOp(DAG.getNode(ISD::FADD, DestVT, Tmp1, FudgeInReg));
-}
-
-/// PromoteLegalINT_TO_FP - This function is responsible for legalizing a
-/// *INT_TO_FP operation of the specified operand when the target requests that
-/// we promote it.  At this point, we know that the result and operand types are
-/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP
-/// operation that takes a larger input.
-SDOperand SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDOperand LegalOp,
-                                                      MVT::ValueType DestVT,
-                                                      bool isSigned) {
-  // First step, figure out the appropriate *INT_TO_FP operation to use.
-  MVT::ValueType NewInTy = LegalOp.getValueType();
-
-  unsigned OpToUse = 0;
-
-  // Scan for the appropriate larger type to use.
-  while (1) {
-    NewInTy = (MVT::ValueType)(NewInTy+1);
-    assert(MVT::isInteger(NewInTy) && "Ran out of possibilities!");
-
-    // If the target supports SINT_TO_FP of this type, use it.
-    switch (TLI.getOperationAction(ISD::SINT_TO_FP, NewInTy)) {
-      default: break;
-      case TargetLowering::Legal:
-        if (!TLI.isTypeLegal(NewInTy))
-          break;  // Can't use this datatype.
-        // FALL THROUGH.
-      case TargetLowering::Custom:
-        OpToUse = ISD::SINT_TO_FP;
-        break;
-    }
-    if (OpToUse) break;
-    if (isSigned) continue;
-
-    // If the target supports UINT_TO_FP of this type, use it.
-    switch (TLI.getOperationAction(ISD::UINT_TO_FP, NewInTy)) {
-      default: break;
-      case TargetLowering::Legal:
-        if (!TLI.isTypeLegal(NewInTy))
-          break;  // Can't use this datatype.
-        // FALL THROUGH.
-      case TargetLowering::Custom:
-        OpToUse = ISD::UINT_TO_FP;
-        break;
-    }
-    if (OpToUse) break;
-
-    // Otherwise, try a larger type.
-  }
-
-  // Okay, we found the operation and type to use.  Zero extend our input to the
-  // desired type then run the operation on it.
-  SDOperand N = DAG.getNode(OpToUse, DestVT,
-                     DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
-                                 NewInTy, LegalOp));
-  // Make sure to legalize any nodes we create here.
-  return LegalizeOp(N);
-}
-
-/// PromoteLegalFP_TO_INT - This function is responsible for legalizing a
-/// FP_TO_*INT operation of the specified operand when the target requests that
-/// we promote it.  At this point, we know that the result and operand types are
-/// legal for the target, and that there is a legal FP_TO_UINT or FP_TO_SINT
-/// operation that returns a larger result.
-SDOperand SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDOperand LegalOp,
-                                                      MVT::ValueType DestVT,
-                                                      bool isSigned) {
-  // First step, figure out the appropriate FP_TO*INT operation to use.
-  MVT::ValueType NewOutTy = DestVT;
-
-  unsigned OpToUse = 0;
-
-  // Scan for the appropriate larger type to use.
-  while (1) {
-    NewOutTy = (MVT::ValueType)(NewOutTy+1);
-    assert(MVT::isInteger(NewOutTy) && "Ran out of possibilities!");
-
-    // If the target supports FP_TO_SINT returning this type, use it.
-    switch (TLI.getOperationAction(ISD::FP_TO_SINT, NewOutTy)) {
-    default: break;
-    case TargetLowering::Legal:
-      if (!TLI.isTypeLegal(NewOutTy))
-        break;  // Can't use this datatype.
-      // FALL THROUGH.
-    case TargetLowering::Custom:
-      OpToUse = ISD::FP_TO_SINT;
-      break;
-    }
-    if (OpToUse) break;
-
-    // If the target supports FP_TO_UINT of this type, use it.
-    switch (TLI.getOperationAction(ISD::FP_TO_UINT, NewOutTy)) {
-    default: break;
-    case TargetLowering::Legal:
-      if (!TLI.isTypeLegal(NewOutTy))
-        break;  // Can't use this datatype.
-      // FALL THROUGH.
-    case TargetLowering::Custom:
-      OpToUse = ISD::FP_TO_UINT;
-      break;
-    }
-    if (OpToUse) break;
-
-    // Otherwise, try a larger type.
-  }
-
-  // Okay, we found the operation and type to use.  Truncate the result of the
-  // extended FP_TO_*INT operation to the desired size.
-  SDOperand N = DAG.getNode(ISD::TRUNCATE, DestVT,
-                            DAG.getNode(OpToUse, NewOutTy, LegalOp));
-  // Make sure to legalize any nodes we create here in the next pass.
-  return LegalizeOp(N);
-}
-
 /// ComputeTopDownOrdering - Add the specified node to the Order list if it has
 /// not been visited yet and if all of its operands have already been visited.
 static void ComputeTopDownOrdering(SDNode *N, std::vector<SDNode*> &Order,
@@ -409,6 +235,9 @@ static void ComputeTopDownOrdering(SDNode *N, std::vector<SDNode*> &Order,
 
 
 void SelectionDAGLegalize::LegalizeDAG() {
+  LastCALLSEQ_END = DAG.getEntryNode();
+  IsLegalizingCall = false;
+  
   // The legalize process is inherently a bottom-up recursive process (users
   // legalize their uses before themselves).  Given infinite stack space, we
   // could just start legalizing on the root and traverse the whole graph.  In
@@ -434,23 +263,8 @@ void SelectionDAGLegalize::LegalizeDAG() {
          "Error: DAG is cyclic!");
   Visited.clear();
   
-  for (unsigned i = 0, e = Order.size(); i != e; ++i) {
-    SDNode *N = Order[i];
-    switch (getTypeAction(N->getValueType(0))) {
-    default: assert(0 && "Bad type action!");
-    case Legal:
-      LegalizeOp(SDOperand(N, 0));
-      break;
-    case Promote:
-      PromoteOp(SDOperand(N, 0));
-      break;
-    case Expand: {
-      SDOperand X, Y;
-      ExpandOp(SDOperand(N, 0), X, Y);
-      break;
-    }
-    }
-  }
+  for (unsigned i = 0, e = Order.size(); i != e; ++i)
+    HandleOp(SDOperand(Order[i], 0));
 
   // Finally, it's possible the root changed.  Get the new root.
   SDOperand OldRoot = DAG.getRoot();
@@ -460,11 +274,153 @@ void SelectionDAGLegalize::LegalizeDAG() {
   ExpandedNodes.clear();
   LegalizedNodes.clear();
   PromotedNodes.clear();
+  SplitNodes.clear();
+  PackedNodes.clear();
 
   // Remove dead nodes now.
   DAG.RemoveDeadNodes(OldRoot.Val);
 }
 
+
+/// FindCallEndFromCallStart - Given a chained node that is part of a call
+/// sequence, find the CALLSEQ_END node that terminates the call sequence.
+static SDNode *FindCallEndFromCallStart(SDNode *Node) {
+  if (Node->getOpcode() == ISD::CALLSEQ_END)
+    return Node;
+  if (Node->use_empty())
+    return 0;   // No CallSeqEnd
+  
+  // The chain is usually at the end.
+  SDOperand TheChain(Node, Node->getNumValues()-1);
+  if (TheChain.getValueType() != MVT::Other) {
+    // Sometimes it's at the beginning.
+    TheChain = SDOperand(Node, 0);
+    if (TheChain.getValueType() != MVT::Other) {
+      // Otherwise, hunt for it.
+      for (unsigned i = 1, e = Node->getNumValues(); i != e; ++i)
+        if (Node->getValueType(i) == MVT::Other) {
+          TheChain = SDOperand(Node, i);
+          break;
+        }
+          
+      // Otherwise, we walked into a node without a chain.  
+      if (TheChain.getValueType() != MVT::Other)
+        return 0;
+    }
+  }
+  
+  for (SDNode::use_iterator UI = Node->use_begin(),
+       E = Node->use_end(); UI != E; ++UI) {
+    
+    // Make sure to only follow users of our token chain.
+    SDNode *User = *UI;
+    for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i)
+      if (User->getOperand(i) == TheChain)
+        if (SDNode *Result = FindCallEndFromCallStart(User))
+          return Result;
+  }
+  return 0;
+}
+
+/// FindCallStartFromCallEnd - Given a chained node that is part of a call 
+/// sequence, find the CALLSEQ_START node that initiates the call sequence.
+static SDNode *FindCallStartFromCallEnd(SDNode *Node) {
+  assert(Node && "Didn't find callseq_start for a call??");
+  if (Node->getOpcode() == ISD::CALLSEQ_START) return Node;
+  
+  assert(Node->getOperand(0).getValueType() == MVT::Other &&
+         "Node doesn't have a token chain argument!");
+  return FindCallStartFromCallEnd(Node->getOperand(0).Val);
+}
+
+/// LegalizeAllNodesNotLeadingTo - Recursively walk the uses of N, looking to
+/// see if any uses can reach Dest.  If no dest operands can get to dest, 
+/// legalize them, legalize ourself, and return false, otherwise, return true.
+bool SelectionDAGLegalize::LegalizeAllNodesNotLeadingTo(SDNode *N, 
+                                                        SDNode *Dest) {
+  if (N == Dest) return true;  // N certainly leads to Dest :)
+  
+  // If the first result of this node has been already legalized, then it cannot
+  // reach N.
+  switch (getTypeAction(N->getValueType(0))) {
+  case Legal: 
+    if (LegalizedNodes.count(SDOperand(N, 0))) return false;
+    break;
+  case Promote:
+    if (PromotedNodes.count(SDOperand(N, 0))) return false;
+    break;
+  case Expand:
+    if (ExpandedNodes.count(SDOperand(N, 0))) return false;
+    break;
+  }
+  
+  // Okay, this node has not already been legalized.  Check and legalize all
+  // operands.  If none lead to Dest, then we can legalize this node.
+  bool OperandsLeadToDest = false;
+  for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i)
+    OperandsLeadToDest |=     // If an operand leads to Dest, so do we.
+      LegalizeAllNodesNotLeadingTo(N->getOperand(i).Val, Dest);
+
+  if (OperandsLeadToDest) return true;
+
+  // Okay, this node looks safe, legalize it and return false.
+  switch (getTypeAction(N->getValueType(0))) {
+  case Legal:
+    LegalizeOp(SDOperand(N, 0));
+    break;
+  case Promote:
+    PromoteOp(SDOperand(N, 0));
+    break;
+  case Expand: {
+    SDOperand X, Y;
+    ExpandOp(SDOperand(N, 0), X, Y);
+    break;
+  }
+  }
+  return false;
+}
+
+/// HandleOp - Legalize, Promote, Expand or Pack the specified operand as
+/// appropriate for its type.
+void SelectionDAGLegalize::HandleOp(SDOperand Op) {
+  switch (getTypeAction(Op.getValueType())) {
+  default: assert(0 && "Bad type action!");
+  case Legal:   LegalizeOp(Op); break;
+  case Promote: PromoteOp(Op);  break;
+  case Expand:
+    if (Op.getValueType() != MVT::Vector) {
+      SDOperand X, Y;
+      ExpandOp(Op, X, Y);
+    } else {
+      SDNode *N = Op.Val;
+      unsigned NumOps = N->getNumOperands();
+      unsigned NumElements =
+        cast<ConstantSDNode>(N->getOperand(NumOps-2))->getValue();
+      MVT::ValueType EVT = cast<VTSDNode>(N->getOperand(NumOps-1))->getVT();
+      MVT::ValueType PackedVT = getVectorType(EVT, NumElements);
+      if (PackedVT != MVT::Other && TLI.isTypeLegal(PackedVT)) {
+        // In the common case, this is a legal vector type, convert it to the
+        // packed operation and type now.
+        PackVectorOp(Op, PackedVT);
+      } else if (NumElements == 1) {
+        // Otherwise, if this is a single element vector, convert it to a
+        // scalar operation.
+        PackVectorOp(Op, EVT);
+      } else {
+        // Otherwise, this is a multiple element vector that isn't supported.
+        // Split it in half and legalize both parts.
+        SDOperand X, Y;
+        SplitVectorOp(Op, X, Y);
+      }
+    }
+    break;
+  }
+}
+
+
+/// LegalizeOp - We know that the specified value has a legal type.
+/// Recursively ensure that the operands have legal types, then return the
+/// result.
 SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
   assert(isTypeLegal(Op.getValueType()) &&
          "Caller should expand or promote operands that are not legal!");
@@ -474,19 +430,10 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
   // register on this target, make sure to expand or promote them.
   if (Node->getNumValues() > 1) {
     for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
-      switch (getTypeAction(Node->getValueType(i))) {
-      case Legal: break;  // Nothing to do.
-      case Expand: {
-        SDOperand T1, T2;
-        ExpandOp(Op.getValue(i), T1, T2);
+      if (getTypeAction(Node->getValueType(i)) != Legal) {
+        HandleOp(Op.getValue(i));
         assert(LegalizedNodes.count(Op) &&
-               "Expansion didn't add legal operands!");
-        return LegalizedNodes[Op];
-      }
-      case Promote:
-        PromoteOp(Op.getValue(i));
-        assert(LegalizedNodes.count(Op) &&
-               "Expansion didn't add legal operands!");
+               "Handling didn't add legal operands!");
         return LegalizedNodes[Op];
       }
   }
@@ -497,10 +444,28 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
   if (I != LegalizedNodes.end()) return I->second;
 
   SDOperand Tmp1, Tmp2, Tmp3, Tmp4;
-
   SDOperand Result = Op;
-
+  bool isCustom = false;
+  
   switch (Node->getOpcode()) {
+  case ISD::FrameIndex:
+  case ISD::EntryToken:
+  case ISD::Register:
+  case ISD::BasicBlock:
+  case ISD::TargetFrameIndex:
+  case ISD::TargetConstant:
+  case ISD::TargetConstantFP:
+  case ISD::TargetConstantPool:
+  case ISD::TargetGlobalAddress:
+  case ISD::TargetExternalSymbol:
+  case ISD::VALUETYPE:
+  case ISD::SRCVALUE:
+  case ISD::STRING:
+  case ISD::CONDCODE:
+    // Primitives must all be legal.
+    assert(TLI.isOperationLegal(Node->getValueType(0), Node->getValueType(0)) &&
+           "This must be legal!");
+    break;
   default:
     if (Node->getOpcode() >= ISD::BUILTIN_OP_END) {
       // If this is a target node, legalize it by legalizing the operands then
@@ -528,62 +493,41 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     std::cerr << "NODE: "; Node->dump(); std::cerr << "\n";
     assert(0 && "Do not know how to legalize this operator!");
     abort();
-  case ISD::EntryToken:
-  case ISD::FrameIndex:
-  case ISD::TargetFrameIndex:
-  case ISD::Register:
-  case ISD::TargetConstant:
-  case ISD::TargetConstantPool:
   case ISD::GlobalAddress:
-  case ISD::TargetGlobalAddress:
   case ISD::ExternalSymbol:
-  case ISD::TargetExternalSymbol:
   case ISD::ConstantPool:           // Nothing to do.
-  case ISD::BasicBlock:
-  case ISD::CONDCODE:
-  case ISD::VALUETYPE:
-  case ISD::SRCVALUE:
-  case ISD::STRING:
     switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
     default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Custom: {
-      SDOperand Tmp = TLI.LowerOperation(Op, DAG);
-      if (Tmp.Val) {
-        Result = LegalizeOp(Tmp);
-        break;
-      }
-    } // FALLTHROUGH if the target doesn't want to lower this op after all.
+    case TargetLowering::Custom:
+      Tmp1 = TLI.LowerOperation(Op, DAG);
+      if (Tmp1.Val) Result = Tmp1;
+      // FALLTHROUGH if the target doesn't want to lower this op after all.
     case TargetLowering::Legal:
-      assert(isTypeLegal(Node->getValueType(0)) && "This must be legal!");
       break;
     }
     break;
   case ISD::AssertSext:
   case ISD::AssertZext:
     Tmp1 = LegalizeOp(Node->getOperand(0));
-    if (Tmp1 != Node->getOperand(0))
-      Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1,
-                           Node->getOperand(1));
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1));
     break;
   case ISD::MERGE_VALUES:
-    return LegalizeOp(Node->getOperand(Op.ResNo));
+    // Legalize eliminates MERGE_VALUES nodes.
+    Result = Node->getOperand(Op.ResNo);
+    break;
   case ISD::CopyFromReg:
     Tmp1 = LegalizeOp(Node->getOperand(0));
     Result = Op.getValue(0);
     if (Node->getNumValues() == 2) {
-      if (Tmp1 != Node->getOperand(0))
-        Result = DAG.getCopyFromReg(Tmp1, 
-                            cast<RegisterSDNode>(Node->getOperand(1))->getReg(),
-                                    Node->getValueType(0));
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1));
     } else {
       assert(Node->getNumValues() == 3 && "Invalid copyfromreg!");
-      if (Node->getNumOperands() == 3)
+      if (Node->getNumOperands() == 3) {
         Tmp2 = LegalizeOp(Node->getOperand(2));
-      if (Tmp1 != Node->getOperand(0) ||
-          (Node->getNumOperands() == 3 && Tmp2 != Node->getOperand(2)))
-        Result = DAG.getCopyFromReg(Tmp1, 
-                            cast<RegisterSDNode>(Node->getOperand(1))->getReg(),
-                                    Node->getValueType(0), Tmp2);
+        Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1),Tmp2);
+      } else {
+        Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1));
+      }
       AddLegalizedOperand(Op.getValue(2), Result.getValue(2));
     }
     // Since CopyFromReg produces two values, make sure to remember that we
@@ -596,7 +540,6 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     switch (TLI.getOperationAction(ISD::UNDEF, VT)) {
     default: assert(0 && "This action is not supported yet!");
     case TargetLowering::Expand:
-    case TargetLowering::Promote:
       if (MVT::isInteger(VT))
         Result = DAG.getConstant(0, VT);
       else if (MVT::isFloatingPoint(VT))
@@ -618,23 +561,37 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     case TargetLowering::Promote:
     default: assert(0 && "This action is not supported yet!");
     case TargetLowering::Expand: {
-      if (TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other)) {
-        MachineDebugInfo &DebugInfo = DAG.getMachineFunction().getDebugInfo();
-        std::vector<SDOperand> Ops;
-        Ops.push_back(Tmp1);  // chain
-        Ops.push_back(Node->getOperand(1));  // line #
-        Ops.push_back(Node->getOperand(2));  // col #
-        const std::string &fname =
+      MachineDebugInfo *DebugInfo = DAG.getMachineDebugInfo();
+      bool useDEBUG_LOC = TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other);
+      bool useDEBUG_LABEL = TLI.isOperationLegal(ISD::DEBUG_LABEL, MVT::Other);
+      
+      if (DebugInfo && (useDEBUG_LOC || useDEBUG_LABEL)) {
+        const std::string &FName =
           cast<StringSDNode>(Node->getOperand(3))->getValue();
-        const std::string &dirname = 
+        const std::string &DirName = 
           cast<StringSDNode>(Node->getOperand(4))->getValue();
-        unsigned id = DebugInfo.RecordSource(fname, dirname);
-        Ops.push_back(DAG.getConstant(id, MVT::i32));  // source file id
-        Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Ops);
+        unsigned SrcFile = DebugInfo->RecordSource(DirName, FName);
+
+        std::vector<SDOperand> Ops;
+        Ops.push_back(Tmp1);  // chain
+        SDOperand LineOp = Node->getOperand(1);
+        SDOperand ColOp = Node->getOperand(2);
+        
+        if (useDEBUG_LOC) {
+          Ops.push_back(LineOp);  // line #
+          Ops.push_back(ColOp);  // col #
+          Ops.push_back(DAG.getConstant(SrcFile, MVT::i32));  // source file id
+          Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Ops);
+        } else {
+          unsigned Line = cast<ConstantSDNode>(LineOp)->getValue();
+          unsigned Col = cast<ConstantSDNode>(ColOp)->getValue();
+          unsigned ID = DebugInfo->RecordLabel(Line, Col, SrcFile);
+          Ops.push_back(DAG.getConstant(ID, MVT::i32));
+          Result = DAG.getNode(ISD::DEBUG_LABEL, MVT::Other, Ops);
+        }
       } else {
         Result = Tmp1;  // chain
       }
-      Result = LegalizeOp(Result);  // Relegalize new nodes.
       break;
     }
     case TargetLowering::Legal:
@@ -652,7 +609,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         }
         Ops.push_back(Node->getOperand(3));  // filename must be legal.
         Ops.push_back(Node->getOperand(4));  // working dir # must be legal.
-        Result = DAG.getNode(ISD::LOCATION, MVT::Other, Ops);
+        Result = DAG.UpdateNodeOperands(Result, Ops);
       }
       break;
     }
@@ -661,25 +618,29 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
   case ISD::DEBUG_LOC:
     assert(Node->getNumOperands() == 4 && "Invalid DEBUG_LOC node!");
     switch (TLI.getOperationAction(ISD::DEBUG_LOC, MVT::Other)) {
-    case TargetLowering::Promote:
-    case TargetLowering::Expand:
     default: assert(0 && "This action is not supported yet!");
     case TargetLowering::Legal:
       Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
       Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the line #.
       Tmp3 = LegalizeOp(Node->getOperand(2));  // Legalize the col #.
       Tmp4 = LegalizeOp(Node->getOperand(3));  // Legalize the source file id.
-      
-      if (Tmp1 != Node->getOperand(0) ||
-          Tmp2 != Node->getOperand(1) ||
-          Tmp3 != Node->getOperand(2) ||
-          Tmp4 != Node->getOperand(3)) {
-        Result = DAG.getNode(ISD::DEBUG_LOC,MVT::Other, Tmp1, Tmp2, Tmp3, Tmp4);
-      }
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3, Tmp4);
       break;
     }
     break;    
 
+  case ISD::DEBUG_LABEL:
+    assert(Node->getNumOperands() == 2 && "Invalid DEBUG_LABEL node!");
+    switch (TLI.getOperationAction(ISD::DEBUG_LABEL, MVT::Other)) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Legal:
+      Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
+      Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the label id.
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+      break;
+    }
+    break;
+
   case ISD::Constant:
     // We know we don't need to expand constants here, constants only have one
     // value and we check that it is fine above.
@@ -692,7 +653,6 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     // codegen them.  Targets often have some immediate values that can be
     // efficiently generated into an FP register without a load.  We explicitly
     // leave these constants as ConstantFP nodes for the target to deal with.
-
     ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Node);
 
     // Check to see if this FP immediate is already legal.
@@ -704,13 +664,29 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         break;
       }
 
-    if (!isLegal) {
+    // If this is a legal constant, turn it into a TargetConstantFP node.
+    if (isLegal) {
+      Result = DAG.getTargetConstantFP(CFP->getValue(), CFP->getValueType(0));
+      break;
+    }
+
+    switch (TLI.getOperationAction(ISD::ConstantFP, CFP->getValueType(0))) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Custom:
+      Tmp3 = TLI.LowerOperation(Result, DAG);
+      if (Tmp3.Val) {
+        Result = Tmp3;
+        break;
+      }
+      // FALLTHROUGH
+    case TargetLowering::Expand:
       // Otherwise we need to spill the constant to memory.
       bool Extend = false;
 
-      // If a FP immediate is precise when represented as a float, we put it
-      // into the constant pool as a float, even if it's is statically typed
-      // as a double.
+      // If a FP immediate is precise when represented as a float and if the
+      // target can do an extending load from float to double, we put it into
+      // the constant pool as a float, even if it's is statically typed as a
+      // double.
       MVT::ValueType VT = CFP->getValueType(0);
       bool isDouble = VT == MVT::f64;
       ConstantFP *LLVMC = ConstantFP::get(isDouble ? Type::DoubleTy :
@@ -724,8 +700,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         Extend = true;
       }
 
-      SDOperand CPIdx = 
-        LegalizeOp(DAG.getConstantPool(LLVMC, TLI.getPointerTy()));
+      SDOperand CPIdx = DAG.getConstantPool(LLVMC, TLI.getPointerTy());
       if (Extend) {
         Result = DAG.getExtLoad(ISD::EXTLOAD, MVT::f64, DAG.getEntryNode(),
                                 CPIdx, DAG.getSrcValue(NULL), MVT::f32);
@@ -736,122 +711,359 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     }
     break;
   }
-  case ISD::ConstantVec: {
-    // We assume that vector constants are not legal, and will be immediately
-    // spilled to the constant pool.
-    //
-    // FIXME: revisit this when we have some kind of mechanism by which targets
-    // can decided legality of vector constants, of which there may be very
-    // many.
-    //
-    // Create a ConstantPacked, and put it in the constant pool.
-    std::vector<Constant*> CV;
-    MVT::ValueType VT = Node->getValueType(0);
-    for (unsigned I = 0, E = Node->getNumOperands(); I < E; ++I) {
-      SDOperand OpN = Node->getOperand(I);
-      const Type* OpNTy = MVT::getTypeForValueType(OpN.getValueType());
-      if (MVT::isFloatingPoint(VT))
-        CV.push_back(ConstantFP::get(OpNTy, 
-                                     cast<ConstantFPSDNode>(OpN)->getValue()));
-      else
-        CV.push_back(ConstantUInt::get(OpNTy,
-                                       cast<ConstantSDNode>(OpN)->getValue()));
-    }
-    Constant *CP = ConstantPacked::get(CV);
-    SDOperand CPIdx = LegalizeOp(DAG.getConstantPool(CP, TLI.getPointerTy()));
-    Result = DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, DAG.getSrcValue(NULL));
-    break;
-  }
   case ISD::TokenFactor:
     if (Node->getNumOperands() == 2) {
-      bool Changed = false;
-      SDOperand Op0 = LegalizeOp(Node->getOperand(0));
-      SDOperand Op1 = LegalizeOp(Node->getOperand(1));
-      if (Op0 != Node->getOperand(0) || Op1 != Node->getOperand(1))
-        Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Op0, Op1);
+      Tmp1 = LegalizeOp(Node->getOperand(0));
+      Tmp2 = LegalizeOp(Node->getOperand(1));
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+    } else if (Node->getNumOperands() == 3) {
+      Tmp1 = LegalizeOp(Node->getOperand(0));
+      Tmp2 = LegalizeOp(Node->getOperand(1));
+      Tmp3 = LegalizeOp(Node->getOperand(2));
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
     } else {
       std::vector<SDOperand> Ops;
-      bool Changed = false;
       // Legalize the operands.
-      for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
-        SDOperand Op = Node->getOperand(i);
-        Ops.push_back(LegalizeOp(Op));
-        Changed |= Ops[i] != Op;
+      for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
+        Ops.push_back(LegalizeOp(Node->getOperand(i)));
+      Result = DAG.UpdateNodeOperands(Result, Ops);
+    }
+    break;
+
+  case ISD::BUILD_VECTOR:
+    switch (TLI.getOperationAction(ISD::BUILD_VECTOR, Node->getValueType(0))) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Custom:
+      Tmp3 = TLI.LowerOperation(Result, DAG);
+      if (Tmp3.Val) {
+        Result = Tmp3;
+        break;
+      }
+      // FALLTHROUGH
+    case TargetLowering::Expand:
+      Result = ExpandBUILD_VECTOR(Result.Val);
+      break;
+    }
+    break;
+  case ISD::INSERT_VECTOR_ELT:
+    Tmp1 = LegalizeOp(Node->getOperand(0));  // InVec
+    Tmp2 = LegalizeOp(Node->getOperand(1));  // InVal
+    Tmp3 = LegalizeOp(Node->getOperand(2));  // InEltNo
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
+    
+    switch (TLI.getOperationAction(ISD::INSERT_VECTOR_ELT,
+                                   Node->getValueType(0))) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Legal:
+      break;
+    case TargetLowering::Custom:
+      Tmp3 = TLI.LowerOperation(Result, DAG);
+      if (Tmp3.Val) {
+        Result = Tmp3;
+        break;
+      }
+      // FALLTHROUGH
+    case TargetLowering::Expand: {
+      // If the target doesn't support this, we have to spill the input vector
+      // to a temporary stack slot, update the element, then reload it.  This is
+      // badness.  We could also load the value into a vector register (either
+      // with a "move to register" or "extload into register" instruction, then
+      // permute it into place, if the idx is a constant and if the idx is
+      // supported by the target.
+      assert(0 && "INSERT_VECTOR_ELT expand not supported yet!");
+      break;
+    }
+    }
+    break;
+  case ISD::SCALAR_TO_VECTOR:
+    Tmp1 = LegalizeOp(Node->getOperand(0));  // InVal
+    Result = DAG.UpdateNodeOperands(Result, Tmp1);
+    switch (TLI.getOperationAction(ISD::SCALAR_TO_VECTOR,
+                                   Node->getValueType(0))) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Legal:
+      break;
+    case TargetLowering::Custom:
+      Tmp3 = TLI.LowerOperation(Result, DAG);
+      if (Tmp3.Val) {
+        Result = Tmp3;
+        break;
+      }
+      // FALLTHROUGH
+    case TargetLowering::Expand: {
+      // If the target doesn't support this, store the value to a temporary
+      // stack slot, then EXTLOAD the vector back out.
+      // TODO: If a target doesn't support this, create a stack slot for the
+      // whole vector, then store into it, then load the whole vector.
+      SDOperand StackPtr = 
+        CreateStackTemporary(Node->getOperand(0).getValueType());
+      SDOperand Ch = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+                                 Node->getOperand(0), StackPtr,
+                                 DAG.getSrcValue(NULL));
+      Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0), Ch, StackPtr,
+                              DAG.getSrcValue(NULL),
+                              Node->getOperand(0).getValueType());
+      break;
+    }
+    }
+    break;
+  case ISD::VECTOR_SHUFFLE:
+    assert(TLI.isShuffleLegal(Result.getValueType(), Node->getOperand(2)) &&
+           "vector shuffle should not be created if not legal!");
+    Tmp1 = LegalizeOp(Node->getOperand(0));   // Legalize the input vectors,
+    Tmp2 = LegalizeOp(Node->getOperand(1));   // but not the shuffle mask.
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
+
+    // Allow targets to custom lower the SHUFFLEs they support.
+    if (TLI.getOperationAction(ISD::VECTOR_SHUFFLE, Result.getValueType())
+        == TargetLowering::Custom) {
+      Tmp1 = TLI.LowerOperation(Result, DAG);
+      if (Tmp1.Val) Result = Tmp1;
+    }
+    break;
+  
+  case ISD::EXTRACT_VECTOR_ELT:
+    Tmp1 = LegalizeOp(Node->getOperand(0));
+    Tmp2 = LegalizeOp(Node->getOperand(1));
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+    
+    switch (TLI.getOperationAction(ISD::EXTRACT_VECTOR_ELT,
+                                   Tmp1.getValueType())) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Legal:
+      break;
+    case TargetLowering::Custom:
+      Tmp3 = TLI.LowerOperation(Result, DAG);
+      if (Tmp3.Val) {
+        Result = Tmp3;
+        break;
+      }
+      // FALLTHROUGH
+    case TargetLowering::Expand: {
+      // If the target doesn't support this, store the value to a temporary
+      // stack slot, then LOAD the scalar element back out.
+      SDOperand StackPtr = CreateStackTemporary(Tmp1.getValueType());
+      SDOperand Ch = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+                                 Tmp1, StackPtr, DAG.getSrcValue(NULL));
+      
+      // Add the offset to the index.
+      unsigned EltSize = MVT::getSizeInBits(Result.getValueType())/8;
+      Tmp2 = DAG.getNode(ISD::MUL, Tmp2.getValueType(), Tmp2,
+                         DAG.getConstant(EltSize, Tmp2.getValueType()));
+      StackPtr = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2, StackPtr);
+      
+      Result = DAG.getLoad(Result.getValueType(), Ch, StackPtr,
+                              DAG.getSrcValue(NULL));
+      break;
+    }
+    }
+    break;
+
+  case ISD::VEXTRACT_VECTOR_ELT:
+    // We know that operand #0 is the Vec vector.  If the index is a constant
+    // or if the invec is a supported hardware type, we can use it.  Otherwise,
+    // lower to a store then an indexed load.
+    Tmp1 = Node->getOperand(0);
+    Tmp2 = LegalizeOp(Node->getOperand(1));
+    
+    SDNode *InVal = Tmp1.Val;
+    unsigned NumElems = cast<ConstantSDNode>(*(InVal->op_end()-2))->getValue();
+    MVT::ValueType EVT = cast<VTSDNode>(*(InVal->op_end()-1))->getVT();
+    
+    // Figure out if there is a Packed type corresponding to this Vector
+    // type.  If so, convert to the packed type.
+    MVT::ValueType TVT = MVT::getVectorType(EVT, NumElems);
+    if (TVT != MVT::Other && TLI.isTypeLegal(TVT)) {
+      // Turn this into a packed extract_vector_elt operation.
+      Tmp1 = PackVectorOp(Tmp1, TVT);
+      Result = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, Node->getValueType(0),
+                           Tmp1, Tmp2);
+      break;
+    } else if (NumElems == 1) {
+      // This must be an access of the only element.
+      Result = PackVectorOp(Tmp1, EVT);
+      break;
+    } else if (ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Tmp2)) {
+      SDOperand Lo, Hi;
+      SplitVectorOp(Tmp1, Lo, Hi);
+      if (CIdx->getValue() < NumElems/2) {
+        Tmp1 = Lo;
+      } else {
+        Tmp1 = Hi;
+        Tmp2 = DAG.getConstant(CIdx->getValue() - NumElems/2,
+                               Tmp2.getValueType());
       }
-      if (Changed)
-        Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Ops);
+
+      // It's now an extract from the appropriate high or low part.
+      Result = LegalizeOp(DAG.UpdateNodeOperands(Result, Tmp1, Tmp2));
+    } else {
+      // FIXME: IMPLEMENT STORE/LOAD lowering.
+      assert(0 && "unimp!");
     }
     break;
+    
+  case ISD::CALLSEQ_START: {
+    SDNode *CallEnd = FindCallEndFromCallStart(Node);
+    
+    // Recursively Legalize all of the inputs of the call end that do not lead
+    // to this call start.  This ensures that any libcalls that need be inserted
+    // are inserted *before* the CALLSEQ_START.
+    for (unsigned i = 0, e = CallEnd->getNumOperands(); i != e; ++i)
+      LegalizeAllNodesNotLeadingTo(CallEnd->getOperand(i).Val, Node);
+
+    // Now that we legalized all of the inputs (which may have inserted
+    // libcalls) create the new CALLSEQ_START node.
+    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
 
-  case ISD::CALLSEQ_START:
+    // Merge in the last call, to ensure that this call start after the last
+    // call ended.
+    Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END);
+    Tmp1 = LegalizeOp(Tmp1);
+      
+    // Do not try to legalize the target-specific arguments (#1+).
+    if (Tmp1 != Node->getOperand(0)) {
+      std::vector<SDOperand> Ops(Node->op_begin(), Node->op_end());
+      Ops[0] = Tmp1;
+      Result = DAG.UpdateNodeOperands(Result, Ops);
+    }
+    
+    // Remember that the CALLSEQ_START is legalized.
+    AddLegalizedOperand(Op.getValue(0), Result);
+    if (Node->getNumValues() == 2)    // If this has a flag result, remember it.
+      AddLegalizedOperand(Op.getValue(1), Result.getValue(1));
+    
+    // Now that the callseq_start and all of the non-call nodes above this call
+    // sequence have been legalized, legalize the call itself.  During this 
+    // process, no libcalls can/will be inserted, guaranteeing that no calls
+    // can overlap.
+    assert(!IsLegalizingCall && "Inconsistent sequentialization of calls!");
+    SDOperand InCallSEQ = LastCALLSEQ_END;
+    // Note that we are selecting this call!
+    LastCALLSEQ_END = SDOperand(CallEnd, 0);
+    IsLegalizingCall = true;
+    
+    // Legalize the call, starting from the CALLSEQ_END.
+    LegalizeOp(LastCALLSEQ_END);
+    assert(!IsLegalizingCall && "CALLSEQ_END should have cleared this!");
+    return Result;
+  }
   case ISD::CALLSEQ_END:
+    // If the CALLSEQ_START node hasn't been legalized first, legalize it.  This
+    // will cause this node to be legalized as well as handling libcalls right.
+    if (LastCALLSEQ_END.Val != Node) {
+      LegalizeOp(SDOperand(FindCallStartFromCallEnd(Node), 0));
+      std::map<SDOperand, SDOperand>::iterator I = LegalizedNodes.find(Op);
+      assert(I != LegalizedNodes.end() &&
+             "Legalizing the call start should have legalized this node!");
+      return I->second;
+    }
+    
+    // Otherwise, the call start has been legalized and everything is going 
+    // according to plan.  Just legalize ourselves normally here.
     Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    // Do not try to legalize the target-specific arguments (#1+)
-    Tmp2 = Node->getOperand(0);
-    if (Tmp1 != Tmp2)
-      Node->setAdjCallChain(Tmp1);
-      
-    // Note that we do not create new CALLSEQ_DOWN/UP nodes here.  These
-    // nodes are treated specially and are mutated in place.  This makes the dag
-    // legalization process more efficient and also makes libcall insertion
-    // easier.
-    break;
-  case ISD::DYNAMIC_STACKALLOC:
+    // Do not try to legalize the target-specific arguments (#1+), except for
+    // an optional flag input.
+    if (Node->getOperand(Node->getNumOperands()-1).getValueType() != MVT::Flag){
+      if (Tmp1 != Node->getOperand(0)) {
+        std::vector<SDOperand> Ops(Node->op_begin(), Node->op_end());
+        Ops[0] = Tmp1;
+        Result = DAG.UpdateNodeOperands(Result, Ops);
+      }
+    } else {
+      Tmp2 = LegalizeOp(Node->getOperand(Node->getNumOperands()-1));
+      if (Tmp1 != Node->getOperand(0) ||
+          Tmp2 != Node->getOperand(Node->getNumOperands()-1)) {
+        std::vector<SDOperand> Ops(Node->op_begin(), Node->op_end());
+        Ops[0] = Tmp1;
+        Ops.back() = Tmp2;
+        Result = DAG.UpdateNodeOperands(Result, Ops);
+      }
+    }
+    assert(IsLegalizingCall && "Call sequence imbalance between start/end?");
+    // This finishes up call legalization.
+    IsLegalizingCall = false;
+    
+    // If the CALLSEQ_END node has a flag, remember that we legalized it.
+    AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0));
+    if (Node->getNumValues() == 2)
+      AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
+    return Result.getValue(Op.ResNo);
+  case ISD::DYNAMIC_STACKALLOC: {
     Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
     Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the size.
     Tmp3 = LegalizeOp(Node->getOperand(2));  // Legalize the alignment.
-    if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
-        Tmp3 != Node->getOperand(2)) {
-      std::vector<MVT::ValueType> VTs(Node->value_begin(), Node->value_end());
-      std::vector<SDOperand> Ops;
-      Ops.push_back(Tmp1); Ops.push_back(Tmp2); Ops.push_back(Tmp3);
-      Result = DAG.getNode(ISD::DYNAMIC_STACKALLOC, VTs, Ops);
-    } else
-      Result = Op.getValue(0);
-
-    // Since this op produces two values, make sure to remember that we
-    // legalized both of them.
-    AddLegalizedOperand(SDOperand(Node, 0), Result);
-    AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
-    return Result.getValue(Op.ResNo);
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
 
-  case ISD::TAILCALL:
-  case ISD::CALL: {
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the callee.
-
-    bool Changed = false;
-    std::vector<SDOperand> Ops;
-    for (unsigned i = 2, e = Node->getNumOperands(); i != e; ++i) {
-      Ops.push_back(LegalizeOp(Node->getOperand(i)));
-      Changed |= Ops.back() != Node->getOperand(i);
+    Tmp1 = Result.getValue(0);
+    Tmp2 = Result.getValue(1);
+    switch (TLI.getOperationAction(Node->getOpcode(),
+                                   Node->getValueType(0))) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Expand: {
+      unsigned SPReg = TLI.getStackPointerRegisterToSaveRestore();
+      assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and"
+             " not tell us which reg is the stack pointer!");
+      SDOperand Chain = Tmp1.getOperand(0);
+      SDOperand Size  = Tmp2.getOperand(1);
+      SDOperand SP = DAG.getCopyFromReg(Chain, SPReg, Node->getValueType(0));
+      Tmp1 = DAG.getNode(ISD::SUB, Node->getValueType(0), SP, Size);    // Value
+      Tmp2 = DAG.getCopyToReg(SP.getValue(1), SPReg, Tmp1);      // Output chain
+      Tmp1 = LegalizeOp(Tmp1);
+      Tmp2 = LegalizeOp(Tmp2);
+      break;
     }
-
-    if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) || Changed) {
-      std::vector<MVT::ValueType> RetTyVTs;
-      RetTyVTs.reserve(Node->getNumValues());
-      for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
-        RetTyVTs.push_back(Node->getValueType(i));
-      Result = SDOperand(DAG.getCall(RetTyVTs, Tmp1, Tmp2, Ops,
-                                     Node->getOpcode() == ISD::TAILCALL), 0);
-    } else {
-      Result = Result.getValue(0);
+    case TargetLowering::Custom:
+      Tmp3 = TLI.LowerOperation(Tmp1, DAG);
+      if (Tmp3.Val) {
+        Tmp1 = LegalizeOp(Tmp3);
+        Tmp2 = LegalizeOp(Tmp3.getValue(1));
+      }
+      break;
+    case TargetLowering::Legal:
+      break;
     }
-    // Since calls produce multiple values, make sure to remember that we
-    // legalized all of them.
-    for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
-      AddLegalizedOperand(SDOperand(Node, i), Result.getValue(i));
-    return Result.getValue(Op.ResNo);
+    // Since this op produce two values, make sure to remember that we
+    // legalized both of them.
+    AddLegalizedOperand(SDOperand(Node, 0), Tmp1);
+    AddLegalizedOperand(SDOperand(Node, 1), Tmp2);
+    return Op.ResNo ? Tmp2 : Tmp1;
   }
+  case ISD::INLINEASM:
+    Tmp1 = LegalizeOp(Node->getOperand(0));   // Legalize Chain.
+    Tmp2 = Node->getOperand(Node->getNumOperands()-1);
+    if (Tmp2.getValueType() == MVT::Flag)     // Legalize Flag if it exists.
+      Tmp2 = Tmp3 = SDOperand(0, 0);
+    else
+      Tmp3 = LegalizeOp(Tmp2);
+    
+    if (Tmp1 != Node->getOperand(0) || Tmp2 != Tmp3) {
+      std::vector<SDOperand> Ops(Node->op_begin(), Node->op_end());
+      Ops[0] = Tmp1;
+      if (Tmp3.Val) Ops.back() = Tmp3;
+      Result = DAG.UpdateNodeOperands(Result, Ops);
+    }
+      
+    // INLINE asm returns a chain and flag, make sure to add both to the map.
+    AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0));
+    AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
+    return Result.getValue(Op.ResNo);
   case ISD::BR:
     Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    if (Tmp1 != Node->getOperand(0))
-      Result = DAG.getNode(ISD::BR, MVT::Other, Tmp1, Node->getOperand(1));
+    // Ensure that libcalls are emitted before a branch.
+    Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END);
+    Tmp1 = LegalizeOp(Tmp1);
+    LastCALLSEQ_END = DAG.getEntryNode();
+    
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1));
     break;
 
   case ISD::BRCOND:
     Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    
+    // Ensure that libcalls are emitted before a return.
+    Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END);
+    Tmp1 = LegalizeOp(Tmp1);
+    LastCALLSEQ_END = DAG.getEntryNode();
+
     switch (getTypeAction(Node->getOperand(1).getValueType())) {
     case Expand: assert(0 && "It's impossible to expand bools");
     case Legal:
@@ -861,9 +1073,17 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       Tmp2 = PromoteOp(Node->getOperand(1));  // Promote the condition.
       break;
     }
+
+    // Basic block destination (Op#2) is always legal.
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
       
     switch (TLI.getOperationAction(ISD::BRCOND, MVT::Other)) {  
     default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Legal: break;
+    case TargetLowering::Custom:
+      Tmp1 = TLI.LowerOperation(Result, DAG);
+      if (Tmp1.Val) Result = Tmp1;
+      break;
     case TargetLowering::Expand:
       // Expand brcond's setcc into its constituent parts and create a BR_CC
       // Node.
@@ -874,171 +1094,49 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       } else {
         // Make sure the condition is either zero or one.  It may have been
         // promoted from something else.
-        Tmp2 = DAG.getZeroExtendInReg(Tmp2, MVT::i1);
+        unsigned NumBits = MVT::getSizeInBits(Tmp2.getValueType());
+        if (!TLI.MaskedValueIsZero(Tmp2, (~0ULL >> (64-NumBits))^1))
+          Tmp2 = DAG.getZeroExtendInReg(Tmp2, MVT::i1);
         
         Result = DAG.getNode(ISD::BR_CC, MVT::Other, Tmp1, 
                              DAG.getCondCode(ISD::SETNE), Tmp2,
                              DAG.getConstant(0, Tmp2.getValueType()),
                              Node->getOperand(2));
       }
-      Result = LegalizeOp(Result);  // Relegalize new nodes.
       break;
-    case TargetLowering::Custom: {
-      SDOperand Tmp =
-        TLI.LowerOperation(DAG.getNode(ISD::BRCOND, Node->getValueType(0),
-                                       Tmp1, Tmp2, Node->getOperand(2)), DAG);
-      if (Tmp.Val) {
-        Result = LegalizeOp(Tmp);
-        break;
-      }
-      // FALLTHROUGH if the target thinks it is legal.
-    }
-    case TargetLowering::Legal:
-      // Basic block destination (Op#2) is always legal.
-      if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1))
-        Result = DAG.getNode(ISD::BRCOND, MVT::Other, Tmp1, Tmp2,
-                             Node->getOperand(2));
-        break;
     }
     break;
   case ISD::BR_CC:
     Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    if (!isTypeLegal(Node->getOperand(2).getValueType())) {
-      Tmp2 = LegalizeOp(DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(),
-                                    Node->getOperand(2),  // LHS
-                                    Node->getOperand(3),  // RHS
-                                    Node->getOperand(1)));
-      // If we get a SETCC back from legalizing the SETCC node we just
-      // created, then use its LHS, RHS, and CC directly in creating a new
-      // node.  Otherwise, select between the true and false value based on
-      // comparing the result of the legalized with zero.
-      if (Tmp2.getOpcode() == ISD::SETCC) {
-        Result = DAG.getNode(ISD::BR_CC, MVT::Other, Tmp1, Tmp2.getOperand(2),
-                             Tmp2.getOperand(0), Tmp2.getOperand(1),
-                             Node->getOperand(4));
-      } else {
-        Result = DAG.getNode(ISD::BR_CC, MVT::Other, Tmp1, 
-                             DAG.getCondCode(ISD::SETNE),
-                             Tmp2, DAG.getConstant(0, Tmp2.getValueType()), 
-                             Node->getOperand(4));
-      }
-      break;
-    }
-
-    Tmp2 = LegalizeOp(Node->getOperand(2));   // LHS
-    Tmp3 = LegalizeOp(Node->getOperand(3));   // RHS
+    // Ensure that libcalls are emitted before a branch.
+    Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END);
+    Tmp1 = LegalizeOp(Tmp1);
+    LastCALLSEQ_END = DAG.getEntryNode();
+    
+    Tmp2 = Node->getOperand(2);              // LHS 
+    Tmp3 = Node->getOperand(3);              // RHS
+    Tmp4 = Node->getOperand(1);              // CC
 
+    LegalizeSetCCOperands(Tmp2, Tmp3, Tmp4);
+    
+    // If we didn't get both a LHS and RHS back from LegalizeSetCCOperands,
+    // the LHS is a legal SETCC itself.  In this case, we need to compare
+    // the result against zero to select between true and false values.
+    if (Tmp3.Val == 0) {
+      Tmp3 = DAG.getConstant(0, Tmp2.getValueType());
+      Tmp4 = DAG.getCondCode(ISD::SETNE);
+    }
+    
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp4, Tmp2, Tmp3, 
+                                    Node->getOperand(4));
+      
     switch (TLI.getOperationAction(ISD::BR_CC, Tmp3.getValueType())) {
     default: assert(0 && "Unexpected action for BR_CC!");
-    case TargetLowering::Custom: {
-      Tmp4 = DAG.getNode(ISD::BR_CC, MVT::Other, Tmp1, Node->getOperand(1),
-                         Tmp2, Tmp3, Node->getOperand(4));
-      Tmp4 = TLI.LowerOperation(Tmp4, DAG);
-      if (Tmp4.Val) {
-        Result = LegalizeOp(Tmp4);
-        break;
-      }
-    } // FALLTHROUGH if the target doesn't want to lower this op after all.
-    case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(2) ||
-          Tmp3 != Node->getOperand(3)) {
-        Result = DAG.getNode(ISD::BR_CC, MVT::Other, Tmp1, Node->getOperand(1),
-                             Tmp2, Tmp3, Node->getOperand(4));
-      }
-      break;
-    }
-    break;
-  case ISD::BRCONDTWOWAY:
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    switch (getTypeAction(Node->getOperand(1).getValueType())) {
-    case Expand: assert(0 && "It's impossible to expand bools");
-    case Legal:
-      Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the condition.
-      break;
-    case Promote:
-      Tmp2 = PromoteOp(Node->getOperand(1));  // Promote the condition.
-      break;
-    }
-    // If this target does not support BRCONDTWOWAY, lower it to a BRCOND/BR
-    // pair.
-    switch (TLI.getOperationAction(ISD::BRCONDTWOWAY, MVT::Other)) {
-    case TargetLowering::Promote:
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) {
-        std::vector<SDOperand> Ops;
-        Ops.push_back(Tmp1);
-        Ops.push_back(Tmp2);
-        Ops.push_back(Node->getOperand(2));
-        Ops.push_back(Node->getOperand(3));
-        Result = DAG.getNode(ISD::BRCONDTWOWAY, MVT::Other, Ops);
-      }
-      break;
-    case TargetLowering::Expand:
-      // If BRTWOWAY_CC is legal for this target, then simply expand this node
-      // to that.  Otherwise, skip BRTWOWAY_CC and expand directly to a
-      // BRCOND/BR pair.
-      if (TLI.isOperationLegal(ISD::BRTWOWAY_CC, MVT::Other)) {
-        if (Tmp2.getOpcode() == ISD::SETCC) {
-          Result = DAG.getBR2Way_CC(Tmp1, Tmp2.getOperand(2),
-                                    Tmp2.getOperand(0), Tmp2.getOperand(1),
-                                    Node->getOperand(2), Node->getOperand(3));
-        } else {
-          Result = DAG.getBR2Way_CC(Tmp1, DAG.getCondCode(ISD::SETNE), Tmp2, 
-                                    DAG.getConstant(0, Tmp2.getValueType()),
-                                    Node->getOperand(2), Node->getOperand(3));
-        }
-      } else {
-        Result = DAG.getNode(ISD::BRCOND, MVT::Other, Tmp1, Tmp2,
-                           Node->getOperand(2));
-        Result = DAG.getNode(ISD::BR, MVT::Other, Result, Node->getOperand(3));
-      }
-      Result = LegalizeOp(Result);  // Relegalize new nodes.
-      break;
-    }
-    break;
-  case ISD::BRTWOWAY_CC:
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    if (isTypeLegal(Node->getOperand(2).getValueType())) {
-      Tmp2 = LegalizeOp(Node->getOperand(2));   // LHS
-      Tmp3 = LegalizeOp(Node->getOperand(3));   // RHS
-      if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(2) ||
-          Tmp3 != Node->getOperand(3)) {
-        Result = DAG.getBR2Way_CC(Tmp1, Node->getOperand(1), Tmp2, Tmp3,
-                                  Node->getOperand(4), Node->getOperand(5));
-      }
+    case TargetLowering::Legal: break;
+    case TargetLowering::Custom:
+      Tmp4 = TLI.LowerOperation(Result, DAG);
+      if (Tmp4.Val) Result = Tmp4;
       break;
-    } else {
-      Tmp2 = LegalizeOp(DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(),
-                                    Node->getOperand(2),  // LHS
-                                    Node->getOperand(3),  // RHS
-                                    Node->getOperand(1)));
-      // If this target does not support BRTWOWAY_CC, lower it to a BRCOND/BR
-      // pair.
-      switch (TLI.getOperationAction(ISD::BRTWOWAY_CC, MVT::Other)) {
-      default: assert(0 && "This action is not supported yet!");
-      case TargetLowering::Legal:
-        // If we get a SETCC back from legalizing the SETCC node we just
-        // created, then use its LHS, RHS, and CC directly in creating a new
-        // node.  Otherwise, select between the true and false value based on
-        // comparing the result of the legalized with zero.
-        if (Tmp2.getOpcode() == ISD::SETCC) {
-          Result = DAG.getBR2Way_CC(Tmp1, Tmp2.getOperand(2),
-                                    Tmp2.getOperand(0), Tmp2.getOperand(1),
-                                    Node->getOperand(4), Node->getOperand(5));
-        } else {
-          Result = DAG.getBR2Way_CC(Tmp1, DAG.getCondCode(ISD::SETNE), Tmp2, 
-                                    DAG.getConstant(0, Tmp2.getValueType()),
-                                    Node->getOperand(4), Node->getOperand(5));
-        }
-        break;
-      case TargetLowering::Expand: 
-        Result = DAG.getNode(ISD::BRCOND, MVT::Other, Tmp1, Tmp2,
-                             Node->getOperand(4));
-        Result = DAG.getNode(ISD::BR, MVT::Other, Result, Node->getOperand(5));
-        break;
-      }
-      Result = LegalizeOp(Result);  // Relegalize new nodes.
     }
     break;
   case ISD::LOAD: {
@@ -1046,37 +1144,26 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the pointer.
 
     MVT::ValueType VT = Node->getValueType(0);
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
+    Tmp2 = Result.getValue(0);
+    Tmp3 = Result.getValue(1);
+    
     switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
     default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Custom: {
-      SDOperand Op = DAG.getLoad(Node->getValueType(0),
-                                 Tmp1, Tmp2, Node->getOperand(2));
-      SDOperand Tmp = TLI.LowerOperation(Op, DAG);
-      if (Tmp.Val) {
-        Result = LegalizeOp(Tmp);
-        // Since loads produce two values, make sure to remember that we legalized
-        // both of them.
-        AddLegalizedOperand(SDOperand(Node, 0), Result);
-        AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
-        return Result.getValue(Op.ResNo);
-      }
-      // FALLTHROUGH if the target thinks it is legal.
-    }
-    case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0) ||
-          Tmp2 != Node->getOperand(1))
-        Result = DAG.getLoad(Node->getValueType(0), Tmp1, Tmp2,
-                             Node->getOperand(2));
-      else
-        Result = SDOperand(Node, 0);
-
-      // Since loads produce two values, make sure to remember that we legalized
-      // both of them.
-      AddLegalizedOperand(SDOperand(Node, 0), Result);
-      AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
-      return Result.getValue(Op.ResNo);
+    case TargetLowering::Legal: break;
+    case TargetLowering::Custom:
+      Tmp1 = TLI.LowerOperation(Tmp2, DAG);
+      if (Tmp1.Val) {
+        Tmp2 = LegalizeOp(Tmp1);
+        Tmp3 = LegalizeOp(Tmp1.getValue(1));
+      }
+      break;
     }
-    assert(0 && "Unreachable");
+    // Since loads produce two values, make sure to remember that we 
+    // legalized both of them.
+    AddLegalizedOperand(SDOperand(Node, 0), Tmp2);
+    AddLegalizedOperand(SDOperand(Node, 1), Tmp3);
+    return Op.ResNo ? Tmp3 : Tmp2;
   }
   case ISD::EXTLOAD:
   case ISD::SEXTLOAD:
@@ -1089,54 +1176,36 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     default: assert(0 && "This action is not supported yet!");
     case TargetLowering::Promote:
       assert(SrcVT == MVT::i1 && "Can only promote EXTLOAD from i1 -> i8!");
-      Result = DAG.getExtLoad(Node->getOpcode(), Node->getValueType(0),
-                              Tmp1, Tmp2, Node->getOperand(2), MVT::i8);
-      // Since loads produce two values, make sure to remember that we legalized
-      // both of them.
-      AddLegalizedOperand(SDOperand(Node, 0), Result);
-      AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
-      return Result.getValue(Op.ResNo);
-
-    case TargetLowering::Custom: {
-      SDOperand Op = DAG.getExtLoad(Node->getOpcode(), Node->getValueType(0),
-                                    Tmp1, Tmp2, Node->getOperand(2),
-                                    SrcVT);
-      SDOperand Tmp = TLI.LowerOperation(Op, DAG);
-      if (Tmp.Val) {
-        Result = LegalizeOp(Tmp);
-        // Since loads produce two values, make sure to remember that we legalized
-        // both of them.
-        AddLegalizedOperand(SDOperand(Node, 0), Result);
-        AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
-        return Result.getValue(Op.ResNo);
-      }
-      // FALLTHROUGH if the target thinks it is legal.
-    }
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2),
+                                      DAG.getValueType(MVT::i8));
+      Tmp1 = Result.getValue(0);
+      Tmp2 = Result.getValue(1);
+      break;
+    case TargetLowering::Custom:
+      isCustom = true;
+      // FALLTHROUGH
     case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0) ||
-          Tmp2 != Node->getOperand(1))
-        Result = DAG.getExtLoad(Node->getOpcode(), Node->getValueType(0),
-                                Tmp1, Tmp2, Node->getOperand(2), SrcVT);
-      else
-        Result = SDOperand(Node, 0);
-
-      // Since loads produce two values, make sure to remember that we legalized
-      // both of them.
-      AddLegalizedOperand(SDOperand(Node, 0), Result);
-      AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
-      return Result.getValue(Op.ResNo);
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2),
+                                      Node->getOperand(3));
+      Tmp1 = Result.getValue(0);
+      Tmp2 = Result.getValue(1);
+      
+      if (isCustom) {
+        Tmp3 = TLI.LowerOperation(Tmp3, DAG);
+        if (Tmp3.Val) {
+          Tmp1 = LegalizeOp(Tmp3);
+          Tmp2 = LegalizeOp(Tmp3.getValue(1));
+        }
+      }
+      break;
     case TargetLowering::Expand:
       // f64 = EXTLOAD f32 should expand to LOAD, FP_EXTEND
       if (SrcVT == MVT::f32 && Node->getValueType(0) == MVT::f64) {
         SDOperand Load = DAG.getLoad(SrcVT, Tmp1, Tmp2, Node->getOperand(2));
         Result = DAG.getNode(ISD::FP_EXTEND, Node->getValueType(0), Load);
-        Result = LegalizeOp(Result);  // Relegalize new nodes.
-        Load = LegalizeOp(Load);
-        AddLegalizedOperand(SDOperand(Node, 0), Result);
-        AddLegalizedOperand(SDOperand(Node, 1), Load.getValue(1));
-        if (Op.ResNo)
-          return Load.getValue(1);
-        return Result;
+        Tmp1 = LegalizeOp(Result);  // Relegalize new nodes.
+        Tmp2 = LegalizeOp(Load.getValue(1));
+        break;
       }
       assert(Node->getOpcode() != ISD::EXTLOAD &&
              "EXTLOAD should always be supported!");
@@ -1150,22 +1219,20 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
                              Result, DAG.getValueType(SrcVT));
       else
         ValRes = DAG.getZeroExtendInReg(Result, SrcVT);
-      Result = LegalizeOp(Result);  // Relegalize new nodes.
-      ValRes = LegalizeOp(ValRes);  // Relegalize new nodes.
-      AddLegalizedOperand(SDOperand(Node, 0), ValRes);
-      AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
-      if (Op.ResNo)
-        return Result.getValue(1);
-      return ValRes;
+      Tmp1 = LegalizeOp(ValRes);  // Relegalize new nodes.
+      Tmp2 = LegalizeOp(Result.getValue(1));  // Relegalize new nodes.
+      break;
     }
-    assert(0 && "Unreachable");
+    // Since loads produce two values, make sure to remember that we legalized
+    // both of them.
+    AddLegalizedOperand(SDOperand(Node, 0), Tmp1);
+    AddLegalizedOperand(SDOperand(Node, 1), Tmp2);
+    return Op.ResNo ? Tmp2 : Tmp1;
   }
   case ISD::EXTRACT_ELEMENT: {
     MVT::ValueType OpTy = Node->getOperand(0).getValueType();
     switch (getTypeAction(OpTy)) {
-    default:
-      assert(0 && "EXTRACT_ELEMENT action for type unimplemented!");
-      break;
+    default: assert(0 && "EXTRACT_ELEMENT action for type unimplemented!");
     case Legal:
       if (cast<ConstantSDNode>(Node->getOperand(1))->getValue()) {
         // 1 -> Hi
@@ -1178,7 +1245,6 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         Result = DAG.getNode(ISD::TRUNCATE, Node->getValueType(0), 
                              Node->getOperand(0));
       }
-      Result = LegalizeOp(Result);
       break;
     case Expand:
       // Get both the low and high parts.
@@ -1200,36 +1266,39 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     // Legalize the incoming value (must be a legal type).
     Tmp2 = LegalizeOp(Node->getOperand(2));
     if (Node->getNumValues() == 1) {
-      if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(2))
-        Result = DAG.getNode(ISD::CopyToReg, MVT::Other, Tmp1,
-                             Node->getOperand(1), Tmp2);
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1), Tmp2);
     } else {
       assert(Node->getNumValues() == 2 && "Unknown CopyToReg");
-      if (Node->getNumOperands() == 4)
+      if (Node->getNumOperands() == 4) {
         Tmp3 = LegalizeOp(Node->getOperand(3));
-      if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(2) ||
-          (Node->getNumOperands() == 4 && Tmp3 != Node->getOperand(3))) {
-        unsigned Reg = cast<RegisterSDNode>(Node->getOperand(1))->getReg();
-        Result = DAG.getCopyToReg(Tmp1, Reg, Tmp2, Tmp3);
+        Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1), Tmp2,
+                                        Tmp3);
+      } else {
+        Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1),Tmp2);
       }
       
       // Since this produces two values, make sure to remember that we legalized
       // both of them.
-      AddLegalizedOperand(SDOperand(Node, 0), Result);
+      AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0));
       AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
-      return Result.getValue(Op.ResNo);
+      return Result;
     }
     break;
 
   case ISD::RET:
     Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
+
+    // Ensure that libcalls are emitted before a return.
+    Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END);
+    Tmp1 = LegalizeOp(Tmp1);
+    LastCALLSEQ_END = DAG.getEntryNode();
+    
     switch (Node->getNumOperands()) {
     case 2:  // ret val
       switch (getTypeAction(Node->getOperand(1).getValueType())) {
       case Legal:
         Tmp2 = LegalizeOp(Node->getOperand(1));
-        if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1))
-          Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Tmp2);
+        Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
         break;
       case Expand: {
         SDOperand Lo, Hi;
@@ -1239,13 +1308,13 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       }
       case Promote:
         Tmp2 = PromoteOp(Node->getOperand(1));
-        Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Tmp2);
+        Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+        Result = LegalizeOp(Result);
         break;
       }
       break;
     case 1:  // ret void
-      if (Tmp1 != Node->getOperand(0))
-        Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1);
+      Result = DAG.UpdateNodeOperands(Result, Tmp1);
       break;
     default: { // ret <values>
       std::vector<SDOperand> NewValues;
@@ -1265,56 +1334,59 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         case Promote:
           assert(0 && "Can't promote multiple return value yet!");
         }
-      Result = DAG.getNode(ISD::RET, MVT::Other, NewValues);
+          
+      if (NewValues.size() == Node->getNumOperands())
+        Result = DAG.UpdateNodeOperands(Result, NewValues);
+      else
+        Result = DAG.getNode(ISD::RET, MVT::Other, NewValues);
       break;
     }
     }
+
+    if (Result.getOpcode() == ISD::RET) {
+      switch (TLI.getOperationAction(Result.getOpcode(), MVT::Other)) {
+      default: assert(0 && "This action is not supported yet!");
+      case TargetLowering::Legal: break;
+      case TargetLowering::Custom:
+        Tmp1 = TLI.LowerOperation(Result, DAG);
+        if (Tmp1.Val) Result = Tmp1;
+        break;
+      }
+    }
     break;
   case ISD::STORE: {
     Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
     Tmp2 = LegalizeOp(Node->getOperand(2));  // Legalize the pointer.
 
     // Turn 'store float 1.0, Ptr' -> 'store int 0x12345678, Ptr'
+    // FIXME: We shouldn't do this for TargetConstantFP's.
+    // FIXME: move this to the DAG Combiner!
     if (ConstantFPSDNode *CFP =dyn_cast<ConstantFPSDNode>(Node->getOperand(1))){
       if (CFP->getValueType(0) == MVT::f32) {
-        Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1,
-                             DAG.getConstant(FloatToBits(CFP->getValue()),
-                                             MVT::i32),
-                             Tmp2,
-                             Node->getOperand(3));
+        Tmp3 = DAG.getConstant(FloatToBits(CFP->getValue()), MVT::i32);
       } else {
         assert(CFP->getValueType(0) == MVT::f64 && "Unknown FP type!");
-        Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1,
-                             DAG.getConstant(DoubleToBits(CFP->getValue()),
-                                             MVT::i64),
-                             Tmp2,
-                             Node->getOperand(3));
+        Tmp3 = DAG.getConstant(DoubleToBits(CFP->getValue()), MVT::i64);
       }
-      Node = Result.Val;
+      Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Tmp3, Tmp2, 
+                           Node->getOperand(3));
+      break;
     }
 
     switch (getTypeAction(Node->getOperand(1).getValueType())) {
     case Legal: {
-      SDOperand Val = LegalizeOp(Node->getOperand(1));
-      if (Val != Node->getOperand(1) || Tmp1 != Node->getOperand(0) ||
-          Tmp2 != Node->getOperand(2))
-        Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Val, Tmp2,
-                             Node->getOperand(3));
-
-      MVT::ValueType VT = Result.Val->getOperand(1).getValueType();
-      switch (TLI.getOperationAction(Result.Val->getOpcode(), VT)) {
-        default: assert(0 && "This action is not supported yet!");
-        case TargetLowering::Custom: {
-          SDOperand Tmp = TLI.LowerOperation(Result, DAG);
-          if (Tmp.Val) {
-            Result = LegalizeOp(Tmp);
-            break;
-          }
-          // FALLTHROUGH if the target thinks it is legal.
-        }
-        case TargetLowering::Legal:
-          // Nothing to do.
-          break;
+      Tmp3 = LegalizeOp(Node->getOperand(1));
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp3, Tmp2, 
+                                      Node->getOperand(3));
+
+      MVT::ValueType VT = Tmp3.getValueType();
+      switch (TLI.getOperationAction(ISD::STORE, VT)) {
+      default: assert(0 && "This action is not supported yet!");
+      case TargetLowering::Legal:  break;
+      case TargetLowering::Custom:
+        Tmp1 = TLI.LowerOperation(Result, DAG);
+        if (Tmp1.Val) Result = Tmp1;
+        break;
       }
       break;
     }
@@ -1327,30 +1399,53 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       break;
 
     case Expand:
+      unsigned IncrementSize = 0;
       SDOperand Lo, Hi;
-      unsigned IncrementSize;
-      ExpandOp(Node->getOperand(1), Lo, Hi);
-
-      if (!TLI.isLittleEndian())
-        std::swap(Lo, Hi);
-
-      Lo = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Lo, Tmp2,
-                       Node->getOperand(3));
+      
       // If this is a vector type, then we have to calculate the increment as
       // the product of the element size in bytes, and the number of elements
       // in the high half of the vector.
-      if (MVT::Vector == Hi.getValueType()) {
-        unsigned NumElems = cast<ConstantSDNode>(Hi.getOperand(2))->getValue();
-        MVT::ValueType EVT = cast<VTSDNode>(Hi.getOperand(3))->getVT();
-        IncrementSize = NumElems * MVT::getSizeInBits(EVT)/8;
+      if (Node->getOperand(1).getValueType() == MVT::Vector) {
+        SDNode *InVal = Node->getOperand(1).Val;
+        unsigned NumElems =
+          cast<ConstantSDNode>(*(InVal->op_end()-2))->getValue();
+        MVT::ValueType EVT = cast<VTSDNode>(*(InVal->op_end()-1))->getVT();
+
+        // Figure out if there is a Packed type corresponding to this Vector
+        // type.  If so, convert to the packed type.
+        MVT::ValueType TVT = MVT::getVectorType(EVT, NumElems);
+        if (TVT != MVT::Other && TLI.isTypeLegal(TVT)) {
+          // Turn this into a normal store of the packed type.
+          Tmp3 = PackVectorOp(Node->getOperand(1), TVT);
+          Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp3, Tmp2, 
+                                          Node->getOperand(3));
+          break;
+        } else if (NumElems == 1) {
+          // Turn this into a normal store of the scalar type.
+          Tmp3 = PackVectorOp(Node->getOperand(1), EVT);
+          Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp3, Tmp2, 
+                                          Node->getOperand(3));
+          break;
+        } else {
+          SplitVectorOp(Node->getOperand(1), Lo, Hi);
+          IncrementSize = NumElems/2 * MVT::getSizeInBits(EVT)/8;
+        }
       } else {
+        ExpandOp(Node->getOperand(1), Lo, Hi);
         IncrementSize = MVT::getSizeInBits(Hi.getValueType())/8;
       }
+
+      if (!TLI.isLittleEndian())
+        std::swap(Lo, Hi);
+
+      Lo = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Lo, Tmp2,
+                       Node->getOperand(3));
       Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2,
                          getIntPtrConstant(IncrementSize));
       assert(isTypeLegal(Tmp2.getValueType()) &&
              "Pointers must be legal!");
-      //Again, claiming both parts of the store came form the same Instr
+      // FIXME: This sets the srcvalue of both halves to be the same, which is
+      // wrong.
       Hi = DAG.getNode(ISD::STORE, MVT::Other, Tmp1, Hi, Tmp2,
                        Node->getOperand(3));
       Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
@@ -1360,69 +1455,110 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
   }
   case ISD::PCMARKER:
     Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    if (Tmp1 != Node->getOperand(0))
-      Result = DAG.getNode(ISD::PCMARKER, MVT::Other, Tmp1,Node->getOperand(1));
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1));
+    break;
+  case ISD::STACKSAVE:
+    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
+    Result = DAG.UpdateNodeOperands(Result, Tmp1);
+    Tmp1 = Result.getValue(0);
+    Tmp2 = Result.getValue(1);
+    
+    switch (TLI.getOperationAction(ISD::STACKSAVE, MVT::Other)) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Legal: break;
+    case TargetLowering::Custom:
+      Tmp3 = TLI.LowerOperation(Result, DAG);
+      if (Tmp3.Val) {
+        Tmp1 = LegalizeOp(Tmp3);
+        Tmp2 = LegalizeOp(Tmp3.getValue(1));
+      }
+      break;
+    case TargetLowering::Expand:
+      // Expand to CopyFromReg if the target set 
+      // StackPointerRegisterToSaveRestore.
+      if (unsigned SP = TLI.getStackPointerRegisterToSaveRestore()) {
+        Tmp1 = DAG.getCopyFromReg(Result.getOperand(0), SP,
+                                  Node->getValueType(0));
+        Tmp2 = Tmp1.getValue(1);
+      } else {
+        Tmp1 = DAG.getNode(ISD::UNDEF, Node->getValueType(0));
+        Tmp2 = Node->getOperand(0);
+      }
+      break;
+    }
+
+    // Since stacksave produce two values, make sure to remember that we
+    // legalized both of them.
+    AddLegalizedOperand(SDOperand(Node, 0), Tmp1);
+    AddLegalizedOperand(SDOperand(Node, 1), Tmp2);
+    return Op.ResNo ? Tmp2 : Tmp1;
+
+  case ISD::STACKRESTORE:
+    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
+    Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the pointer.
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+      
+    switch (TLI.getOperationAction(ISD::STACKRESTORE, MVT::Other)) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Legal: break;
+    case TargetLowering::Custom:
+      Tmp1 = TLI.LowerOperation(Result, DAG);
+      if (Tmp1.Val) Result = Tmp1;
+      break;
+    case TargetLowering::Expand:
+      // Expand to CopyToReg if the target set 
+      // StackPointerRegisterToSaveRestore.
+      if (unsigned SP = TLI.getStackPointerRegisterToSaveRestore()) {
+        Result = DAG.getCopyToReg(Tmp1, SP, Tmp2);
+      } else {
+        Result = Tmp1;
+      }
+      break;
+    }
     break;
+
   case ISD::READCYCLECOUNTER:
     Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain
-    if (Tmp1 != Node->getOperand(0)) {
-      std::vector<MVT::ValueType> rtypes;
-      std::vector<SDOperand> rvals;
-      rtypes.push_back(MVT::i64);
-      rtypes.push_back(MVT::Other);
-      rvals.push_back(Tmp1);
-      Result = DAG.getNode(ISD::READCYCLECOUNTER, rtypes, rvals);
-    }
+    Result = DAG.UpdateNodeOperands(Result, Tmp1);
 
     // Since rdcc produce two values, make sure to remember that we legalized
     // both of them.
-    AddLegalizedOperand(SDOperand(Node, 0), Result);
+    AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0));
     AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
-    return Result.getValue(Op.ResNo);
+    return Result;
 
   case ISD::TRUNCSTORE: {
     Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
     Tmp3 = LegalizeOp(Node->getOperand(2));  // Legalize the pointer.
 
-    switch (getTypeAction(Node->getOperand(1).getValueType())) {
-    case Promote:
-    case Expand:
-      assert(0 && "Cannot handle illegal TRUNCSTORE yet!");
-    case Legal:
-      Tmp2 = LegalizeOp(Node->getOperand(1));
-      
-      // The only promote case we handle is TRUNCSTORE:i1 X into
-      //   -> TRUNCSTORE:i8 (and X, 1)
-      if (cast<VTSDNode>(Node->getOperand(4))->getVT() == MVT::i1 &&
-          TLI.getOperationAction(ISD::TRUNCSTORE, MVT::i1) == 
-                TargetLowering::Promote) {
-        // Promote the bool to a mask then store.
-        Tmp2 = DAG.getNode(ISD::AND, Tmp2.getValueType(), Tmp2,
-                           DAG.getConstant(1, Tmp2.getValueType()));
-        Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Tmp1, Tmp2, Tmp3,
-                             Node->getOperand(3), DAG.getValueType(MVT::i8));
-
-      } else if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
-                 Tmp3 != Node->getOperand(2)) {
-        Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Tmp1, Tmp2, Tmp3,
-                             Node->getOperand(3), Node->getOperand(4));
-      }
-
-      MVT::ValueType StVT = cast<VTSDNode>(Result.Val->getOperand(4))->getVT();
-      switch (TLI.getOperationAction(Result.Val->getOpcode(), StVT)) {
-        default: assert(0 && "This action is not supported yet!");
-        case TargetLowering::Custom: {
-          SDOperand Tmp = TLI.LowerOperation(Result, DAG);
-          if (Tmp.Val) {
-            Result = LegalizeOp(Tmp);
-            break;
-          }
-          // FALLTHROUGH if the target thinks it is legal.
-        }
-        case TargetLowering::Legal:
-          // Nothing to do.
-          break;
-      }
+    assert(isTypeLegal(Node->getOperand(1).getValueType()) &&
+           "Cannot handle illegal TRUNCSTORE yet!");
+    Tmp2 = LegalizeOp(Node->getOperand(1));
+    
+    // The only promote case we handle is TRUNCSTORE:i1 X into
+    //   -> TRUNCSTORE:i8 (and X, 1)
+    if (cast<VTSDNode>(Node->getOperand(4))->getVT() == MVT::i1 &&
+        TLI.getOperationAction(ISD::TRUNCSTORE, MVT::i1) == 
+              TargetLowering::Promote) {
+      // Promote the bool to a mask then store.
+      Tmp2 = DAG.getNode(ISD::AND, Tmp2.getValueType(), Tmp2,
+                         DAG.getConstant(1, Tmp2.getValueType()));
+      Result = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Tmp1, Tmp2, Tmp3,
+                           Node->getOperand(3), DAG.getValueType(MVT::i8));
+
+    } else if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
+               Tmp3 != Node->getOperand(2)) {
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3,
+                                      Node->getOperand(3), Node->getOperand(4));
+    }
+
+    MVT::ValueType StVT = cast<VTSDNode>(Result.Val->getOperand(4))->getVT();
+    switch (TLI.getOperationAction(Result.Val->getOpcode(), StVT)) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Legal: break;
+    case TargetLowering::Custom:
+      Tmp1 = TLI.LowerOperation(Result, DAG);
+      if (Tmp1.Val) Result = Tmp1;
       break;
     }
     break;
@@ -1440,8 +1576,16 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     Tmp2 = LegalizeOp(Node->getOperand(1));   // TrueVal
     Tmp3 = LegalizeOp(Node->getOperand(2));   // FalseVal
 
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
+      
     switch (TLI.getOperationAction(ISD::SELECT, Tmp2.getValueType())) {
     default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Legal: break;
+    case TargetLowering::Custom: {
+      Tmp1 = TLI.LowerOperation(Result, DAG);
+      if (Tmp1.Val) Result = Tmp1;
+      break;
+    }
     case TargetLowering::Expand:
       if (Tmp1.getOpcode() == ISD::SETCC) {
         Result = DAG.getSelectCC(Tmp1.getOperand(0), Tmp1.getOperand(1), 
@@ -1450,39 +1594,24 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       } else {
         // Make sure the condition is either zero or one.  It may have been
         // promoted from something else.
-        Tmp1 = DAG.getZeroExtendInReg(Tmp1, MVT::i1);
+        unsigned NumBits = MVT::getSizeInBits(Tmp1.getValueType());
+        if (!TLI.MaskedValueIsZero(Tmp1, (~0ULL >> (64-NumBits))^1))
+          Tmp1 = DAG.getZeroExtendInReg(Tmp1, MVT::i1);
         Result = DAG.getSelectCC(Tmp1, 
                                  DAG.getConstant(0, Tmp1.getValueType()),
                                  Tmp2, Tmp3, ISD::SETNE);
       }
-      Result = LegalizeOp(Result);  // Relegalize new nodes.
-      break;
-    case TargetLowering::Custom: {
-      SDOperand Tmp =
-        TLI.LowerOperation(DAG.getNode(ISD::SELECT, Node->getValueType(0),
-                                       Tmp1, Tmp2, Tmp3), DAG);
-      if (Tmp.Val) {
-        Result = LegalizeOp(Tmp);
-        break;
-      }
-      // FALLTHROUGH if the target thinks it is legal.
-    }
-    case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
-          Tmp3 != Node->getOperand(2))
-        Result = DAG.getNode(ISD::SELECT, Node->getValueType(0),
-                             Tmp1, Tmp2, Tmp3);
       break;
     case TargetLowering::Promote: {
       MVT::ValueType NVT =
         TLI.getTypeToPromoteTo(ISD::SELECT, Tmp2.getValueType());
       unsigned ExtOp, TruncOp;
       if (MVT::isInteger(Tmp2.getValueType())) {
-        ExtOp = ISD::ANY_EXTEND;
-        TruncOp  = ISD::TRUNCATE;
+        ExtOp   = ISD::ANY_EXTEND;
+        TruncOp = ISD::TRUNCATE;
       } else {
-        ExtOp = ISD::FP_EXTEND;
-        TruncOp  = ISD::FP_ROUND;
+        ExtOp   = ISD::FP_EXTEND;
+        TruncOp = ISD::FP_ROUND;
       }
       // Promote each of the values to the new type.
       Tmp2 = DAG.getNode(ExtOp, NVT, Tmp2);
@@ -1494,171 +1623,60 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     }
     }
     break;
-  case ISD::SELECT_CC:
+  case ISD::SELECT_CC: {
+    Tmp1 = Node->getOperand(0);               // LHS
+    Tmp2 = Node->getOperand(1);               // RHS
     Tmp3 = LegalizeOp(Node->getOperand(2));   // True
     Tmp4 = LegalizeOp(Node->getOperand(3));   // False
+    SDOperand CC = Node->getOperand(4);
     
-    if (isTypeLegal(Node->getOperand(0).getValueType())) {
-      // Everything is legal, see if we should expand this op or something.
-      switch (TLI.getOperationAction(ISD::SELECT_CC,
-                                     Node->getOperand(0).getValueType())) {
-      default: assert(0 && "This action is not supported yet!");
-      case TargetLowering::Custom: {
-        SDOperand Tmp =
-          TLI.LowerOperation(DAG.getNode(ISD::SELECT_CC, Node->getValueType(0),
-                                         Node->getOperand(0),
-                                         Node->getOperand(1), Tmp3, Tmp4,
-                                         Node->getOperand(4)), DAG);
-        if (Tmp.Val) {
-          Result = LegalizeOp(Tmp);
-          break;
-        }
-      } // FALLTHROUGH if the target can't lower this operation after all.
-      case TargetLowering::Legal:
-        Tmp1 = LegalizeOp(Node->getOperand(0));   // LHS
-        Tmp2 = LegalizeOp(Node->getOperand(1));   // RHS
-        if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
-            Tmp3 != Node->getOperand(2) || Tmp4 != Node->getOperand(3)) {
-          Result = DAG.getNode(ISD::SELECT_CC, Node->getValueType(0), Tmp1,Tmp2, 
-                               Tmp3, Tmp4, Node->getOperand(4));
-        }
-        break;
-      }
+    LegalizeSetCCOperands(Tmp1, Tmp2, CC);
+    
+    // If we didn't get both a LHS and RHS back from LegalizeSetCCOperands,
+    // the LHS is a legal SETCC itself.  In this case, we need to compare
+    // the result against zero to select between true and false values.
+    if (Tmp2.Val == 0) {
+      Tmp2 = DAG.getConstant(0, Tmp1.getValueType());
+      CC = DAG.getCondCode(ISD::SETNE);
+    }
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3, Tmp4, CC);
+
+    // Everything is legal, see if we should expand this op or something.
+    switch (TLI.getOperationAction(ISD::SELECT_CC, Tmp3.getValueType())) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Legal: break;
+    case TargetLowering::Custom:
+      Tmp1 = TLI.LowerOperation(Result, DAG);
+      if (Tmp1.Val) Result = Tmp1;
       break;
-    } else {
-      Tmp1 = LegalizeOp(DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(),
-                                    Node->getOperand(0),  // LHS
-                                    Node->getOperand(1),  // RHS
-                                    Node->getOperand(4)));
-      // If we get a SETCC back from legalizing the SETCC node we just
-      // created, then use its LHS, RHS, and CC directly in creating a new
-      // node.  Otherwise, select between the true and false value based on
-      // comparing the result of the legalized with zero.
-      if (Tmp1.getOpcode() == ISD::SETCC) {
-        Result = DAG.getNode(ISD::SELECT_CC, Tmp3.getValueType(),
-                             Tmp1.getOperand(0), Tmp1.getOperand(1),
-                             Tmp3, Tmp4, Tmp1.getOperand(2));
-      } else {
-        Result = DAG.getSelectCC(Tmp1,
-                                 DAG.getConstant(0, Tmp1.getValueType()), 
-                                 Tmp3, Tmp4, ISD::SETNE);
-      }
     }
     break;
+  }
   case ISD::SETCC:
-    switch (getTypeAction(Node->getOperand(0).getValueType())) {
-    case Legal:
-      Tmp1 = LegalizeOp(Node->getOperand(0));   // LHS
-      Tmp2 = LegalizeOp(Node->getOperand(1));   // RHS
-      break;
-    case Promote:
-      Tmp1 = PromoteOp(Node->getOperand(0));   // LHS
-      Tmp2 = PromoteOp(Node->getOperand(1));   // RHS
-
-      // If this is an FP compare, the operands have already been extended.
-      if (MVT::isInteger(Node->getOperand(0).getValueType())) {
-        MVT::ValueType VT = Node->getOperand(0).getValueType();
-        MVT::ValueType NVT = TLI.getTypeToTransformTo(VT);
-
-        // Otherwise, we have to insert explicit sign or zero extends.  Note
-        // that we could insert sign extends for ALL conditions, but zero extend
-        // is cheaper on many machines (an AND instead of two shifts), so prefer
-        // it.
-        switch (cast<CondCodeSDNode>(Node->getOperand(2))->get()) {
-        default: assert(0 && "Unknown integer comparison!");
-        case ISD::SETEQ:
-        case ISD::SETNE:
-        case ISD::SETUGE:
-        case ISD::SETUGT:
-        case ISD::SETULE:
-        case ISD::SETULT:
-          // ALL of these operations will work if we either sign or zero extend
-          // the operands (including the unsigned comparisons!).  Zero extend is
-          // usually a simpler/cheaper operation, so prefer it.
-          Tmp1 = DAG.getZeroExtendInReg(Tmp1, VT);
-          Tmp2 = DAG.getZeroExtendInReg(Tmp2, VT);
-          break;
-        case ISD::SETGE:
-        case ISD::SETGT:
-        case ISD::SETLT:
-        case ISD::SETLE:
-          Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1,
-                             DAG.getValueType(VT));
-          Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2,
-                             DAG.getValueType(VT));
-          break;
-        }
-      }
+    Tmp1 = Node->getOperand(0);
+    Tmp2 = Node->getOperand(1);
+    Tmp3 = Node->getOperand(2);
+    LegalizeSetCCOperands(Tmp1, Tmp2, Tmp3);
+    
+    // If we had to Expand the SetCC operands into a SELECT node, then it may 
+    // not always be possible to return a true LHS & RHS.  In this case, just 
+    // return the value we legalized, returned in the LHS
+    if (Tmp2.Val == 0) {
+      Result = Tmp1;
       break;
-    case Expand:
-      SDOperand LHSLo, LHSHi, RHSLo, RHSHi;
-      ExpandOp(Node->getOperand(0), LHSLo, LHSHi);
-      ExpandOp(Node->getOperand(1), RHSLo, RHSHi);
-      switch (cast<CondCodeSDNode>(Node->getOperand(2))->get()) {
-      case ISD::SETEQ:
-      case ISD::SETNE:
-        if (RHSLo == RHSHi)
-          if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo))
-            if (RHSCST->isAllOnesValue()) {
-              // Comparison to -1.
-              Tmp1 = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi);
-              Tmp2 = RHSLo;
-              break;
-            }
-
-        Tmp1 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo);
-        Tmp2 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi);
-        Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp2);
-        Tmp2 = DAG.getConstant(0, Tmp1.getValueType());
-        break;
-      default:
-        // If this is a comparison of the sign bit, just look at the top part.
-        // X > -1,  x < 0
-        if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(Node->getOperand(1)))
-          if ((cast<CondCodeSDNode>(Node->getOperand(2))->get() == ISD::SETLT &&
-               CST->getValue() == 0) ||              // X < 0
-              (cast<CondCodeSDNode>(Node->getOperand(2))->get() == ISD::SETGT &&
-               (CST->isAllOnesValue()))) {            // X > -1
-            Tmp1 = LHSHi;
-            Tmp2 = RHSHi;
-            break;
-          }
-
-        // FIXME: This generated code sucks.
-        ISD::CondCode LowCC;
-        switch (cast<CondCodeSDNode>(Node->getOperand(2))->get()) {
-        default: assert(0 && "Unknown integer setcc!");
-        case ISD::SETLT:
-        case ISD::SETULT: LowCC = ISD::SETULT; break;
-        case ISD::SETGT:
-        case ISD::SETUGT: LowCC = ISD::SETUGT; break;
-        case ISD::SETLE:
-        case ISD::SETULE: LowCC = ISD::SETULE; break;
-        case ISD::SETGE:
-        case ISD::SETUGE: LowCC = ISD::SETUGE; break;
-        }
-
-        // Tmp1 = lo(op1) < lo(op2)   // Always unsigned comparison
-        // Tmp2 = hi(op1) < hi(op2)   // Signedness depends on operands
-        // dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2;
-
-        // NOTE: on targets without efficient SELECT of bools, we can always use
-        // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3)
-        Tmp1 = DAG.getSetCC(Node->getValueType(0), LHSLo, RHSLo, LowCC);
-        Tmp2 = DAG.getNode(ISD::SETCC, Node->getValueType(0), LHSHi, RHSHi,
-                           Node->getOperand(2));
-        Result = DAG.getSetCC(Node->getValueType(0), LHSHi, RHSHi, ISD::SETEQ);
-        Result = LegalizeOp(DAG.getNode(ISD::SELECT, Tmp1.getValueType(),
-                                        Result, Tmp1, Tmp2));
-        AddLegalizedOperand(SDOperand(Node, 0), Result);
-        return Result;
-      }
     }
 
-    switch(TLI.getOperationAction(ISD::SETCC,
-                                  Node->getOperand(0).getValueType())) {
-    default: 
-      assert(0 && "Cannot handle this action for SETCC yet!");
+    switch (TLI.getOperationAction(ISD::SETCC, Tmp1.getValueType())) {
+    default: assert(0 && "Cannot handle this action for SETCC yet!");
+    case TargetLowering::Custom:
+      isCustom = true;
+      // FALLTHROUGH.
+    case TargetLowering::Legal:
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
+      if (isCustom) {
+        Tmp3 = TLI.LowerOperation(Result, DAG);
+        if (Tmp3.Val) Result = Tmp3;
+      }
       break;
     case TargetLowering::Promote: {
       // First step, figure out the appropriate operation to use.
@@ -1686,26 +1704,12 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         Tmp1 = DAG.getNode(ISD::FP_EXTEND, NewInTy, Tmp1);
         Tmp2 = DAG.getNode(ISD::FP_EXTEND, NewInTy, Tmp2);
       }
-      
-      Result = DAG.getNode(ISD::SETCC, Node->getValueType(0), Tmp1, Tmp2,
-                           Node->getOperand(2));
+      Tmp1 = LegalizeOp(Tmp1);
+      Tmp2 = LegalizeOp(Tmp2);
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
+      Result = LegalizeOp(Result);
       break;
     }
-    case TargetLowering::Custom: {
-      SDOperand Tmp =
-        TLI.LowerOperation(DAG.getNode(ISD::SETCC, Node->getValueType(0),
-                                       Tmp1, Tmp2, Node->getOperand(2)), DAG);
-      if (Tmp.Val) {
-        Result = LegalizeOp(Tmp);
-        break;
-      }
-      // FALLTHROUGH if the target thinks it is legal.
-    }
-    case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1))
-        Result = DAG.getNode(ISD::SETCC, Node->getValueType(0), Tmp1, Tmp2,
-                             Node->getOperand(2));
-      break;
     case TargetLowering::Expand:
       // Expand a setcc node into a select_cc of the same condition, lhs, and
       // rhs that selects between const 1 (true) and const 0 (false).
@@ -1713,11 +1717,9 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       Result = DAG.getNode(ISD::SELECT_CC, VT, Tmp1, Tmp2, 
                            DAG.getConstant(1, VT), DAG.getConstant(0, VT),
                            Node->getOperand(2));
-      Result = LegalizeOp(Result);
       break;
     }
     break;
-
   case ISD::MEMSET:
   case ISD::MEMCPY:
   case ISD::MEMMOVE: {
@@ -1767,24 +1769,14 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
 
     switch (TLI.getOperationAction(Node->getOpcode(), MVT::Other)) {
     default: assert(0 && "This action not implemented for this operation!");
-    case TargetLowering::Custom: {
-      SDOperand Tmp =
-        TLI.LowerOperation(DAG.getNode(Node->getOpcode(), MVT::Other, Tmp1, 
-                                       Tmp2, Tmp3, Tmp4, Tmp5), DAG);
-      if (Tmp.Val) {
-        Result = LegalizeOp(Tmp);
-        break;
-      }
-      // FALLTHROUGH if the target thinks it is legal.
-    }
+    case TargetLowering::Custom:
+      isCustom = true;
+      // FALLTHROUGH
     case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
-          Tmp3 != Node->getOperand(2) || Tmp4 != Node->getOperand(3) ||
-          Tmp5 != Node->getOperand(4)) {
-        std::vector<SDOperand> Ops;
-        Ops.push_back(Tmp1); Ops.push_back(Tmp2); Ops.push_back(Tmp3);
-        Ops.push_back(Tmp4); Ops.push_back(Tmp5);
-        Result = DAG.getNode(Node->getOpcode(), MVT::Other, Ops);
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3, Tmp4, Tmp5);
+      if (isCustom) {
+        Tmp1 = TLI.LowerOperation(Result, DAG);
+        if (Tmp1.Val) Result = Tmp1;
       }
       break;
     case TargetLowering::Expand: {
@@ -1797,8 +1789,12 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       const char *FnName = 0;
       if (Node->getOpcode() == ISD::MEMSET) {
         Args.push_back(std::make_pair(Tmp2, IntPtrTy));
-        // Extend the ubyte argument to be an int value for the call.
-        Tmp3 = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Tmp3);
+        // Extend the (previously legalized) ubyte argument to be an int value
+        // for the call.
+        if (Tmp3.getValueType() > MVT::i32)
+          Tmp3 = DAG.getNode(ISD::TRUNCATE, MVT::i32, Tmp3);
+        else
+          Tmp3 = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Tmp3);
         Args.push_back(std::make_pair(Tmp3, Type::IntTy));
         Args.push_back(std::make_pair(Tmp4, IntPtrTy));
 
@@ -1816,96 +1812,13 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       std::pair<SDOperand,SDOperand> CallResult =
         TLI.LowerCallTo(Tmp1, Type::VoidTy, false, CallingConv::C, false,
                         DAG.getExternalSymbol(FnName, IntPtr), Args, DAG);
-      Result = LegalizeOp(CallResult.second);
+      Result = CallResult.second;
       break;
     }
     }
     break;
   }
 
-  case ISD::READPORT:
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    Tmp2 = LegalizeOp(Node->getOperand(1));
-
-    if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) {
-      std::vector<MVT::ValueType> VTs(Node->value_begin(), Node->value_end());
-      std::vector<SDOperand> Ops;
-      Ops.push_back(Tmp1);
-      Ops.push_back(Tmp2);
-      Result = DAG.getNode(ISD::READPORT, VTs, Ops);
-    } else
-      Result = SDOperand(Node, 0);
-    // Since these produce two values, make sure to remember that we legalized
-    // both of them.
-    AddLegalizedOperand(SDOperand(Node, 0), Result);
-    AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
-    return Result.getValue(Op.ResNo);
-  case ISD::WRITEPORT:
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    Tmp2 = LegalizeOp(Node->getOperand(1));
-    Tmp3 = LegalizeOp(Node->getOperand(2));
-    if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
-        Tmp3 != Node->getOperand(2))
-      Result = DAG.getNode(Node->getOpcode(), MVT::Other, Tmp1, Tmp2, Tmp3);
-    break;
-
-  case ISD::READIO:
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    Tmp2 = LegalizeOp(Node->getOperand(1));
-
-    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
-    case TargetLowering::Custom:
-    default: assert(0 && "This action not implemented for this operation!");
-    case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) {
-        std::vector<MVT::ValueType> VTs(Node->value_begin(), Node->value_end());
-        std::vector<SDOperand> Ops;
-        Ops.push_back(Tmp1);
-        Ops.push_back(Tmp2);
-        Result = DAG.getNode(ISD::READPORT, VTs, Ops);
-      } else
-        Result = SDOperand(Node, 0);
-      break;
-    case TargetLowering::Expand:
-      // Replace this with a load from memory.
-      Result = DAG.getLoad(Node->getValueType(0), Node->getOperand(0),
-                           Node->getOperand(1), DAG.getSrcValue(NULL));
-      Result = LegalizeOp(Result);
-      break;
-    }
-
-    // Since these produce two values, make sure to remember that we legalized
-    // both of them.
-    AddLegalizedOperand(SDOperand(Node, 0), Result);
-    AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
-    return Result.getValue(Op.ResNo);
-
-  case ISD::WRITEIO:
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    Tmp2 = LegalizeOp(Node->getOperand(1));
-    Tmp3 = LegalizeOp(Node->getOperand(2));
-
-    switch (TLI.getOperationAction(Node->getOpcode(),
-                                   Node->getOperand(1).getValueType())) {
-    case TargetLowering::Custom:
-    default: assert(0 && "This action not implemented for this operation!");
-    case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1) ||
-          Tmp3 != Node->getOperand(2))
-        Result = DAG.getNode(Node->getOpcode(), MVT::Other, Tmp1, Tmp2, Tmp3);
-      break;
-    case TargetLowering::Expand:
-      // Replace this with a store to memory.
-      Result = DAG.getNode(ISD::STORE, MVT::Other, Node->getOperand(0),
-                           Node->getOperand(1), Node->getOperand(2),
-                           DAG.getSrcValue(NULL));
-      Result = LegalizeOp(Result);
-      break;
-    }
-    break;
-
-  case ISD::ADD_PARTS:
-  case ISD::SUB_PARTS:
   case ISD::SHL_PARTS:
   case ISD::SRA_PARTS:
   case ISD::SRL_PARTS: {
@@ -1915,9 +1828,27 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       Ops.push_back(LegalizeOp(Node->getOperand(i)));
       Changed |= Ops.back() != Node->getOperand(i);
     }
-    if (Changed) {
-      std::vector<MVT::ValueType> VTs(Node->value_begin(), Node->value_end());
-      Result = DAG.getNode(Node->getOpcode(), VTs, Ops);
+    if (Changed)
+      Result = DAG.UpdateNodeOperands(Result, Ops);
+
+    switch (TLI.getOperationAction(Node->getOpcode(),
+                                   Node->getValueType(0))) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Legal: break;
+    case TargetLowering::Custom:
+      Tmp1 = TLI.LowerOperation(Result, DAG);
+      if (Tmp1.Val) {
+        SDOperand Tmp2, RetVal(0, 0);
+        for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) {
+          Tmp2 = LegalizeOp(Tmp1.getValue(i));
+          AddLegalizedOperand(SDOperand(Node, i), Tmp2);
+          if (i == Op.ResNo)
+            RetVal = Tmp2;
+        }
+        assert(RetVal.Val && "Illegal result number");
+        return RetVal;
+      }
+      break;
     }
 
     // Since these produce multiple values, make sure to remember that we
@@ -1955,101 +1886,322 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       Tmp2 = PromoteOp(Node->getOperand(1));  // Promote the RHS.
       break;
     }
-    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
+    
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+      
+    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
+    default: assert(0 && "Operation not supported");
+    case TargetLowering::Legal: break;
+    case TargetLowering::Custom:
+      Tmp1 = TLI.LowerOperation(Result, DAG);
+      if (Tmp1.Val) Result = Tmp1;
+      break;
+    }
+    break;
+    
+  case ISD::FCOPYSIGN:  // FCOPYSIGN does not require LHS/RHS to match type!
+    Tmp1 = LegalizeOp(Node->getOperand(0));   // LHS
+    switch (getTypeAction(Node->getOperand(1).getValueType())) {
+      case Expand: assert(0 && "Not possible");
+      case Legal:
+        Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the RHS.
+        break;
+      case Promote:
+        Tmp2 = PromoteOp(Node->getOperand(1));  // Promote the RHS.
+        break;
+    }
+      
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+    
+    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
+    default: assert(0 && "Operation not supported");
+    case TargetLowering::Custom:
+      Tmp1 = TLI.LowerOperation(Result, DAG);
+      if (Tmp1.Val) Result = Tmp1;
+      break;
+    case TargetLowering::Legal: break;
+    case TargetLowering::Expand:
+      // If this target supports fabs/fneg natively, do this efficiently.
+      if (TLI.isOperationLegal(ISD::FABS, Tmp1.getValueType()) &&
+          TLI.isOperationLegal(ISD::FNEG, Tmp1.getValueType())) {
+        // Get the sign bit of the RHS.
+        MVT::ValueType IVT = 
+          Tmp2.getValueType() == MVT::f32 ? MVT::i32 : MVT::i64;
+        SDOperand SignBit = DAG.getNode(ISD::BIT_CONVERT, IVT, Tmp2);
+        SignBit = DAG.getSetCC(TLI.getSetCCResultTy(),
+                               SignBit, DAG.getConstant(0, IVT), ISD::SETLT);
+        // Get the absolute value of the result.
+        SDOperand AbsVal = DAG.getNode(ISD::FABS, Tmp1.getValueType(), Tmp1);
+        // Select between the nabs and abs value based on the sign bit of
+        // the input.
+        Result = DAG.getNode(ISD::SELECT, AbsVal.getValueType(), SignBit,
+                             DAG.getNode(ISD::FNEG, AbsVal.getValueType(), 
+                                         AbsVal),
+                             AbsVal);
+        Result = LegalizeOp(Result);
+        break;
+      }
+      
+      // Otherwise, do bitwise ops!
+      
+      // copysign -> copysignf/copysign libcall.
+      const char *FnName;
+      if (Node->getValueType(0) == MVT::f32) {
+        FnName = "copysignf";
+        if (Tmp2.getValueType() != MVT::f32)  // Force operands to match type.
+          Result = DAG.UpdateNodeOperands(Result, Tmp1, 
+                                    DAG.getNode(ISD::FP_ROUND, MVT::f32, Tmp2));
+      } else {
+        FnName = "copysign";
+        if (Tmp2.getValueType() != MVT::f64)  // Force operands to match type.
+          Result = DAG.UpdateNodeOperands(Result, Tmp1, 
+                                   DAG.getNode(ISD::FP_EXTEND, MVT::f64, Tmp2));
+      }
+      SDOperand Dummy;
+      Result = ExpandLibCall(FnName, Node, Dummy);
+      break;
+    }
+    break;
+    
+  case ISD::ADDC:
+  case ISD::SUBC:
+    Tmp1 = LegalizeOp(Node->getOperand(0));
+    Tmp2 = LegalizeOp(Node->getOperand(1));
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+    // Since this produces two values, make sure to remember that we legalized
+    // both of them.
+    AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0));
+    AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
+    return Result;
+
+  case ISD::ADDE:
+  case ISD::SUBE:
+    Tmp1 = LegalizeOp(Node->getOperand(0));
+    Tmp2 = LegalizeOp(Node->getOperand(1));
+    Tmp3 = LegalizeOp(Node->getOperand(2));
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
+    // Since this produces two values, make sure to remember that we legalized
+    // both of them.
+    AddLegalizedOperand(SDOperand(Node, 0), Result.getValue(0));
+    AddLegalizedOperand(SDOperand(Node, 1), Result.getValue(1));
+    return Result;
+    
+  case ISD::BUILD_PAIR: {
+    MVT::ValueType PairTy = Node->getValueType(0);
+    // TODO: handle the case where the Lo and Hi operands are not of legal type
+    Tmp1 = LegalizeOp(Node->getOperand(0));   // Lo
+    Tmp2 = LegalizeOp(Node->getOperand(1));   // Hi
+    switch (TLI.getOperationAction(ISD::BUILD_PAIR, PairTy)) {
+    case TargetLowering::Promote:
+    case TargetLowering::Custom:
+      assert(0 && "Cannot promote/custom this yet!");
+    case TargetLowering::Legal:
+      if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1))
+        Result = DAG.getNode(ISD::BUILD_PAIR, PairTy, Tmp1, Tmp2);
+      break;
+    case TargetLowering::Expand:
+      Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, PairTy, Tmp1);
+      Tmp2 = DAG.getNode(ISD::ANY_EXTEND, PairTy, Tmp2);
+      Tmp2 = DAG.getNode(ISD::SHL, PairTy, Tmp2,
+                         DAG.getConstant(MVT::getSizeInBits(PairTy)/2, 
+                                         TLI.getShiftAmountTy()));
+      Result = DAG.getNode(ISD::OR, PairTy, Tmp1, Tmp2);
+      break;
+    }
+    break;
+  }
+
+  case ISD::UREM:
+  case ISD::SREM:
+  case ISD::FREM:
+    Tmp1 = LegalizeOp(Node->getOperand(0));   // LHS
+    Tmp2 = LegalizeOp(Node->getOperand(1));   // RHS
+
+    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
+    case TargetLowering::Promote: assert(0 && "Cannot promote this yet!");
+    case TargetLowering::Custom:
+      isCustom = true;
+      // FALLTHROUGH
+    case TargetLowering::Legal:
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+      if (isCustom) {
+        Tmp1 = TLI.LowerOperation(Result, DAG);
+        if (Tmp1.Val) Result = Tmp1;
+      }
+      break;
+    case TargetLowering::Expand:
+      if (MVT::isInteger(Node->getValueType(0))) {
+        // X % Y -> X-X/Y*Y
+        MVT::ValueType VT = Node->getValueType(0);
+        unsigned Opc = Node->getOpcode() == ISD::UREM ? ISD::UDIV : ISD::SDIV;
+        Result = DAG.getNode(Opc, VT, Tmp1, Tmp2);
+        Result = DAG.getNode(ISD::MUL, VT, Result, Tmp2);
+        Result = DAG.getNode(ISD::SUB, VT, Tmp1, Result);
+      } else {
+        // Floating point mod -> fmod libcall.
+        const char *FnName = Node->getValueType(0) == MVT::f32 ? "fmodf":"fmod";
+        SDOperand Dummy;
+        Result = ExpandLibCall(FnName, Node, Dummy);
+      }
+      break;
+    }
+    break;
+  case ISD::VAARG: {
+    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
+    Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the pointer.
+
+    MVT::ValueType VT = Node->getValueType(0);
+    switch (TLI.getOperationAction(Node->getOpcode(), MVT::Other)) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Custom:
+      isCustom = true;
+      // FALLTHROUGH
+    case TargetLowering::Legal:
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
+      Result = Result.getValue(0);
+      Tmp1 = Result.getValue(1);
+
+      if (isCustom) {
+        Tmp2 = TLI.LowerOperation(Result, DAG);
+        if (Tmp2.Val) {
+          Result = LegalizeOp(Tmp2);
+          Tmp1 = LegalizeOp(Tmp2.getValue(1));
+        }
+      }
+      break;
+    case TargetLowering::Expand: {
+      SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2,
+                                     Node->getOperand(2));
+      // Increment the pointer, VAList, to the next vaarg
+      Tmp3 = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList, 
+                         DAG.getConstant(MVT::getSizeInBits(VT)/8, 
+                                         TLI.getPointerTy()));
+      // Store the incremented VAList to the legalized pointer
+      Tmp3 = DAG.getNode(ISD::STORE, MVT::Other, VAList.getValue(1), Tmp3, Tmp2, 
+                         Node->getOperand(2));
+      // Load the actual argument out of the pointer VAList
+      Result = DAG.getLoad(VT, Tmp3, VAList, DAG.getSrcValue(0));
+      Tmp1 = LegalizeOp(Result.getValue(1));
+      Result = LegalizeOp(Result);
+      break;
+    }
+    }
+    // Since VAARG produces two values, make sure to remember that we 
+    // legalized both of them.
+    AddLegalizedOperand(SDOperand(Node, 0), Result);
+    AddLegalizedOperand(SDOperand(Node, 1), Tmp1);
+    return Op.ResNo ? Tmp1 : Result;
+  }
+    
+  case ISD::VACOPY: 
+    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
+    Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the dest pointer.
+    Tmp3 = LegalizeOp(Node->getOperand(2));  // Legalize the source pointer.
+
+    switch (TLI.getOperationAction(ISD::VACOPY, MVT::Other)) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Custom:
+      isCustom = true;
+      // FALLTHROUGH
     case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0) ||
-         Tmp2 != Node->getOperand(1))
-       Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1,Tmp2);
-      break;
-    case TargetLowering::Custom: {
-      Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1, Tmp2);
-      SDOperand Tmp = TLI.LowerOperation(Result, DAG);
-      if (Tmp.Val) {
-       Tmp = LegalizeOp(Tmp);  // Relegalize input.
-       AddLegalizedOperand(Op, Tmp);
-       return Tmp;
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3,
+                                      Node->getOperand(3), Node->getOperand(4));
+      if (isCustom) {
+        Tmp1 = TLI.LowerOperation(Result, DAG);
+        if (Tmp1.Val) Result = Tmp1;
       }
       break;
-    }
-    default:
-      assert(0 && "Operation not supported");
+    case TargetLowering::Expand:
+      // This defaults to loading a pointer from the input and storing it to the
+      // output, returning the chain.
+      Tmp4 = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp3, Node->getOperand(3));
+      Result = DAG.getNode(ISD::STORE, MVT::Other, Tmp4.getValue(1), Tmp4, Tmp2,
+                           Node->getOperand(4));
+      break;
     }
     break;
 
-  case ISD::BUILD_PAIR: {
-    MVT::ValueType PairTy = Node->getValueType(0);
-    // TODO: handle the case where the Lo and Hi operands are not of legal type
-    Tmp1 = LegalizeOp(Node->getOperand(0));   // Lo
-    Tmp2 = LegalizeOp(Node->getOperand(1));   // Hi
-    switch (TLI.getOperationAction(ISD::BUILD_PAIR, PairTy)) {
+  case ISD::VAEND: 
+    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
+    Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the pointer.
+
+    switch (TLI.getOperationAction(ISD::VAEND, MVT::Other)) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Custom:
+      isCustom = true;
+      // FALLTHROUGH
     case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1))
-        Result = DAG.getNode(ISD::BUILD_PAIR, PairTy, Tmp1, Tmp2);
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
+      if (isCustom) {
+        Tmp1 = TLI.LowerOperation(Tmp1, DAG);
+        if (Tmp1.Val) Result = Tmp1;
+      }
       break;
-    case TargetLowering::Promote:
-    case TargetLowering::Custom:
-      assert(0 && "Cannot promote/custom this yet!");
     case TargetLowering::Expand:
-      Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, PairTy, Tmp1);
-      Tmp2 = DAG.getNode(ISD::ANY_EXTEND, PairTy, Tmp2);
-      Tmp2 = DAG.getNode(ISD::SHL, PairTy, Tmp2,
-                         DAG.getConstant(MVT::getSizeInBits(PairTy)/2, 
-                                         TLI.getShiftAmountTy()));
-      Result = LegalizeOp(DAG.getNode(ISD::OR, PairTy, Tmp1, Tmp2));
+      Result = Tmp1; // Default to a no-op, return the chain
       break;
     }
     break;
-  }
+    
+  case ISD::VASTART: 
+    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
+    Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the pointer.
 
-  case ISD::UREM:
-  case ISD::SREM:
-  case ISD::FREM:
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
+    
+    switch (TLI.getOperationAction(ISD::VASTART, MVT::Other)) {
+    default: assert(0 && "This action is not supported yet!");
+    case TargetLowering::Legal: break;
+    case TargetLowering::Custom:
+      Tmp1 = TLI.LowerOperation(Result, DAG);
+      if (Tmp1.Val) Result = Tmp1;
+      break;
+    }
+    break;
+    
+  case ISD::ROTL:
+  case ISD::ROTR:
     Tmp1 = LegalizeOp(Node->getOperand(0));   // LHS
     Tmp2 = LegalizeOp(Node->getOperand(1));   // RHS
+    
+    assert(TLI.isOperationLegal(Node->getOpcode(), Node->getValueType(0)) &&
+           "Cannot handle this yet!");
+    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+    break;
+    
+  case ISD::BSWAP:
+    Tmp1 = LegalizeOp(Node->getOperand(0));   // Op
     switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
+    case TargetLowering::Custom:
+      assert(0 && "Cannot custom legalize this yet!");
     case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0) ||
-          Tmp2 != Node->getOperand(1))
-        Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1,
-                             Tmp2);
+      Result = DAG.UpdateNodeOperands(Result, Tmp1);
       break;
-    case TargetLowering::Promote:
-      assert(0 && "Cannot promote handle this yet!");
-    case TargetLowering::Custom: {
-      Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1, Tmp2);
-      SDOperand Tmp = TLI.LowerOperation(Result, DAG);
-      if (Tmp.Val) {
-       Tmp = LegalizeOp(Tmp);  // Relegalize input.
-       AddLegalizedOperand(Op, Tmp);
-       return Tmp;
-      }
+    case TargetLowering::Promote: {
+      MVT::ValueType OVT = Tmp1.getValueType();
+      MVT::ValueType NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT);
+      unsigned DiffBits = getSizeInBits(NVT) - getSizeInBits(OVT);
+
+      Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Tmp1);
+      Tmp1 = DAG.getNode(ISD::BSWAP, NVT, Tmp1);
+      Result = DAG.getNode(ISD::SRL, NVT, Tmp1,
+                           DAG.getConstant(DiffBits, TLI.getShiftAmountTy()));
       break;
     }
     case TargetLowering::Expand:
-      if (MVT::isInteger(Node->getValueType(0))) {
-        MVT::ValueType VT = Node->getValueType(0);
-        unsigned Opc = (Node->getOpcode() == ISD::UREM) ? ISD::UDIV : ISD::SDIV;
-        Result = DAG.getNode(Opc, VT, Tmp1, Tmp2);
-        Result = DAG.getNode(ISD::MUL, VT, Result, Tmp2);
-        Result = DAG.getNode(ISD::SUB, VT, Tmp1, Result);
-      } else {
-        // Floating point mod -> fmod libcall.
-        const char *FnName = Node->getValueType(0) == MVT::f32 ? "fmodf":"fmod";
-        SDOperand Dummy;
-        Result = ExpandLibCall(FnName, Node, Dummy);
-      }
+      Result = ExpandBSWAP(Tmp1);
       break;
     }
     break;
-
+    
   case ISD::CTPOP:
   case ISD::CTTZ:
   case ISD::CTLZ:
     Tmp1 = LegalizeOp(Node->getOperand(0));   // Op
     switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
+    case TargetLowering::Custom: assert(0 && "Cannot custom handle this yet!");
     case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0))
-        Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
+      Result = DAG.UpdateNodeOperands(Result, Tmp1);
       break;
     case TargetLowering::Promote: {
       MVT::ValueType OVT = Tmp1.getValueType();
@@ -2059,8 +2211,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Tmp1);
       // Perform the larger operation, then subtract if needed.
       Tmp1 = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
-      switch(Node->getOpcode())
-      {
+      switch (Node->getOpcode()) {
       case ISD::CTPOP:
         Result = Tmp1;
         break;
@@ -2073,7 +2224,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
                            DAG.getConstant(getSizeInBits(OVT),NVT), Tmp1);
         break;
       case ISD::CTLZ:
-        //Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT))
+        // Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT))
         Result = DAG.getNode(ISD::SUB, NVT, Tmp1,
                              DAG.getConstant(getSizeInBits(NVT) -
                                              getSizeInBits(OVT), NVT));
@@ -2081,81 +2232,8 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       }
       break;
     }
-    case TargetLowering::Custom:
-      assert(0 && "Cannot custom handle this yet!");
     case TargetLowering::Expand:
-      switch(Node->getOpcode())
-      {
-      case ISD::CTPOP: {
-        static const uint64_t mask[6] = {
-          0x5555555555555555ULL, 0x3333333333333333ULL,
-          0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL,
-          0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL
-        };
-        MVT::ValueType VT = Tmp1.getValueType();
-        MVT::ValueType ShVT = TLI.getShiftAmountTy();
-        unsigned len = getSizeInBits(VT);
-        for (unsigned i = 0; (1U << i) <= (len / 2); ++i) {
-          //x = (x & mask[i][len/8]) + (x >> (1 << i) & mask[i][len/8])
-          Tmp2 = DAG.getConstant(mask[i], VT);
-          Tmp3 = DAG.getConstant(1ULL << i, ShVT);
-          Tmp1 = DAG.getNode(ISD::ADD, VT,
-                             DAG.getNode(ISD::AND, VT, Tmp1, Tmp2),
-                             DAG.getNode(ISD::AND, VT,
-                                         DAG.getNode(ISD::SRL, VT, Tmp1, Tmp3),
-                                         Tmp2));
-        }
-        Result = Tmp1;
-        break;
-      }
-      case ISD::CTLZ: {
-        /* for now, we do this:
-           x = x | (x >> 1);
-           x = x | (x >> 2);
-           ...
-           x = x | (x >>16);
-           x = x | (x >>32); // for 64-bit input
-           return popcount(~x);
-
-           but see also: http://www.hackersdelight.org/HDcode/nlz.cc */
-        MVT::ValueType VT = Tmp1.getValueType();
-        MVT::ValueType ShVT = TLI.getShiftAmountTy();
-        unsigned len = getSizeInBits(VT);
-        for (unsigned i = 0; (1U << i) <= (len / 2); ++i) {
-          Tmp3 = DAG.getConstant(1ULL << i, ShVT);
-          Tmp1 = DAG.getNode(ISD::OR, VT, Tmp1,
-                             DAG.getNode(ISD::SRL, VT, Tmp1, Tmp3));
-        }
-        Tmp3 = DAG.getNode(ISD::XOR, VT, Tmp1, DAG.getConstant(~0ULL, VT));
-        Result = LegalizeOp(DAG.getNode(ISD::CTPOP, VT, Tmp3));
-        break;
-      }
-      case ISD::CTTZ: {
-        // for now, we use: { return popcount(~x & (x - 1)); }
-        // unless the target has ctlz but not ctpop, in which case we use:
-        // { return 32 - nlz(~x & (x-1)); }
-        // see also http://www.hackersdelight.org/HDcode/ntz.cc
-        MVT::ValueType VT = Tmp1.getValueType();
-        Tmp2 = DAG.getConstant(~0ULL, VT);
-        Tmp3 = DAG.getNode(ISD::AND, VT,
-                           DAG.getNode(ISD::XOR, VT, Tmp1, Tmp2),
-                           DAG.getNode(ISD::SUB, VT, Tmp1,
-                                       DAG.getConstant(1, VT)));
-        // If ISD::CTLZ is legal and CTPOP isn't, then do that instead
-        if (!TLI.isOperationLegal(ISD::CTPOP, VT) &&
-            TLI.isOperationLegal(ISD::CTLZ, VT)) {
-          Result = LegalizeOp(DAG.getNode(ISD::SUB, VT,
-                                        DAG.getConstant(getSizeInBits(VT), VT),
-                                        DAG.getNode(ISD::CTLZ, VT, Tmp3)));
-        } else {
-          Result = LegalizeOp(DAG.getNode(ISD::CTPOP, VT, Tmp3));
-        }
-        break;
-      }
-      default:
-        assert(0 && "Cannot expand this yet!");
-        break;
-      }
+      Result = ExpandBitCount(Node->getOpcode(), Tmp1);
       break;
     }
     break;
@@ -2168,22 +2246,25 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
   case ISD::FCOS:
     Tmp1 = LegalizeOp(Node->getOperand(0));
     switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
-    case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0))
-        Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
-      break;
     case TargetLowering::Promote:
     case TargetLowering::Custom:
-      assert(0 && "Cannot promote/custom handle this yet!");
+     isCustom = true;
+     // FALLTHROUGH
+    case TargetLowering::Legal:
+      Result = DAG.UpdateNodeOperands(Result, Tmp1);
+      if (isCustom) {
+        Tmp1 = TLI.LowerOperation(Result, DAG);
+        if (Tmp1.Val) Result = Tmp1;
+      }
+      break;
     case TargetLowering::Expand:
-      switch(Node->getOpcode()) {
-      case ISD::FNEG: {
+      switch (Node->getOpcode()) {
+      default: assert(0 && "Unreachable!");
+      case ISD::FNEG:
         // Expand Y = FNEG(X) ->  Y = SUB -0.0, X
         Tmp2 = DAG.getConstantFP(-0.0, Node->getValueType(0));
-        Result = LegalizeOp(DAG.getNode(ISD::FSUB, Node->getValueType(0),
-                                        Tmp2, Tmp1));
+        Result = DAG.getNode(ISD::FSUB, Node->getValueType(0), Tmp2, Tmp1);
         break;
-      }
       case ISD::FABS: {
         // Expand Y = FABS(X) -> Y = (X >u 0.0) ? X : fneg(X).
         MVT::ValueType VT = Node->getValueType(0);
@@ -2191,7 +2272,6 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), Tmp1, Tmp2, ISD::SETUGT);
         Tmp3 = DAG.getNode(ISD::FNEG, VT, Tmp1);
         Result = DAG.getNode(ISD::SELECT, VT, Tmp2, Tmp1, Tmp3);
-        Result = LegalizeOp(Result);
         break;
       }
       case ISD::FSQRT:
@@ -2209,17 +2289,15 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         Result = ExpandLibCall(FnName, Node, Dummy);
         break;
       }
-      default:
-        assert(0 && "Unreachable!");
       }
       break;
     }
     break;
     
   case ISD::BIT_CONVERT:
-    if (!isTypeLegal(Node->getOperand(0).getValueType()))
+    if (!isTypeLegal(Node->getOperand(0).getValueType())) {
       Result = ExpandBIT_CONVERT(Node->getValueType(0), Node->getOperand(0));
-    else {
+    else {
       switch (TLI.getOperationAction(ISD::BIT_CONVERT,
                                      Node->getOperand(0).getValueType())) {
       default: assert(0 && "Unknown operation action!");
@@ -2228,8 +2306,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
         break;
       case TargetLowering::Legal:
         Tmp1 = LegalizeOp(Node->getOperand(0));
-        if (Tmp1 != Node->getOperand(0))
-          Result = DAG.getNode(ISD::BIT_CONVERT, Node->getValueType(0), Tmp1);
+        Result = DAG.UpdateNodeOperands(Result, Tmp1);
         break;
       }
     }
@@ -2243,55 +2320,44 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       switch (TLI.getOperationAction(Node->getOpcode(),
                                      Node->getOperand(0).getValueType())) {
       default: assert(0 && "Unknown operation action!");
+      case TargetLowering::Custom:
+        isCustom = true;
+        // FALLTHROUGH
+      case TargetLowering::Legal:
+        Tmp1 = LegalizeOp(Node->getOperand(0));
+        Result = DAG.UpdateNodeOperands(Result, Tmp1);
+        if (isCustom) {
+          Tmp1 = TLI.LowerOperation(Result, DAG);
+          if (Tmp1.Val) Result = Tmp1;
+        }
+        break;
       case TargetLowering::Expand:
         Result = ExpandLegalINT_TO_FP(isSigned,
                                       LegalizeOp(Node->getOperand(0)),
                                       Node->getValueType(0));
-        AddLegalizedOperand(Op, Result);
-        return Result;
+        break;
       case TargetLowering::Promote:
         Result = PromoteLegalINT_TO_FP(LegalizeOp(Node->getOperand(0)),
                                        Node->getValueType(0),
                                        isSigned);
-        AddLegalizedOperand(Op, Result);
-        return Result;
-      case TargetLowering::Legal:
         break;
-      case TargetLowering::Custom: {
-        Tmp1 = LegalizeOp(Node->getOperand(0));
-        SDOperand Tmp =
-          DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
-        Tmp = TLI.LowerOperation(Tmp, DAG);
-        if (Tmp.Val) {
-          Tmp = LegalizeOp(Tmp);  // Relegalize input.
-          AddLegalizedOperand(Op, Tmp);
-          return Tmp;
-        } else {
-          assert(0 && "Target Must Lower this");
-        }
       }
-      }
-
-      Tmp1 = LegalizeOp(Node->getOperand(0));
-      if (Tmp1 != Node->getOperand(0))
-        Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
       break;
     case Expand:
       Result = ExpandIntToFP(Node->getOpcode() == ISD::SINT_TO_FP,
                              Node->getValueType(0), Node->getOperand(0));
       break;
     case Promote:
+      Tmp1 = PromoteOp(Node->getOperand(0));
       if (isSigned) {
-        Result = PromoteOp(Node->getOperand(0));
-        Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(),
-                 Result, DAG.getValueType(Node->getOperand(0).getValueType()));
-        Result = DAG.getNode(ISD::SINT_TO_FP, Op.getValueType(), Result);
+        Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, Tmp1.getValueType(),
+                 Tmp1, DAG.getValueType(Node->getOperand(0).getValueType()));
       } else {
-        Result = PromoteOp(Node->getOperand(0));
-        Result = DAG.getZeroExtendInReg(Result,
-                                        Node->getOperand(0).getValueType());
-        Result = DAG.getNode(ISD::UINT_TO_FP, Op.getValueType(), Result);
+        Tmp1 = DAG.getZeroExtendInReg(Tmp1,
+                                      Node->getOperand(0).getValueType());
       }
+      Result = DAG.UpdateNodeOperands(Result, Tmp1);
+      Result = LegalizeOp(Result);  // The 'op' is not necessarily legal!
       break;
     }
     break;
@@ -2300,8 +2366,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     switch (getTypeAction(Node->getOperand(0).getValueType())) {
     case Legal:
       Tmp1 = LegalizeOp(Node->getOperand(0));
-      if (Tmp1 != Node->getOperand(0))
-        Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
+      Result = DAG.UpdateNodeOperands(Result, Tmp1);
       break;
     case Expand:
       ExpandOp(Node->getOperand(0), Tmp1, Tmp2);
@@ -2325,6 +2390,20 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
 
       switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))){
       default: assert(0 && "Unknown operation action!");
+      case TargetLowering::Custom:
+        isCustom = true;
+        // FALLTHROUGH
+      case TargetLowering::Legal:
+        Result = DAG.UpdateNodeOperands(Result, Tmp1);
+        if (isCustom) {
+          Tmp1 = TLI.LowerOperation(Result, DAG);
+          if (Tmp1.Val) Result = Tmp1;
+        }
+        break;
+      case TargetLowering::Promote:
+        Result = PromoteLegalFP_TO_INT(Tmp1, Node->getValueType(0),
+                                       Node->getOpcode() == ISD::FP_TO_SINT);
+        break;
       case TargetLowering::Expand:
         if (Node->getOpcode() == ISD::FP_TO_UINT) {
           SDOperand True, False;
@@ -2340,43 +2419,20 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
                                           Tmp2));
           False = DAG.getNode(ISD::XOR, NVT, False, 
                               DAG.getConstant(1ULL << ShiftAmt, NVT));
-          Result = LegalizeOp(DAG.getNode(ISD::SELECT, NVT, Tmp3, True, False));
-          AddLegalizedOperand(SDOperand(Node, 0), Result);
-          return Result;
+          Result = DAG.getNode(ISD::SELECT, NVT, Tmp3, True, False);
+          break;
         } else {
           assert(0 && "Do not know how to expand FP_TO_SINT yet!");
         }
         break;
-      case TargetLowering::Promote:
-        Result = PromoteLegalFP_TO_INT(Tmp1, Node->getValueType(0),
-                                       Node->getOpcode() == ISD::FP_TO_SINT);
-        AddLegalizedOperand(Op, Result);
-        return Result;
-      case TargetLowering::Custom: {
-        SDOperand Tmp =
-          DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
-        Tmp = TLI.LowerOperation(Tmp, DAG);
-        if (Tmp.Val) {
-          Tmp = LegalizeOp(Tmp);
-          AddLegalizedOperand(Op, Tmp);
-          return Tmp;
-        } else {
-          // The target thinks this is legal afterall.
-          break;
-        }
-      }
-      case TargetLowering::Legal:
-        break;
       }
-
-      if (Tmp1 != Node->getOperand(0))
-        Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
       break;
     case Expand:
       assert(0 && "Shouldn't need to expand other operators here!");
     case Promote:
-      Result = PromoteOp(Node->getOperand(0));
-      Result = DAG.getNode(Node->getOpcode(), Op.getValueType(), Result);
+      Tmp1 = PromoteOp(Node->getOperand(0));
+      Result = DAG.UpdateNodeOperands(Result, LegalizeOp(Tmp1));
+      Result = LegalizeOp(Result);
       break;
     }
     break;
@@ -2387,19 +2443,16 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
   case ISD::FP_EXTEND:
   case ISD::FP_ROUND:
     switch (getTypeAction(Node->getOperand(0).getValueType())) {
+    case Expand: assert(0 && "Shouldn't need to expand other operators here!");
     case Legal:
       Tmp1 = LegalizeOp(Node->getOperand(0));
-      if (Tmp1 != Node->getOperand(0))
-        Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1);
+      Result = DAG.UpdateNodeOperands(Result, Tmp1);
       break;
-    case Expand:
-      assert(0 && "Shouldn't need to expand other operators here!");
-
     case Promote:
       switch (Node->getOpcode()) {
       case ISD::ANY_EXTEND:
-        Result = PromoteOp(Node->getOperand(0));
-        Result = DAG.getNode(ISD::ANY_EXTEND, Op.getValueType(), Result);
+        Tmp1 = PromoteOp(Node->getOperand(0));
+        Result = DAG.getNode(ISD::ANY_EXTEND, Op.getValueType(), Tmp1);
         break;
       case ISD::ZERO_EXTEND:
         Result = PromoteOp(Node->getOperand(0));
@@ -2437,9 +2490,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
     switch (TLI.getOperationAction(Node->getOpcode(), ExtraVT)) {
     default: assert(0 && "This action not supported for this op yet!");
     case TargetLowering::Legal:
-      if (Tmp1 != Node->getOperand(0))
-        Result = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1,
-                             DAG.getValueType(ExtraVT));
+      Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1));
       break;
     case TargetLowering::Expand:
       // If this is an integer extend and shifts are supported, do that.
@@ -2476,12 +2527,15 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
       } else {
         assert(0 && "Unknown op");
       }
-      Result = LegalizeOp(Result);
       break;
     }
     break;
   }
   }
+  
+  // Make sure that the generated code is itself legal.
+  if (Result != Op)
+    Result = LegalizeOp(Result);
 
   // Note that LegalizeOp may be reentered even from single-use nodes, which
   // means that we always must cache transformed nodes.
@@ -2502,18 +2556,12 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
          "Cannot promote to smaller type!");
 
   SDOperand Tmp1, Tmp2, Tmp3;
-
   SDOperand Result;
   SDNode *Node = Op.Val;
 
   std::map<SDOperand, SDOperand>::iterator I = PromotedNodes.find(Op);
   if (I != PromotedNodes.end()) return I->second;
 
-  // Promotion needs an optimization step to clean up after it, and is not
-  // careful to avoid operations the target does not support.  Make sure that
-  // all generated operations are legalized in the next iteration.
-  NeedsAnotherIteration = true;
-
   switch (Node->getOpcode()) {
   case ISD::CopyFromReg:
     assert(0 && "CopyFromReg must be legal!");
@@ -2540,7 +2588,6 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
     assert(isTypeLegal(TLI.getSetCCResultTy()) && "SetCC type is not legal??");
     Result = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(),Node->getOperand(0),
                          Node->getOperand(1), Node->getOperand(2));
-    Result = LegalizeOp(Result);
     break;
 
   case ISD::TRUNCATE:
@@ -2570,8 +2617,7 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
     case Expand: assert(0 && "BUG: Smaller reg should have been promoted!");
     case Legal:
       // Input is legal?  Just do extend all the way to the larger type.
-      Result = LegalizeOp(Node->getOperand(0));
-      Result = DAG.getNode(Node->getOpcode(), NVT, Result);
+      Result = DAG.getNode(Node->getOpcode(), NVT, Node->getOperand(0));
       break;
     case Promote:
       // Promote the reg if it's smaller.
@@ -2599,8 +2645,7 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
     case Promote:  assert(0 && "Unreachable with 2 FP types!");
     case Legal:
       // Input is legal?  Do an FP_ROUND_INREG.
-      Result = LegalizeOp(Node->getOperand(0));
-      Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
+      Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Node->getOperand(0),
                            DAG.getValueType(VT));
       break;
     }
@@ -2610,9 +2655,8 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
   case ISD::UINT_TO_FP:
     switch (getTypeAction(Node->getOperand(0).getValueType())) {
     case Legal:
-      Result = LegalizeOp(Node->getOperand(0));
       // No extra round required here.
-      Result = DAG.getNode(Node->getOpcode(), NVT, Result);
+      Result = DAG.getNode(Node->getOpcode(), NVT, Node->getOperand(0));
       break;
 
     case Promote:
@@ -2647,7 +2691,7 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
   case ISD::FP_TO_UINT:
     switch (getTypeAction(Node->getOperand(0).getValueType())) {
     case Legal:
-      Tmp1 = LegalizeOp(Node->getOperand(0));
+      Tmp1 = Node->getOperand(0);
       break;
     case Promote:
       // The input result is prerounded, so we don't have to do anything
@@ -2688,7 +2732,7 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
     Tmp1 = PromoteOp(Node->getOperand(0));
     assert(Tmp1.getValueType() == NVT);
     Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1);
-    if(NoExcessFPPrecision)
+    if (NoExcessFPPrecision)
       Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
                            DAG.getValueType(VT));
     break;
@@ -2710,8 +2754,6 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
   case ISD::FADD:
   case ISD::FSUB:
   case ISD::FMUL:
-    // The input may have strange things in the top bits of the registers, but
-    // these operations don't care.
     Tmp1 = PromoteOp(Node->getOperand(0));
     Tmp2 = PromoteOp(Node->getOperand(1));
     assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT);
@@ -2747,13 +2789,14 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
     break;
   case ISD::FDIV:
   case ISD::FREM:
+  case ISD::FCOPYSIGN:
     // These operators require that their input be fp extended.
     Tmp1 = PromoteOp(Node->getOperand(0));
     Tmp2 = PromoteOp(Node->getOperand(1));
     Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2);
     
     // Perform FP_ROUND: this is probably overly pessimistic.
-    if (NoExcessFPPrecision)
+    if (NoExcessFPPrecision && Node->getOpcode() != ISD::FCOPYSIGN)
       Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result,
                            DAG.getValueType(VT));
     break;
@@ -2771,106 +2814,97 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
 
   case ISD::SHL:
     Tmp1 = PromoteOp(Node->getOperand(0));
-    Tmp2 = LegalizeOp(Node->getOperand(1));
-    Result = DAG.getNode(ISD::SHL, NVT, Tmp1, Tmp2);
+    Result = DAG.getNode(ISD::SHL, NVT, Tmp1, Node->getOperand(1));
     break;
   case ISD::SRA:
     // The input value must be properly sign extended.
     Tmp1 = PromoteOp(Node->getOperand(0));
     Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1,
                        DAG.getValueType(VT));
-    Tmp2 = LegalizeOp(Node->getOperand(1));
-    Result = DAG.getNode(ISD::SRA, NVT, Tmp1, Tmp2);
+    Result = DAG.getNode(ISD::SRA, NVT, Tmp1, Node->getOperand(1));
     break;
   case ISD::SRL:
     // The input value must be properly zero extended.
     Tmp1 = PromoteOp(Node->getOperand(0));
     Tmp1 = DAG.getZeroExtendInReg(Tmp1, VT);
-    Tmp2 = LegalizeOp(Node->getOperand(1));
-    Result = DAG.getNode(ISD::SRL, NVT, Tmp1, Tmp2);
+    Result = DAG.getNode(ISD::SRL, NVT, Tmp1, Node->getOperand(1));
+    break;
+
+  case ISD::VAARG:
+    Tmp1 = Node->getOperand(0);   // Get the chain.
+    Tmp2 = Node->getOperand(1);   // Get the pointer.
+    if (TLI.getOperationAction(ISD::VAARG, VT) == TargetLowering::Custom) {
+      Tmp3 = DAG.getVAArg(VT, Tmp1, Tmp2, Node->getOperand(2));
+      Result = TLI.CustomPromoteOperation(Tmp3, DAG);
+    } else {
+      SDOperand VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2,
+                                     Node->getOperand(2));
+      // Increment the pointer, VAList, to the next vaarg
+      Tmp3 = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList, 
+                         DAG.getConstant(MVT::getSizeInBits(VT)/8, 
+                                         TLI.getPointerTy()));
+      // Store the incremented VAList to the legalized pointer
+      Tmp3 = DAG.getNode(ISD::STORE, MVT::Other, VAList.getValue(1), Tmp3, Tmp2, 
+                         Node->getOperand(2));
+      // Load the actual argument out of the pointer VAList
+      Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp3, VAList,
+                              DAG.getSrcValue(0), VT);
+    }
+    // Remember that we legalized the chain.
+    AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1)));
     break;
+
   case ISD::LOAD:
-    Tmp1 = LegalizeOp(Node->getOperand(0));   // Legalize the chain.
-    Tmp2 = LegalizeOp(Node->getOperand(1));   // Legalize the pointer.
-    Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp1, Tmp2,
-                            Node->getOperand(2), VT);
+    Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Node->getOperand(0),
+                            Node->getOperand(1), Node->getOperand(2), VT);
     // Remember that we legalized the chain.
-    AddLegalizedOperand(Op.getValue(1), Result.getValue(1));
+    AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1)));
     break;
   case ISD::SEXTLOAD:
   case ISD::ZEXTLOAD:
   case ISD::EXTLOAD:
-    Tmp1 = LegalizeOp(Node->getOperand(0));   // Legalize the chain.
-    Tmp2 = LegalizeOp(Node->getOperand(1));   // Legalize the pointer.
-    Result = DAG.getExtLoad(Node->getOpcode(), NVT, Tmp1, Tmp2,
-                         Node->getOperand(2),
+    Result = DAG.getExtLoad(Node->getOpcode(), NVT, Node->getOperand(0),
+                            Node->getOperand(1), Node->getOperand(2),
                             cast<VTSDNode>(Node->getOperand(3))->getVT());
     // Remember that we legalized the chain.
-    AddLegalizedOperand(Op.getValue(1), Result.getValue(1));
+    AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1)));
     break;
   case ISD::SELECT:
-    switch (getTypeAction(Node->getOperand(0).getValueType())) {
-    case Expand: assert(0 && "It's impossible to expand bools");
-    case Legal:
-      Tmp1 = LegalizeOp(Node->getOperand(0));// Legalize the condition.
-      break;
-    case Promote:
-      Tmp1 = PromoteOp(Node->getOperand(0)); // Promote the condition.
-      break;
-    }
     Tmp2 = PromoteOp(Node->getOperand(1));   // Legalize the op0
     Tmp3 = PromoteOp(Node->getOperand(2));   // Legalize the op1
-    Result = DAG.getNode(ISD::SELECT, NVT, Tmp1, Tmp2, Tmp3);
+    Result = DAG.getNode(ISD::SELECT, NVT, Node->getOperand(0), Tmp2, Tmp3);
     break;
   case ISD::SELECT_CC:
     Tmp2 = PromoteOp(Node->getOperand(2));   // True
     Tmp3 = PromoteOp(Node->getOperand(3));   // False
     Result = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0),
-                         Node->getOperand(1), Tmp2, Tmp3,
-                         Node->getOperand(4));
+                         Node->getOperand(1), Tmp2, Tmp3, Node->getOperand(4));
     break;
-  case ISD::TAILCALL:
-  case ISD::CALL: {
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the callee.
-
-    std::vector<SDOperand> Ops;
-    for (unsigned i = 2, e = Node->getNumOperands(); i != e; ++i)
-      Ops.push_back(LegalizeOp(Node->getOperand(i)));
-
-    assert(Node->getNumValues() == 2 && Op.ResNo == 0 &&
-           "Can only promote single result calls");
-    std::vector<MVT::ValueType> RetTyVTs;
-    RetTyVTs.reserve(2);
-    RetTyVTs.push_back(NVT);
-    RetTyVTs.push_back(MVT::Other);
-    SDNode *NC = DAG.getCall(RetTyVTs, Tmp1, Tmp2, Ops,
-                             Node->getOpcode() == ISD::TAILCALL);
-    Result = SDOperand(NC, 0);
-
-    // Insert the new chain mapping.
-    AddLegalizedOperand(Op.getValue(1), Result.getValue(1));
+  case ISD::BSWAP:
+    Tmp1 = Node->getOperand(0);
+    Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Tmp1);
+    Tmp1 = DAG.getNode(ISD::BSWAP, NVT, Tmp1);
+    Result = DAG.getNode(ISD::SRL, NVT, Tmp1,
+                         DAG.getConstant(getSizeInBits(NVT) - getSizeInBits(VT),
+                                         TLI.getShiftAmountTy()));
     break;
-  }
   case ISD::CTPOP:
   case ISD::CTTZ:
   case ISD::CTLZ:
-    Tmp1 = Node->getOperand(0);
-    //Zero extend the argument
-    Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Tmp1);
+    // Zero extend the argument
+    Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Node->getOperand(0));
     // Perform the larger operation, then subtract if needed.
     Tmp1 = DAG.getNode(Node->getOpcode(), NVT, Tmp1);
-    switch(Node->getOpcode())
-    {
+    switch(Node->getOpcode()) {
     case ISD::CTPOP:
       Result = Tmp1;
       break;
     case ISD::CTTZ:
-      //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
+      // if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
       Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), Tmp1,
                           DAG.getConstant(getSizeInBits(NVT), NVT), ISD::SETEQ);
       Result = DAG.getNode(ISD::SELECT, NVT, Tmp2,
-                           DAG.getConstant(getSizeInBits(VT),NVT), Tmp1);
+                           DAG.getConstant(getSizeInBits(VT), NVT), Tmp1);
       break;
     case ISD::CTLZ:
       //Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT))
@@ -2883,46 +2917,283 @@ SDOperand SelectionDAGLegalize::PromoteOp(SDOperand Op) {
   }
 
   assert(Result.Val && "Didn't set a result!");
+
+  // Make sure the result is itself legal.
+  Result = LegalizeOp(Result);
+  
+  // Remember that we promoted this!
   AddPromotedOperand(Op, Result);
   return Result;
 }
 
+/// LegalizeSetCCOperands - Attempts to create a legal LHS and RHS for a SETCC
+/// with condition CC on the current target.  This usually involves legalizing
+/// or promoting the arguments.  In the case where LHS and RHS must be expanded,
+/// there may be no choice but to create a new SetCC node to represent the
+/// legalized value of setcc lhs, rhs.  In this case, the value is returned in
+/// LHS, and the SDOperand returned in RHS has a nil SDNode value.
+void SelectionDAGLegalize::LegalizeSetCCOperands(SDOperand &LHS,
+                                                 SDOperand &RHS,
+                                                 SDOperand &CC) {
+  SDOperand Tmp1, Tmp2, Result;    
+  
+  switch (getTypeAction(LHS.getValueType())) {
+  case Legal:
+    Tmp1 = LegalizeOp(LHS);   // LHS
+    Tmp2 = LegalizeOp(RHS);   // RHS
+    break;
+  case Promote:
+    Tmp1 = PromoteOp(LHS);   // LHS
+    Tmp2 = PromoteOp(RHS);   // RHS
+
+    // If this is an FP compare, the operands have already been extended.
+    if (MVT::isInteger(LHS.getValueType())) {
+      MVT::ValueType VT = LHS.getValueType();
+      MVT::ValueType NVT = TLI.getTypeToTransformTo(VT);
+
+      // Otherwise, we have to insert explicit sign or zero extends.  Note
+      // that we could insert sign extends for ALL conditions, but zero extend
+      // is cheaper on many machines (an AND instead of two shifts), so prefer
+      // it.
+      switch (cast<CondCodeSDNode>(CC)->get()) {
+      default: assert(0 && "Unknown integer comparison!");
+      case ISD::SETEQ:
+      case ISD::SETNE:
+      case ISD::SETUGE:
+      case ISD::SETUGT:
+      case ISD::SETULE:
+      case ISD::SETULT:
+        // ALL of these operations will work if we either sign or zero extend
+        // the operands (including the unsigned comparisons!).  Zero extend is
+        // usually a simpler/cheaper operation, so prefer it.
+        Tmp1 = DAG.getZeroExtendInReg(Tmp1, VT);
+        Tmp2 = DAG.getZeroExtendInReg(Tmp2, VT);
+        break;
+      case ISD::SETGE:
+      case ISD::SETGT:
+      case ISD::SETLT:
+      case ISD::SETLE:
+        Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1,
+                           DAG.getValueType(VT));
+        Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2,
+                           DAG.getValueType(VT));
+        break;
+      }
+    }
+    break;
+  case Expand:
+    SDOperand LHSLo, LHSHi, RHSLo, RHSHi;
+    ExpandOp(LHS, LHSLo, LHSHi);
+    ExpandOp(RHS, RHSLo, RHSHi);
+    switch (cast<CondCodeSDNode>(CC)->get()) {
+    case ISD::SETEQ:
+    case ISD::SETNE:
+      if (RHSLo == RHSHi)
+        if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo))
+          if (RHSCST->isAllOnesValue()) {
+            // Comparison to -1.
+            Tmp1 = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi);
+            Tmp2 = RHSLo;
+            break;
+          }
+
+      Tmp1 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo);
+      Tmp2 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi);
+      Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp2);
+      Tmp2 = DAG.getConstant(0, Tmp1.getValueType());
+      break;
+    default:
+      // If this is a comparison of the sign bit, just look at the top part.
+      // X > -1,  x < 0
+      if (ConstantSDNode *CST = dyn_cast<ConstantSDNode>(RHS))
+        if ((cast<CondCodeSDNode>(CC)->get() == ISD::SETLT && 
+             CST->getValue() == 0) ||             // X < 0
+            (cast<CondCodeSDNode>(CC)->get() == ISD::SETGT &&
+             CST->isAllOnesValue())) {            // X > -1
+          Tmp1 = LHSHi;
+          Tmp2 = RHSHi;
+          break;
+        }
+
+      // FIXME: This generated code sucks.
+      ISD::CondCode LowCC;
+      switch (cast<CondCodeSDNode>(CC)->get()) {
+      default: assert(0 && "Unknown integer setcc!");
+      case ISD::SETLT:
+      case ISD::SETULT: LowCC = ISD::SETULT; break;
+      case ISD::SETGT:
+      case ISD::SETUGT: LowCC = ISD::SETUGT; break;
+      case ISD::SETLE:
+      case ISD::SETULE: LowCC = ISD::SETULE; break;
+      case ISD::SETGE:
+      case ISD::SETUGE: LowCC = ISD::SETUGE; break;
+      }
+
+      // Tmp1 = lo(op1) < lo(op2)   // Always unsigned comparison
+      // Tmp2 = hi(op1) < hi(op2)   // Signedness depends on operands
+      // dest = hi(op1) == hi(op2) ? Tmp1 : Tmp2;
+
+      // NOTE: on targets without efficient SELECT of bools, we can always use
+      // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3)
+      Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, LowCC);
+      Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultTy(), LHSHi, RHSHi, CC);
+      Result = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETEQ);
+      Result = LegalizeOp(DAG.getNode(ISD::SELECT, Tmp1.getValueType(),
+                                      Result, Tmp1, Tmp2));
+      Tmp1 = Result;
+      Tmp2 = SDOperand();
+    }
+  }
+  LHS = Tmp1;
+  RHS = Tmp2;
+}
+
 /// ExpandBIT_CONVERT - Expand a BIT_CONVERT node into a store/load combination.
 /// The resultant code need not be legal.  Note that SrcOp is the input operand
 /// to the BIT_CONVERT, not the BIT_CONVERT node itself.
 SDOperand SelectionDAGLegalize::ExpandBIT_CONVERT(MVT::ValueType DestVT, 
                                                   SDOperand SrcOp) {
   // Create the stack frame object.
-  MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
-  unsigned ByteSize = MVT::getSizeInBits(DestVT)/8;
-  int FrameIdx = FrameInfo->CreateStackObject(ByteSize, ByteSize);
-  SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, TLI.getPointerTy());
+  SDOperand FIPtr = CreateStackTemporary(DestVT);
+  
+  // Emit a store to the stack slot.
+  SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+                                SrcOp, FIPtr, DAG.getSrcValue(NULL));
+  // Result is a load from the stack slot.
+  return DAG.getLoad(DestVT, Store, FIPtr, DAG.getSrcValue(0));
+}
+
+/// ExpandBUILD_VECTOR - Expand a BUILD_VECTOR node on targets that don't
+/// support the operation, but do support the resultant packed vector type.
+SDOperand SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
+  
+  // If the only non-undef value is the low element, turn this into a 
+  // SCALAR_TO_VECTOR node.  If this is { X, X, X, X }, determine X.
+  bool isOnlyLowElement = true;
+  SDOperand SplatValue = Node->getOperand(0);
+  for (SDNode::op_iterator I = Node->op_begin()+1, E = Node->op_end();
+       I != E; ++I) {
+    if (I->getOpcode() != ISD::UNDEF)
+      isOnlyLowElement = false;
+    if (SplatValue != *I)
+      SplatValue = SDOperand(0,0);
+  }
+  
+  if (isOnlyLowElement) {
+    // If the low element is an undef too, then this whole things is an undef.
+    if (Node->getOperand(0).getOpcode() == ISD::UNDEF)
+      return DAG.getNode(ISD::UNDEF, Node->getValueType(0));
+    // Otherwise, turn this into a scalar_to_vector node.
+    return DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0),
+                       Node->getOperand(0));
+  }
+  
+  if (SplatValue.Val) {   // Splat of one value?
+    // Build the shuffle constant vector: <0, 0, 0, 0>
+    MVT::ValueType MaskVT = 
+      MVT::getIntVectorWithNumElements(Node->getNumOperands());
+    SDOperand Zero = DAG.getConstant(0, MVT::getVectorBaseType(MaskVT));
+    std::vector<SDOperand> ZeroVec(Node->getNumOperands(), Zero);
+    SDOperand SplatMask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, ZeroVec);
+
+    // If the target supports VECTOR_SHUFFLE and this shuffle mask, use it.
+    if (TLI.isShuffleLegal(Node->getValueType(0), SplatMask)) {
+      // Get the splatted value into the low element of a vector register.
+      SDOperand LowValVec = 
+        DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0), SplatValue);
+    
+      // Return shuffle(LowValVec, undef, <0,0,0,0>)
+      return DAG.getNode(ISD::VECTOR_SHUFFLE, Node->getValueType(0), LowValVec,
+                         DAG.getNode(ISD::UNDEF, Node->getValueType(0)),
+                         SplatMask);
+    }
+  }
+  
+  // If the elements are all constants, turn this into a load from the constant
+  // pool.
+  bool isConstant = true;
+  for (SDNode::op_iterator I = Node->op_begin(), E = Node->op_end();
+       I != E; ++I) {
+    if (!isa<ConstantFPSDNode>(I) && !isa<ConstantSDNode>(I) &&
+        I->getOpcode() != ISD::UNDEF) {
+      isConstant = false;
+      break;
+    }
+  }
+  
+  // Create a ConstantPacked, and put it in the constant pool.
+  if (isConstant) {
+    MVT::ValueType VT = Node->getValueType(0);
+    const Type *OpNTy = 
+      MVT::getTypeForValueType(Node->getOperand(0).getValueType());
+    std::vector<Constant*> CV;
+    for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
+      if (ConstantFPSDNode *V = 
+          dyn_cast<ConstantFPSDNode>(Node->getOperand(i))) {
+        CV.push_back(ConstantFP::get(OpNTy, V->getValue()));
+      } else if (ConstantSDNode *V = 
+                 dyn_cast<ConstantSDNode>(Node->getOperand(i))) {
+        CV.push_back(ConstantUInt::get(OpNTy, V->getValue()));
+      } else {
+        assert(Node->getOperand(i).getOpcode() == ISD::UNDEF);
+        CV.push_back(UndefValue::get(OpNTy));
+      }
+    }
+    Constant *CP = ConstantPacked::get(CV);
+    SDOperand CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy());
+    return DAG.getLoad(VT, DAG.getEntryNode(), CPIdx,
+                       DAG.getSrcValue(NULL));
+  }
+  
+  // Otherwise, we can't handle this case efficiently.  Allocate a sufficiently
+  // aligned object on the stack, store each element into it, then load
+  // the result as a vector.
+  MVT::ValueType VT = Node->getValueType(0);
+  // Create the stack frame object.
+  SDOperand FIPtr = CreateStackTemporary(VT);
+  
+  // Emit a store of each element to the stack slot.
+  std::vector<SDOperand> Stores;
+  bool isLittleEndian = TLI.isLittleEndian();
+  unsigned TypeByteSize = 
+    MVT::getSizeInBits(Node->getOperand(0).getValueType())/8;
+  unsigned VectorSize = MVT::getSizeInBits(VT)/8;
+  // Store (in the right endianness) the elements to memory.
+  for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
+    // Ignore undef elements.
+    if (Node->getOperand(i).getOpcode() == ISD::UNDEF) continue;
+    
+    unsigned Offset;
+    if (isLittleEndian) 
+      Offset = TypeByteSize*i;
+    else
+      Offset = TypeByteSize*(e-i-1);
+    
+    SDOperand Idx = DAG.getConstant(Offset, FIPtr.getValueType());
+    Idx = DAG.getNode(ISD::ADD, FIPtr.getValueType(), FIPtr, Idx);
+    
+    Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+                                 Node->getOperand(i), Idx, 
+                                 DAG.getSrcValue(NULL)));
+  }
+  
+  SDOperand StoreChain;
+  if (!Stores.empty())    // Not all undef elements?
+    StoreChain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores);
+  else
+    StoreChain = DAG.getEntryNode();
   
-  // Emit a store to the stack slot.
-  SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
-                                SrcOp, FIPtr, DAG.getSrcValue(NULL));
   // Result is a load from the stack slot.
-  return DAG.getLoad(DestVT, Store, FIPtr, DAG.getSrcValue(0));
+  return DAG.getLoad(VT, StoreChain, FIPtr, DAG.getSrcValue(0));
 }
 
-/// ExpandAddSub - Find a clever way to expand this add operation into
-/// subcomponents.
-void SelectionDAGLegalize::
-ExpandByParts(unsigned NodeOp, SDOperand LHS, SDOperand RHS,
-              SDOperand &Lo, SDOperand &Hi) {
-  // Expand the subcomponents.
-  SDOperand LHSL, LHSH, RHSL, RHSH;
-  ExpandOp(LHS, LHSL, LHSH);
-  ExpandOp(RHS, RHSL, RHSH);
-
-  std::vector<SDOperand> Ops;
-  Ops.push_back(LHSL);
-  Ops.push_back(LHSH);
-  Ops.push_back(RHSL);
-  Ops.push_back(RHSH);
-  std::vector<MVT::ValueType> VTs(2, LHSL.getValueType());
-  Lo = DAG.getNode(NodeOp, VTs, Ops);
-  Hi = Lo.getValue(1);
+/// CreateStackTemporary - Create a stack temporary, suitable for holding the
+/// specified value type.
+SDOperand SelectionDAGLegalize::CreateStackTemporary(MVT::ValueType VT) {
+  MachineFrameInfo *FrameInfo = DAG.getMachineFunction().getFrameInfo();
+  unsigned ByteSize = MVT::getSizeInBits(VT)/8;
+  int FrameIdx = FrameInfo->CreateStackObject(ByteSize, ByteSize);
+  return DAG.getFrameIndex(FrameIdx, TLI.getPointerTy());
 }
 
 void SelectionDAGLegalize::ExpandShiftParts(unsigned NodeOp,
@@ -3021,205 +3292,7 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDOperand Op,SDOperand Amt,
       return true;
     }
   }
-  // FIXME: The following code for expanding shifts using ISD::SELECT is buggy,
-  // so disable it for now.  Currently targets are handling this via SHL_PARTS
-  // and friends.
   return false;
-
-  // If we have an efficient select operation (or if the selects will all fold
-  // away), lower to some complex code, otherwise just emit the libcall.
-  if (!TLI.isOperationLegal(ISD::SELECT, NVT) && !isa<ConstantSDNode>(Amt))
-    return false;
-
-  SDOperand InL, InH;
-  ExpandOp(Op, InL, InH);
-  SDOperand NAmt = DAG.getNode(ISD::SUB, ShTy,           // NAmt = 32-ShAmt
-                               DAG.getConstant(NVTBits, ShTy), ShAmt);
-
-  // Compare the unmasked shift amount against 32.
-  SDOperand Cond = DAG.getSetCC(TLI.getSetCCResultTy(), ShAmt,
-                                DAG.getConstant(NVTBits, ShTy), ISD::SETGE);
-
-  if (TLI.getShiftAmountFlavor() != TargetLowering::Mask) {
-    ShAmt = DAG.getNode(ISD::AND, ShTy, ShAmt,             // ShAmt &= 31
-                        DAG.getConstant(NVTBits-1, ShTy));
-    NAmt  = DAG.getNode(ISD::AND, ShTy, NAmt,              // NAmt &= 31
-                        DAG.getConstant(NVTBits-1, ShTy));
-  }
-
-  if (Opc == ISD::SHL) {
-    SDOperand T1 = DAG.getNode(ISD::OR, NVT,// T1 = (Hi << Amt) | (Lo >> NAmt)
-                               DAG.getNode(ISD::SHL, NVT, InH, ShAmt),
-                               DAG.getNode(ISD::SRL, NVT, InL, NAmt));
-    SDOperand T2 = DAG.getNode(ISD::SHL, NVT, InL, ShAmt); // T2 = Lo << Amt&31
-
-    Hi = DAG.getNode(ISD::SELECT, NVT, Cond, T2, T1);
-    Lo = DAG.getNode(ISD::SELECT, NVT, Cond, DAG.getConstant(0, NVT), T2);
-  } else {
-    SDOperand HiLoPart = DAG.getNode(ISD::SELECT, NVT,
-                                     DAG.getSetCC(TLI.getSetCCResultTy(), NAmt,
-                                                  DAG.getConstant(32, ShTy),
-                                                  ISD::SETEQ),
-                                     DAG.getConstant(0, NVT),
-                                     DAG.getNode(ISD::SHL, NVT, InH, NAmt));
-    SDOperand T1 = DAG.getNode(ISD::OR, NVT,// T1 = (Hi << NAmt) | (Lo >> Amt)
-                               HiLoPart,
-                               DAG.getNode(ISD::SRL, NVT, InL, ShAmt));
-    SDOperand T2 = DAG.getNode(Opc, NVT, InH, ShAmt);  // T2 = InH >> ShAmt&31
-
-    SDOperand HiPart;
-    if (Opc == ISD::SRA)
-      HiPart = DAG.getNode(ISD::SRA, NVT, InH,
-                           DAG.getConstant(NVTBits-1, ShTy));
-    else
-      HiPart = DAG.getConstant(0, NVT);
-    Lo = DAG.getNode(ISD::SELECT, NVT, Cond, T2, T1);
-    Hi = DAG.getNode(ISD::SELECT, NVT, Cond, HiPart, T2);
-  }
-  return true;
-}
-
-/// FindLatestCallSeqStart - Scan up the dag to find the latest (highest
-/// NodeDepth) node that is an CallSeqStart operation and occurs later than
-/// Found.
-static void FindLatestCallSeqStart(SDNode *Node, SDNode *&Found) {
-  if (Node->getNodeDepth() <= Found->getNodeDepth()) return;
-  
-  // If we found an CALLSEQ_START, we already know this node occurs later
-  // than the Found node. Just remember this node and return.
-  if (Node->getOpcode() == ISD::CALLSEQ_START) {
-    Found = Node;
-    return;
-  }
-
-  // Otherwise, scan the operands of Node to see if any of them is a call.
-  assert(Node->getNumOperands() != 0 &&
-         "All leaves should have depth equal to the entry node!");
-  for (unsigned i = 0, e = Node->getNumOperands()-1; i != e; ++i)
-    FindLatestCallSeqStart(Node->getOperand(i).Val, Found);
-
-  // Tail recurse for the last iteration.
-  FindLatestCallSeqStart(Node->getOperand(Node->getNumOperands()-1).Val,
-                             Found);
-}
-
-
-/// FindEarliestCallSeqEnd - Scan down the dag to find the earliest (lowest
-/// NodeDepth) node that is an CallSeqEnd operation and occurs more recent
-/// than Found.
-static void FindEarliestCallSeqEnd(SDNode *Node, SDNode *&Found,
-                                   std::set<SDNode*> &Visited) {
-  if ((Found && Node->getNodeDepth() >= Found->getNodeDepth()) ||
-      !Visited.insert(Node).second) return;
-
-  // If we found an CALLSEQ_END, we already know this node occurs earlier
-  // than the Found node. Just remember this node and return.
-  if (Node->getOpcode() == ISD::CALLSEQ_END) {
-    Found = Node;
-    return;
-  }
-
-  // Otherwise, scan the operands of Node to see if any of them is a call.
-  SDNode::use_iterator UI = Node->use_begin(), E = Node->use_end();
-  if (UI == E) return;
-  for (--E; UI != E; ++UI)
-    FindEarliestCallSeqEnd(*UI, Found, Visited);
-
-  // Tail recurse for the last iteration.
-  FindEarliestCallSeqEnd(*UI, Found, Visited);
-}
-
-/// FindCallSeqEnd - Given a chained node that is part of a call sequence,
-/// find the CALLSEQ_END node that terminates the call sequence.
-static SDNode *FindCallSeqEnd(SDNode *Node) {
-  if (Node->getOpcode() == ISD::CALLSEQ_END)
-    return Node;
-  if (Node->use_empty())
-    return 0;   // No CallSeqEnd
-
-  SDOperand TheChain(Node, Node->getNumValues()-1);
-  if (TheChain.getValueType() != MVT::Other)
-    TheChain = SDOperand(Node, 0);
-  if (TheChain.getValueType() != MVT::Other)
-    return 0;
-
-  for (SDNode::use_iterator UI = Node->use_begin(),
-         E = Node->use_end(); UI != E; ++UI) {
-
-    // Make sure to only follow users of our token chain.
-    SDNode *User = *UI;
-    for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i)
-      if (User->getOperand(i) == TheChain)
-        if (SDNode *Result = FindCallSeqEnd(User))
-          return Result;
-  }
-  return 0;
-}
-
-/// FindCallSeqStart - Given a chained node that is part of a call sequence,
-/// find the CALLSEQ_START node that initiates the call sequence.
-static SDNode *FindCallSeqStart(SDNode *Node) {
-  assert(Node && "Didn't find callseq_start for a call??");
-  if (Node->getOpcode() == ISD::CALLSEQ_START) return Node;
-
-  assert(Node->getOperand(0).getValueType() == MVT::Other &&
-         "Node doesn't have a token chain argument!");
-  return FindCallSeqStart(Node->getOperand(0).Val);
-}
-
-
-/// FindInputOutputChains - If we are replacing an operation with a call we need
-/// to find the call that occurs before and the call that occurs after it to
-/// properly serialize the calls in the block.  The returned operand is the
-/// input chain value for the new call (e.g. the entry node or the previous
-/// call), and OutChain is set to be the chain node to update to point to the
-/// end of the call chain.
-static SDOperand FindInputOutputChains(SDNode *OpNode, SDNode *&OutChain,
-                                       SDOperand Entry) {
-  SDNode *LatestCallSeqStart = Entry.Val;
-  SDNode *LatestCallSeqEnd = 0;
-  FindLatestCallSeqStart(OpNode, LatestCallSeqStart);
-  //std::cerr<<"Found node: "; LatestCallSeqStart->dump(); std::cerr <<"\n";
-
-  // It is possible that no ISD::CALLSEQ_START was found because there is no
-  // previous call in the function.  LatestCallStackDown may in that case be
-  // the entry node itself.  Do not attempt to find a matching CALLSEQ_END
-  // unless LatestCallStackDown is an CALLSEQ_START.
-  if (LatestCallSeqStart->getOpcode() == ISD::CALLSEQ_START) {
-    LatestCallSeqEnd = FindCallSeqEnd(LatestCallSeqStart);
-    //std::cerr<<"Found end node: "; LatestCallSeqEnd->dump(); std::cerr <<"\n";
-  } else {
-    LatestCallSeqEnd = Entry.Val;
-  }
-  assert(LatestCallSeqEnd && "NULL return from FindCallSeqEnd");
-
-  // Finally, find the first call that this must come before, first we find the
-  // CallSeqEnd that ends the call.
-  OutChain = 0;
-  std::set<SDNode*> Visited;
-  FindEarliestCallSeqEnd(OpNode, OutChain, Visited);
-
-  // If we found one, translate from the adj up to the callseq_start.
-  if (OutChain)
-    OutChain = FindCallSeqStart(OutChain);
-
-  return SDOperand(LatestCallSeqEnd, 0);
-}
-
-/// SpliceCallInto - Given the result chain of a libcall (CallResult), and a
-void SelectionDAGLegalize::SpliceCallInto(const SDOperand &CallResult,
-                                          SDNode *OutChain) {
-  // Nothing to splice it into?
-  if (OutChain == 0) return;
-
-  assert(OutChain->getOperand(0).getValueType() == MVT::Other);
-  //OutChain->dump();
-
-  // Form a token factor node merging the old inval and the new inval.
-  SDOperand InToken = DAG.getNode(ISD::TokenFactor, MVT::Other, CallResult,
-                                  OutChain->getOperand(0));
-  // Change the node to refer to the new token.
-  OutChain->setAdjCallChain(InToken);
 }
 
 
@@ -3229,12 +3302,12 @@ void SelectionDAGLegalize::SpliceCallInto(const SDOperand &CallResult,
 // and leave the Hi part unset.
 SDOperand SelectionDAGLegalize::ExpandLibCall(const char *Name, SDNode *Node,
                                               SDOperand &Hi) {
-  SDNode *OutChain;
-  SDOperand InChain = FindInputOutputChains(Node, OutChain,
-                                            DAG.getEntryNode());
-  if (InChain.Val == 0)
-    InChain = DAG.getEntryNode();
-
+  assert(!IsLegalizingCall && "Cannot overlap legalization of calls!");
+  // The input chain to this libcall is the entry node of the function. 
+  // Legalizing the call will automatically add the previous call to the
+  // dependence.
+  SDOperand InChain = DAG.getEntryNode();
+  
   TargetLowering::ArgListTy Args;
   for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) {
     MVT::ValueType ArgVT = Node->getOperand(i).getValueType();
@@ -3249,22 +3322,20 @@ SDOperand SelectionDAGLegalize::ExpandLibCall(const char *Name, SDNode *Node,
     TLI.LowerCallTo(InChain, RetTy, false, CallingConv::C, false,
                     Callee, Args, DAG);
 
+  // Legalize the call sequence, starting with the chain.  This will advance
+  // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that
+  // was added by LowerCallTo (guaranteeing proper serialization of calls).
+  LegalizeOp(CallInfo.second);
   SDOperand Result;
   switch (getTypeAction(CallInfo.first.getValueType())) {
   default: assert(0 && "Unknown thing");
   case Legal:
     Result = CallInfo.first;
     break;
-  case Promote:
-    assert(0 && "Cannot promote this yet!");
   case Expand:
     ExpandOp(CallInfo.first, Result, Hi);
-    CallInfo.second = LegalizeOp(CallInfo.second);
     break;
   }
-  
-  SpliceCallInto(CallInfo.second, OutChain);
-  NeedsAnotherIteration = true;
   return Result;
 }
 
@@ -3337,9 +3408,6 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) {
   ExpandOp(Source, SrcLo, SrcHi);
   Source = DAG.getNode(ISD::BUILD_PAIR, Source.getValueType(), SrcLo, SrcHi);
 
-  SDNode *OutChain = 0;
-  SDOperand InChain = FindInputOutputChains(Source.Val, OutChain,
-                                            DAG.getEntryNode());
   const char *FnName = 0;
   if (DestTy == MVT::f32)
     FnName = "__floatdisf";
@@ -3347,27 +3415,336 @@ ExpandIntToFP(bool isSigned, MVT::ValueType DestTy, SDOperand Source) {
     assert(DestTy == MVT::f64 && "Unknown fp value type!");
     FnName = "__floatdidf";
   }
+  
+  Source = DAG.getNode(ISD::SINT_TO_FP, DestTy, Source);
+  SDOperand UnusedHiPart;
+  return ExpandLibCall(FnName, Source.Val, UnusedHiPart);
+}
+
+/// ExpandLegalINT_TO_FP - This function is responsible for legalizing a
+/// INT_TO_FP operation of the specified operand when the target requests that
+/// we expand it.  At this point, we know that the result and operand types are
+/// legal for the target.
+SDOperand SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned,
+                                                     SDOperand Op0,
+                                                     MVT::ValueType DestVT) {
+  if (Op0.getValueType() == MVT::i32) {
+    // simple 32-bit [signed|unsigned] integer to float/double expansion
+    
+    // get the stack frame index of a 8 byte buffer
+    MachineFunction &MF = DAG.getMachineFunction();
+    int SSFI = MF.getFrameInfo()->CreateStackObject(8, 8);
+    // get address of 8 byte buffer
+    SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
+    // word offset constant for Hi/Lo address computation
+    SDOperand WordOff = DAG.getConstant(sizeof(int), TLI.getPointerTy());
+    // set up Hi and Lo (into buffer) address based on endian
+    SDOperand Hi, Lo;
+    if (TLI.isLittleEndian()) {
+      Hi = DAG.getNode(ISD::ADD, TLI.getPointerTy(), StackSlot, WordOff);
+      Lo = StackSlot;
+    } else {
+      Hi = StackSlot;
+      Lo = DAG.getNode(ISD::ADD, TLI.getPointerTy(), StackSlot, WordOff);
+    }
+    // if signed map to unsigned space
+    SDOperand Op0Mapped;
+    if (isSigned) {
+      // constant used to invert sign bit (signed to unsigned mapping)
+      SDOperand SignBit = DAG.getConstant(0x80000000u, MVT::i32);
+      Op0Mapped = DAG.getNode(ISD::XOR, MVT::i32, Op0, SignBit);
+    } else {
+      Op0Mapped = Op0;
+    }
+    // store the lo of the constructed double - based on integer input
+    SDOperand Store1 = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
+                                   Op0Mapped, Lo, DAG.getSrcValue(NULL));
+    // initial hi portion of constructed double
+    SDOperand InitialHi = DAG.getConstant(0x43300000u, MVT::i32);
+    // store the hi of the constructed double - biased exponent
+    SDOperand Store2 = DAG.getNode(ISD::STORE, MVT::Other, Store1,
+                                   InitialHi, Hi, DAG.getSrcValue(NULL));
+    // load the constructed double
+    SDOperand Load = DAG.getLoad(MVT::f64, Store2, StackSlot,
+                               DAG.getSrcValue(NULL));
+    // FP constant to bias correct the final result
+    SDOperand Bias = DAG.getConstantFP(isSigned ?
+                                            BitsToDouble(0x4330000080000000ULL)
+                                          : BitsToDouble(0x4330000000000000ULL),
+                                     MVT::f64);
+    // subtract the bias
+    SDOperand Sub = DAG.getNode(ISD::FSUB, MVT::f64, Load, Bias);
+    // final result
+    SDOperand Result;
+    // handle final rounding
+    if (DestVT == MVT::f64) {
+      // do nothing
+      Result = Sub;
+    } else {
+     // if f32 then cast to f32
+      Result = DAG.getNode(ISD::FP_ROUND, MVT::f32, Sub);
+    }
+    return Result;
+  }
+  assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet");
+  SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0);
+
+  SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultTy(), Op0,
+                                   DAG.getConstant(0, Op0.getValueType()),
+                                   ISD::SETLT);
+  SDOperand Zero = getIntPtrConstant(0), Four = getIntPtrConstant(4);
+  SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
+                                    SignSet, Four, Zero);
+
+  // If the sign bit of the integer is set, the large number will be treated
+  // as a negative number.  To counteract this, the dynamic code adds an
+  // offset depending on the data type.
+  uint64_t FF;
+  switch (Op0.getValueType()) {
+  default: assert(0 && "Unsupported integer type!");
+  case MVT::i8 : FF = 0x43800000ULL; break;  // 2^8  (as a float)
+  case MVT::i16: FF = 0x47800000ULL; break;  // 2^16 (as a float)
+  case MVT::i32: FF = 0x4F800000ULL; break;  // 2^32 (as a float)
+  case MVT::i64: FF = 0x5F800000ULL; break;  // 2^64 (as a float)
+  }
+  if (TLI.isLittleEndian()) FF <<= 32;
+  static Constant *FudgeFactor = ConstantUInt::get(Type::ULongTy, FF);
+
+  SDOperand CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy());
+  CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
+  SDOperand FudgeInReg;
+  if (DestVT == MVT::f32)
+    FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx,
+                             DAG.getSrcValue(NULL));
+  else {
+    assert(DestVT == MVT::f64 && "Unexpected conversion");
+    FudgeInReg = LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, MVT::f64,
+                                           DAG.getEntryNode(), CPIdx,
+                                           DAG.getSrcValue(NULL), MVT::f32));
+  }
+
+  return DAG.getNode(ISD::FADD, DestVT, Tmp1, FudgeInReg);
+}
+
+/// PromoteLegalINT_TO_FP - This function is responsible for legalizing a
+/// *INT_TO_FP operation of the specified operand when the target requests that
+/// we promote it.  At this point, we know that the result and operand types are
+/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP
+/// operation that takes a larger input.
+SDOperand SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDOperand LegalOp,
+                                                      MVT::ValueType DestVT,
+                                                      bool isSigned) {
+  // First step, figure out the appropriate *INT_TO_FP operation to use.
+  MVT::ValueType NewInTy = LegalOp.getValueType();
+
+  unsigned OpToUse = 0;
+
+  // Scan for the appropriate larger type to use.
+  while (1) {
+    NewInTy = (MVT::ValueType)(NewInTy+1);
+    assert(MVT::isInteger(NewInTy) && "Ran out of possibilities!");
+
+    // If the target supports SINT_TO_FP of this type, use it.
+    switch (TLI.getOperationAction(ISD::SINT_TO_FP, NewInTy)) {
+      default: break;
+      case TargetLowering::Legal:
+        if (!TLI.isTypeLegal(NewInTy))
+          break;  // Can't use this datatype.
+        // FALL THROUGH.
+      case TargetLowering::Custom:
+        OpToUse = ISD::SINT_TO_FP;
+        break;
+    }
+    if (OpToUse) break;
+    if (isSigned) continue;
+
+    // If the target supports UINT_TO_FP of this type, use it.
+    switch (TLI.getOperationAction(ISD::UINT_TO_FP, NewInTy)) {
+      default: break;
+      case TargetLowering::Legal:
+        if (!TLI.isTypeLegal(NewInTy))
+          break;  // Can't use this datatype.
+        // FALL THROUGH.
+      case TargetLowering::Custom:
+        OpToUse = ISD::UINT_TO_FP;
+        break;
+    }
+    if (OpToUse) break;
+
+    // Otherwise, try a larger type.
+  }
+
+  // Okay, we found the operation and type to use.  Zero extend our input to the
+  // desired type then run the operation on it.
+  return DAG.getNode(OpToUse, DestVT,
+                     DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
+                                 NewInTy, LegalOp));
+}
 
-  SDOperand Callee = DAG.getExternalSymbol(FnName, TLI.getPointerTy());
+/// PromoteLegalFP_TO_INT - This function is responsible for legalizing a
+/// FP_TO_*INT operation of the specified operand when the target requests that
+/// we promote it.  At this point, we know that the result and operand types are
+/// legal for the target, and that there is a legal FP_TO_UINT or FP_TO_SINT
+/// operation that returns a larger result.
+SDOperand SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDOperand LegalOp,
+                                                      MVT::ValueType DestVT,
+                                                      bool isSigned) {
+  // First step, figure out the appropriate FP_TO*INT operation to use.
+  MVT::ValueType NewOutTy = DestVT;
+
+  unsigned OpToUse = 0;
+
+  // Scan for the appropriate larger type to use.
+  while (1) {
+    NewOutTy = (MVT::ValueType)(NewOutTy+1);
+    assert(MVT::isInteger(NewOutTy) && "Ran out of possibilities!");
 
-  TargetLowering::ArgListTy Args;
-  const Type *ArgTy = MVT::getTypeForValueType(Source.getValueType());
+    // If the target supports FP_TO_SINT returning this type, use it.
+    switch (TLI.getOperationAction(ISD::FP_TO_SINT, NewOutTy)) {
+    default: break;
+    case TargetLowering::Legal:
+      if (!TLI.isTypeLegal(NewOutTy))
+        break;  // Can't use this datatype.
+      // FALL THROUGH.
+    case TargetLowering::Custom:
+      OpToUse = ISD::FP_TO_SINT;
+      break;
+    }
+    if (OpToUse) break;
 
-  Args.push_back(std::make_pair(Source, ArgTy));
+    // If the target supports FP_TO_UINT of this type, use it.
+    switch (TLI.getOperationAction(ISD::FP_TO_UINT, NewOutTy)) {
+    default: break;
+    case TargetLowering::Legal:
+      if (!TLI.isTypeLegal(NewOutTy))
+        break;  // Can't use this datatype.
+      // FALL THROUGH.
+    case TargetLowering::Custom:
+      OpToUse = ISD::FP_TO_UINT;
+      break;
+    }
+    if (OpToUse) break;
 
-  // We don't care about token chains for libcalls.  We just use the entry
-  // node as our input and ignore the output chain.  This allows us to place
-  // calls wherever we need them to satisfy data dependences.
-  const Type *RetTy = MVT::getTypeForValueType(DestTy);
+    // Otherwise, try a larger type.
+  }
 
-  std::pair<SDOperand,SDOperand> CallResult =
-    TLI.LowerCallTo(InChain, RetTy, false, CallingConv::C, true,
-                    Callee, Args, DAG);
+  // Okay, we found the operation and type to use.  Truncate the result of the
+  // extended FP_TO_*INT operation to the desired size.
+  return DAG.getNode(ISD::TRUNCATE, DestVT,
+                     DAG.getNode(OpToUse, NewOutTy, LegalOp));
+}
 
-  SpliceCallInto(CallResult.second, OutChain);
-  return CallResult.first;
+/// ExpandBSWAP - Open code the operations for BSWAP of the specified operation.
+///
+SDOperand SelectionDAGLegalize::ExpandBSWAP(SDOperand Op) {
+  MVT::ValueType VT = Op.getValueType();
+  MVT::ValueType SHVT = TLI.getShiftAmountTy();
+  SDOperand Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6, Tmp7, Tmp8;
+  switch (VT) {
+  default: assert(0 && "Unhandled Expand type in BSWAP!"); abort();
+  case MVT::i16:
+    Tmp2 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT));
+    Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT));
+    return DAG.getNode(ISD::OR, VT, Tmp1, Tmp2);
+  case MVT::i32:
+    Tmp4 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(24, SHVT));
+    Tmp3 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT));
+    Tmp2 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT));
+    Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(24, SHVT));
+    Tmp3 = DAG.getNode(ISD::AND, VT, Tmp3, DAG.getConstant(0xFF0000, VT));
+    Tmp2 = DAG.getNode(ISD::AND, VT, Tmp2, DAG.getConstant(0xFF00, VT));
+    Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp3);
+    Tmp2 = DAG.getNode(ISD::OR, VT, Tmp2, Tmp1);
+    return DAG.getNode(ISD::OR, VT, Tmp4, Tmp2);
+  case MVT::i64:
+    Tmp8 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(56, SHVT));
+    Tmp7 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(40, SHVT));
+    Tmp6 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(24, SHVT));
+    Tmp5 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT));
+    Tmp4 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT));
+    Tmp3 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(24, SHVT));
+    Tmp2 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(40, SHVT));
+    Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(56, SHVT));
+    Tmp7 = DAG.getNode(ISD::AND, VT, Tmp7, DAG.getConstant(255ULL<<48, VT));
+    Tmp6 = DAG.getNode(ISD::AND, VT, Tmp6, DAG.getConstant(255ULL<<40, VT));
+    Tmp5 = DAG.getNode(ISD::AND, VT, Tmp5, DAG.getConstant(255ULL<<32, VT));
+    Tmp4 = DAG.getNode(ISD::AND, VT, Tmp4, DAG.getConstant(255ULL<<24, VT));
+    Tmp3 = DAG.getNode(ISD::AND, VT, Tmp3, DAG.getConstant(255ULL<<16, VT));
+    Tmp2 = DAG.getNode(ISD::AND, VT, Tmp2, DAG.getConstant(255ULL<<8 , VT));
+    Tmp8 = DAG.getNode(ISD::OR, VT, Tmp8, Tmp7);
+    Tmp6 = DAG.getNode(ISD::OR, VT, Tmp6, Tmp5);
+    Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp3);
+    Tmp2 = DAG.getNode(ISD::OR, VT, Tmp2, Tmp1);
+    Tmp8 = DAG.getNode(ISD::OR, VT, Tmp8, Tmp6);
+    Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp2);
+    return DAG.getNode(ISD::OR, VT, Tmp8, Tmp4);
+  }
 }
 
+/// ExpandBitCount - Expand the specified bitcount instruction into operations.
+///
+SDOperand SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDOperand Op) {
+  switch (Opc) {
+  default: assert(0 && "Cannot expand this yet!");
+  case ISD::CTPOP: {
+    static const uint64_t mask[6] = {
+      0x5555555555555555ULL, 0x3333333333333333ULL,
+      0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL,
+      0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL
+    };
+    MVT::ValueType VT = Op.getValueType();
+    MVT::ValueType ShVT = TLI.getShiftAmountTy();
+    unsigned len = getSizeInBits(VT);
+    for (unsigned i = 0; (1U << i) <= (len / 2); ++i) {
+      //x = (x & mask[i][len/8]) + (x >> (1 << i) & mask[i][len/8])
+      SDOperand Tmp2 = DAG.getConstant(mask[i], VT);
+      SDOperand Tmp3 = DAG.getConstant(1ULL << i, ShVT);
+      Op = DAG.getNode(ISD::ADD, VT, DAG.getNode(ISD::AND, VT, Op, Tmp2),
+                       DAG.getNode(ISD::AND, VT,
+                                   DAG.getNode(ISD::SRL, VT, Op, Tmp3),Tmp2));
+    }
+    return Op;
+  }
+  case ISD::CTLZ: {
+    // for now, we do this:
+    // x = x | (x >> 1);
+    // x = x | (x >> 2);
+    // ...
+    // x = x | (x >>16);
+    // x = x | (x >>32); // for 64-bit input
+    // return popcount(~x);
+    //
+    // but see also: http://www.hackersdelight.org/HDcode/nlz.cc
+    MVT::ValueType VT = Op.getValueType();
+    MVT::ValueType ShVT = TLI.getShiftAmountTy();
+    unsigned len = getSizeInBits(VT);
+    for (unsigned i = 0; (1U << i) <= (len / 2); ++i) {
+      SDOperand Tmp3 = DAG.getConstant(1ULL << i, ShVT);
+      Op = DAG.getNode(ISD::OR, VT, Op, DAG.getNode(ISD::SRL, VT, Op, Tmp3));
+    }
+    Op = DAG.getNode(ISD::XOR, VT, Op, DAG.getConstant(~0ULL, VT));
+    return DAG.getNode(ISD::CTPOP, VT, Op);
+  }
+  case ISD::CTTZ: {
+    // for now, we use: { return popcount(~x & (x - 1)); }
+    // unless the target has ctlz but not ctpop, in which case we use:
+    // { return 32 - nlz(~x & (x-1)); }
+    // see also http://www.hackersdelight.org/HDcode/ntz.cc
+    MVT::ValueType VT = Op.getValueType();
+    SDOperand Tmp2 = DAG.getConstant(~0ULL, VT);
+    SDOperand Tmp3 = DAG.getNode(ISD::AND, VT,
+                       DAG.getNode(ISD::XOR, VT, Op, Tmp2),
+                       DAG.getNode(ISD::SUB, VT, Op, DAG.getConstant(1, VT)));
+    // If ISD::CTLZ is legal and CTPOP isn't, then do that instead.
+    if (!TLI.isOperationLegal(ISD::CTPOP, VT) &&
+        TLI.isOperationLegal(ISD::CTLZ, VT))
+      return DAG.getNode(ISD::SUB, VT,
+                         DAG.getConstant(getSizeInBits(VT), VT),
+                         DAG.getNode(ISD::CTLZ, VT, Tmp3));
+    return DAG.getNode(ISD::CTPOP, VT, Tmp3);
+  }
+  }
+}
 
 
 /// ExpandOp - Expand the specified SDOperand into its two component pieces
@@ -3394,15 +3771,10 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     return;
   }
 
-  // Expanding to multiple registers needs to perform an optimization step, and
-  // is not careful to avoid operations the target does not support.  Make sure
-  // that all generated operations are legalized in the next iteration.
-  NeedsAnotherIteration = true;
-
   switch (Node->getOpcode()) {
-   case ISD::CopyFromReg:
-      assert(0 && "CopyFromReg must be legal!");
-   default:
+  case ISD::CopyFromReg:
+    assert(0 && "CopyFromReg must be legal!");
+  default:
     std::cerr << "NODE: "; Node->dump(); std::cerr << "\n";
     assert(0 && "Do not know how to expand this operator!");
     abort();
@@ -3416,35 +3788,10 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     Hi = DAG.getConstant(Cst >> MVT::getSizeInBits(NVT), NVT);
     break;
   }
-  case ISD::ConstantVec: {
-    unsigned NumElements = Node->getNumOperands();
-    // If we only have two elements left in the constant vector, just break it
-    // apart into the two scalar constants it contains.  Otherwise, bisect the
-    // ConstantVec, and return each half as a new ConstantVec.
-    // FIXME: this is hard coded as big endian, it may have to change to support
-    // SSE and Alpha MVI
-    if (NumElements == 2) {
-      Hi = Node->getOperand(0);
-      Lo = Node->getOperand(1);
-    } else {
-      NumElements /= 2; 
-      std::vector<SDOperand> LoOps, HiOps;
-      for (unsigned I = 0, E = NumElements; I < E; ++I) {
-        HiOps.push_back(Node->getOperand(I));
-        LoOps.push_back(Node->getOperand(I+NumElements));
-      }
-      Lo = DAG.getNode(ISD::ConstantVec, MVT::Vector, LoOps);
-      Hi = DAG.getNode(ISD::ConstantVec, MVT::Vector, HiOps);
-    }
-    break;
-  }
-
   case ISD::BUILD_PAIR:
-    // Legalize both operands.  FIXME: in the future we should handle the case
-    // where the two elements are not legal.
-    assert(isTypeLegal(NVT) && "Cannot expand this multiple times yet!");
-    Lo = LegalizeOp(Node->getOperand(0));
-    Hi = LegalizeOp(Node->getOperand(1));
+    // Return the operands.
+    Lo = Node->getOperand(0);
+    Hi = Node->getOperand(1);
     break;
     
   case ISD::SIGN_EXTEND_INREG:
@@ -3457,6 +3804,14 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Lo, Node->getOperand(1));
     break;
 
+  case ISD::BSWAP: {
+    ExpandOp(Node->getOperand(0), Lo, Hi);
+    SDOperand TempLo = DAG.getNode(ISD::BSWAP, NVT, Hi);
+    Hi = DAG.getNode(ISD::BSWAP, NVT, Lo);
+    Lo = TempLo;
+    break;
+  }
+    
   case ISD::CTPOP:
     ExpandOp(Node->getOperand(0), Lo, Hi);
     Lo = DAG.getNode(ISD::ADD, NVT,          // ctpop(HL) -> ctpop(H)+ctpop(L)
@@ -3495,17 +3850,30 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     break;
   }
 
+  case ISD::VAARG: {
+    SDOperand Ch = Node->getOperand(0);   // Legalize the chain.
+    SDOperand Ptr = Node->getOperand(1);  // Legalize the pointer.
+    Lo = DAG.getVAArg(NVT, Ch, Ptr, Node->getOperand(2));
+    Hi = DAG.getVAArg(NVT, Lo.getValue(1), Ptr, Node->getOperand(2));
+
+    // Remember that we legalized the chain.
+    Hi = LegalizeOp(Hi);
+    AddLegalizedOperand(Op.getValue(1), Hi.getValue(1));
+    if (!TLI.isLittleEndian())
+      std::swap(Lo, Hi);
+    break;
+  }
+    
   case ISD::LOAD: {
-    SDOperand Ch = LegalizeOp(Node->getOperand(0));   // Legalize the chain.
-    SDOperand Ptr = LegalizeOp(Node->getOperand(1));  // Legalize the pointer.
+    SDOperand Ch = Node->getOperand(0);   // Legalize the chain.
+    SDOperand Ptr = Node->getOperand(1);  // Legalize the pointer.
     Lo = DAG.getLoad(NVT, Ch, Ptr, Node->getOperand(2));
 
     // Increment the pointer to the other half.
     unsigned IncrementSize = MVT::getSizeInBits(Lo.getValueType())/8;
     Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
                       getIntPtrConstant(IncrementSize));
-    //Is this safe?  declaring that the two parts of the split load
-    //are from the same instruction?
+    // FIXME: This creates a bogus srcvalue!
     Hi = DAG.getLoad(NVT, Ch, Ptr, Node->getOperand(2));
 
     // Build a factor node to remember that this load is independent of the
@@ -3514,105 +3882,11 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
                                Hi.getValue(1));
 
     // Remember that we legalized the chain.
-    AddLegalizedOperand(Op.getValue(1), TF);
-    if (!TLI.isLittleEndian())
-      std::swap(Lo, Hi);
-    break;
-  }
-  case ISD::VLOAD: {
-    SDOperand Ch = LegalizeOp(Node->getOperand(0));   // Legalize the chain.
-    SDOperand Ptr = LegalizeOp(Node->getOperand(1));  // Legalize the pointer.
-    unsigned NumElements =cast<ConstantSDNode>(Node->getOperand(2))->getValue();
-    MVT::ValueType EVT = cast<VTSDNode>(Node->getOperand(3))->getVT();
-    
-    // If we only have two elements, turn into a pair of scalar loads.
-    // FIXME: handle case where a vector of two elements is fine, such as
-    //   2 x double on SSE2.
-    if (NumElements == 2) {
-      Lo = DAG.getLoad(EVT, Ch, Ptr, Node->getOperand(4));
-      // Increment the pointer to the other half.
-      unsigned IncrementSize = MVT::getSizeInBits(EVT)/8;
-      Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                        getIntPtrConstant(IncrementSize));
-      //Is this safe?  declaring that the two parts of the split load
-      //are from the same instruction?
-      Hi = DAG.getLoad(EVT, Ch, Ptr, Node->getOperand(4));
-    } else {
-      NumElements /= 2; // Split the vector in half
-      Lo = DAG.getVecLoad(NumElements, EVT, Ch, Ptr, Node->getOperand(4));
-      unsigned IncrementSize = NumElements * MVT::getSizeInBits(EVT)/8;
-      Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                        getIntPtrConstant(IncrementSize));
-      //Is this safe?  declaring that the two parts of the split load
-      //are from the same instruction?
-      Hi = DAG.getVecLoad(NumElements, EVT, Ch, Ptr, Node->getOperand(4));
-    }
-    
-    // Build a factor node to remember that this load is independent of the
-    // other one.
-    SDOperand TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
-                               Hi.getValue(1));
-    
-    // Remember that we legalized the chain.
-    AddLegalizedOperand(Op.getValue(1), TF);
+    AddLegalizedOperand(Op.getValue(1), LegalizeOp(TF));
     if (!TLI.isLittleEndian())
       std::swap(Lo, Hi);
     break;
   }
-  case ISD::VADD:
-  case ISD::VSUB:
-  case ISD::VMUL: {
-    unsigned NumElements =cast<ConstantSDNode>(Node->getOperand(2))->getValue();
-    MVT::ValueType EVT = cast<VTSDNode>(Node->getOperand(3))->getVT();
-    SDOperand LL, LH, RL, RH;
-    
-    ExpandOp(Node->getOperand(0), LL, LH);
-    ExpandOp(Node->getOperand(1), RL, RH);
-
-    // If we only have two elements, turn into a pair of scalar loads.
-    // FIXME: handle case where a vector of two elements is fine, such as
-    //   2 x double on SSE2.
-    if (NumElements == 2) {
-      unsigned Opc = getScalarizedOpcode(Node->getOpcode(), EVT);
-      Lo = DAG.getNode(Opc, EVT, LL, RL);
-      Hi = DAG.getNode(Opc, EVT, LH, RH);
-    } else {
-      Lo = DAG.getNode(Node->getOpcode(), MVT::Vector, LL, RL, LL.getOperand(2),
-                       LL.getOperand(3));
-      Hi = DAG.getNode(Node->getOpcode(), MVT::Vector, LH, RH, LH.getOperand(2),
-                       LH.getOperand(3));
-    }
-    break;
-  }
-  case ISD::TAILCALL:
-  case ISD::CALL: {
-    SDOperand Chain  = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    SDOperand Callee = LegalizeOp(Node->getOperand(1));  // Legalize the callee.
-
-    bool Changed = false;
-    std::vector<SDOperand> Ops;
-    for (unsigned i = 2, e = Node->getNumOperands(); i != e; ++i) {
-      Ops.push_back(LegalizeOp(Node->getOperand(i)));
-      Changed |= Ops.back() != Node->getOperand(i);
-    }
-
-    assert(Node->getNumValues() == 2 && Op.ResNo == 0 &&
-           "Can only expand a call once so far, not i64 -> i16!");
-
-    std::vector<MVT::ValueType> RetTyVTs;
-    RetTyVTs.reserve(3);
-    RetTyVTs.push_back(NVT);
-    RetTyVTs.push_back(NVT);
-    RetTyVTs.push_back(MVT::Other);
-    SDNode *NC = DAG.getCall(RetTyVTs, Chain, Callee, Ops,
-                             Node->getOpcode() == ISD::TAILCALL);
-    Lo = SDOperand(NC, 0);
-    Hi = SDOperand(NC, 1);
-
-    // Insert the new chain mapping.
-    AddLegalizedOperand(Op.getValue(1), Hi.getValue(2));
-    break;
-  }
   case ISD::AND:
   case ISD::OR:
   case ISD::XOR: {   // Simple logical operators -> two trivial pieces.
@@ -3624,21 +3898,11 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     break;
   }
   case ISD::SELECT: {
-    SDOperand C, LL, LH, RL, RH;
-
-    switch (getTypeAction(Node->getOperand(0).getValueType())) {
-    case Expand: assert(0 && "It's impossible to expand bools");
-    case Legal:
-      C = LegalizeOp(Node->getOperand(0)); // Legalize the condition.
-      break;
-    case Promote:
-      C = PromoteOp(Node->getOperand(0));  // Promote the condition.
-      break;
-    }
+    SDOperand LL, LH, RL, RH;
     ExpandOp(Node->getOperand(1), LL, LH);
     ExpandOp(Node->getOperand(2), RL, RH);
-    Lo = DAG.getNode(ISD::SELECT, NVT, C, LL, RL);
-    Hi = DAG.getNode(ISD::SELECT, NVT, C, LH, RH);
+    Lo = DAG.getNode(ISD::SELECT, NVT, Node->getOperand(0), LL, RL);
+    Hi = DAG.getNode(ISD::SELECT, NVT, Node->getOperand(0), LH, RH);
     break;
   }
   case ISD::SELECT_CC: {
@@ -3649,13 +3913,11 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
                      Node->getOperand(1), TL, FL, Node->getOperand(4));
     Hi = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0),
                      Node->getOperand(1), TH, FH, Node->getOperand(4));
-    Lo = LegalizeOp(Lo);
-    Hi = LegalizeOp(Hi);
     break;
   }
   case ISD::SEXTLOAD: {
-    SDOperand Chain = LegalizeOp(Node->getOperand(0));
-    SDOperand Ptr   = LegalizeOp(Node->getOperand(1));
+    SDOperand Chain = Node->getOperand(0);
+    SDOperand Ptr   = Node->getOperand(1);
     MVT::ValueType EVT = cast<VTSDNode>(Node->getOperand(3))->getVT();
     
     if (EVT == NVT)
@@ -3665,20 +3927,18 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
                           EVT);
     
     // Remember that we legalized the chain.
-    AddLegalizedOperand(SDOperand(Node, 1), Lo.getValue(1));
+    AddLegalizedOperand(SDOperand(Node, 1), LegalizeOp(Lo.getValue(1)));
     
     // The high part is obtained by SRA'ing all but one of the bits of the lo
     // part.
     unsigned LoSize = MVT::getSizeInBits(Lo.getValueType());
     Hi = DAG.getNode(ISD::SRA, NVT, Lo, DAG.getConstant(LoSize-1,
                                                        TLI.getShiftAmountTy()));
-    Lo = LegalizeOp(Lo);
-    Hi = LegalizeOp(Hi);
     break;
   }
   case ISD::ZEXTLOAD: {
-    SDOperand Chain = LegalizeOp(Node->getOperand(0));
-    SDOperand Ptr   = LegalizeOp(Node->getOperand(1));
+    SDOperand Chain = Node->getOperand(0);
+    SDOperand Ptr   = Node->getOperand(1);
     MVT::ValueType EVT = cast<VTSDNode>(Node->getOperand(3))->getVT();
     
     if (EVT == NVT)
@@ -3688,16 +3948,15 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
                           EVT);
     
     // Remember that we legalized the chain.
-    AddLegalizedOperand(SDOperand(Node, 1), Lo.getValue(1));
+    AddLegalizedOperand(SDOperand(Node, 1), LegalizeOp(Lo.getValue(1)));
 
     // The high part is just a zero.
-    Hi = LegalizeOp(DAG.getConstant(0, NVT));
-    Lo = LegalizeOp(Lo);
+    Hi = DAG.getConstant(0, NVT);
     break;
   }
   case ISD::EXTLOAD: {
-    SDOperand Chain = LegalizeOp(Node->getOperand(0));
-    SDOperand Ptr   = LegalizeOp(Node->getOperand(1));
+    SDOperand Chain = Node->getOperand(0);
+    SDOperand Ptr   = Node->getOperand(1);
     MVT::ValueType EVT = cast<VTSDNode>(Node->getOperand(3))->getVT();
     
     if (EVT == NVT)
@@ -3707,73 +3966,38 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
                           EVT);
     
     // Remember that we legalized the chain.
-    AddLegalizedOperand(SDOperand(Node, 1), Lo.getValue(1));
+    AddLegalizedOperand(SDOperand(Node, 1), LegalizeOp(Lo.getValue(1)));
     
     // The high part is undefined.
-    Hi = LegalizeOp(DAG.getNode(ISD::UNDEF, NVT));
-    Lo = LegalizeOp(Lo);
+    Hi = DAG.getNode(ISD::UNDEF, NVT);
     break;
   }
-  case ISD::ANY_EXTEND: {
-    SDOperand In;
-    switch (getTypeAction(Node->getOperand(0).getValueType())) {
-    case Expand: assert(0 && "expand-expand not implemented yet!");
-    case Legal: In = LegalizeOp(Node->getOperand(0)); break;
-    case Promote:
-      In = PromoteOp(Node->getOperand(0));
-      break;
-    }
-    
+  case ISD::ANY_EXTEND:
     // The low part is any extension of the input (which degenerates to a copy).
-    Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, In);
+    Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, Node->getOperand(0));
     // The high part is undefined.
     Hi = DAG.getNode(ISD::UNDEF, NVT);
     break;
-  }
   case ISD::SIGN_EXTEND: {
-    SDOperand In;
-    switch (getTypeAction(Node->getOperand(0).getValueType())) {
-    case Expand: assert(0 && "expand-expand not implemented yet!");
-    case Legal: In = LegalizeOp(Node->getOperand(0)); break;
-    case Promote:
-      In = PromoteOp(Node->getOperand(0));
-      // Emit the appropriate sign_extend_inreg to get the value we want.
-      In = DAG.getNode(ISD::SIGN_EXTEND_INREG, In.getValueType(), In,
-                       DAG.getValueType(Node->getOperand(0).getValueType()));
-      break;
-    }
-
     // The low part is just a sign extension of the input (which degenerates to
     // a copy).
-    Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, In);
+    Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, Node->getOperand(0));
 
     // The high part is obtained by SRA'ing all but one of the bits of the lo
     // part.
     unsigned LoSize = MVT::getSizeInBits(Lo.getValueType());
-    Hi = DAG.getNode(ISD::SRA, NVT, Lo, DAG.getConstant(LoSize-1,
-                                                       TLI.getShiftAmountTy()));
+    Hi = DAG.getNode(ISD::SRA, NVT, Lo,
+                     DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
     break;
   }
-  case ISD::ZERO_EXTEND: {
-    SDOperand In;
-    switch (getTypeAction(Node->getOperand(0).getValueType())) {
-    case Expand: assert(0 && "expand-expand not implemented yet!");
-    case Legal: In = LegalizeOp(Node->getOperand(0)); break;
-    case Promote:
-      In = PromoteOp(Node->getOperand(0));
-      // Emit the appropriate zero_extend_inreg to get the value we want.
-      In = DAG.getZeroExtendInReg(In, Node->getOperand(0).getValueType());
-      break;
-    }
-
+  case ISD::ZERO_EXTEND:
     // The low part is just a zero extension of the input (which degenerates to
     // a copy).
-    Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, In);
+    Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, Node->getOperand(0));
 
     // The high part is just a zero.
     Hi = DAG.getConstant(0, NVT);
     break;
-  }
     
   case ISD::BIT_CONVERT: {
     SDOperand Tmp = ExpandBIT_CONVERT(Node->getValueType(0), 
@@ -3782,18 +4006,16 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     break;
   }
 
-  case ISD::READCYCLECOUNTER: {
+  case ISD::READCYCLECOUNTER:
     assert(TLI.getOperationAction(ISD::READCYCLECOUNTER, VT) == 
                  TargetLowering::Custom &&
            "Must custom expand ReadCycleCounter");
-    SDOperand T = TLI.LowerOperation(Op, DAG);
-    assert(T.Val && "Node must be custom expanded!");
-    Lo = LegalizeOp(T.getValue(0));
-    Hi = LegalizeOp(T.getValue(1));
+    Lo = TLI.LowerOperation(Op, DAG);
+    assert(Lo.Val && "Node must be custom expanded!");
+    Hi = Lo.getValue(1);
     AddLegalizedOperand(SDOperand(Node, 1), // Remember we legalized the chain.
-                        LegalizeOp(T.getValue(2)));
+                        LegalizeOp(Lo.getValue(2)));
     break;
-  }
 
     // These operators cannot be expanded directly, emit them as calls to
     // library functions.
@@ -3802,8 +4024,8 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
       SDOperand Op;
       switch (getTypeAction(Node->getOperand(0).getValueType())) {
       case Expand: assert(0 && "cannot expand FP!");
-      case Legal: Op = LegalizeOp(Node->getOperand(0)); break;
-      case Promote: Op = PromoteOp(Node->getOperand(0)); break;
+      case Legal:   Op = LegalizeOp(Node->getOperand(0)); break;
+      case Promote: Op = PromoteOp (Node->getOperand(0)); break;
       }
 
       Op = TLI.LowerOperation(DAG.getNode(ISD::FP_TO_SINT, VT, Op), DAG);
@@ -3824,11 +4046,16 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
 
   case ISD::FP_TO_UINT:
     if (TLI.getOperationAction(ISD::FP_TO_UINT, VT) == TargetLowering::Custom) {
-      SDOperand Op = DAG.getNode(ISD::FP_TO_UINT, VT,
-                                 LegalizeOp(Node->getOperand(0)));
-      // Now that the custom expander is done, expand the result, which is still
-      // VT.
-      Op = TLI.LowerOperation(Op, DAG);
+      SDOperand Op;
+      switch (getTypeAction(Node->getOperand(0).getValueType())) {
+        case Expand: assert(0 && "cannot expand FP!");
+        case Legal:   Op = LegalizeOp(Node->getOperand(0)); break;
+        case Promote: Op = PromoteOp (Node->getOperand(0)); break;
+      }
+        
+      Op = TLI.LowerOperation(DAG.getNode(ISD::FP_TO_UINT, VT, Op), DAG);
+
+      // Now that the custom expander is done, expand the result.
       if (Op.Val) {
         ExpandOp(Op, Lo, Hi);
         break;
@@ -3841,11 +4068,11 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
       Lo = ExpandLibCall("__fixunsdfdi", Node, Hi);
     break;
 
-  case ISD::SHL:
+  case ISD::SHL: {
     // If the target wants custom lowering, do so.
+    SDOperand ShiftAmt = LegalizeOp(Node->getOperand(1));
     if (TLI.getOperationAction(ISD::SHL, VT) == TargetLowering::Custom) {
-      SDOperand Op = DAG.getNode(ISD::SHL, VT, Node->getOperand(0),
-                                 LegalizeOp(Node->getOperand(1)));
+      SDOperand Op = DAG.getNode(ISD::SHL, VT, Node->getOperand(0), ShiftAmt);
       Op = TLI.LowerOperation(Op, DAG);
       if (Op.Val) {
         // Now that the custom expander is done, expand the result, which is
@@ -3856,25 +4083,28 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     }
     
     // If we can emit an efficient shift operation, do so now.
-    if (ExpandShift(ISD::SHL, Node->getOperand(0), Node->getOperand(1), Lo, Hi))
+    if (ExpandShift(ISD::SHL, Node->getOperand(0), ShiftAmt, Lo, Hi))
       break;
 
     // If this target supports SHL_PARTS, use it.
-    if (TLI.isOperationLegal(ISD::SHL_PARTS, NVT)) {
-      ExpandShiftParts(ISD::SHL_PARTS, Node->getOperand(0), Node->getOperand(1),
-                       Lo, Hi);
+    TargetLowering::LegalizeAction Action =
+      TLI.getOperationAction(ISD::SHL_PARTS, NVT);
+    if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
+        Action == TargetLowering::Custom) {
+      ExpandShiftParts(ISD::SHL_PARTS, Node->getOperand(0), ShiftAmt, Lo, Hi);
       break;
     }
 
     // Otherwise, emit a libcall.
     Lo = ExpandLibCall("__ashldi3", Node, Hi);
     break;
+  }
 
-  case ISD::SRA:
+  case ISD::SRA: {
     // If the target wants custom lowering, do so.
+    SDOperand ShiftAmt = LegalizeOp(Node->getOperand(1));
     if (TLI.getOperationAction(ISD::SRA, VT) == TargetLowering::Custom) {
-      SDOperand Op = DAG.getNode(ISD::SRA, VT, Node->getOperand(0),
-                                 LegalizeOp(Node->getOperand(1)));
+      SDOperand Op = DAG.getNode(ISD::SRA, VT, Node->getOperand(0), ShiftAmt);
       Op = TLI.LowerOperation(Op, DAG);
       if (Op.Val) {
         // Now that the custom expander is done, expand the result, which is
@@ -3885,24 +4115,28 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     }
     
     // If we can emit an efficient shift operation, do so now.
-    if (ExpandShift(ISD::SRA, Node->getOperand(0), Node->getOperand(1), Lo, Hi))
+    if (ExpandShift(ISD::SRA, Node->getOperand(0), ShiftAmt, Lo, Hi))
       break;
 
     // If this target supports SRA_PARTS, use it.
-    if (TLI.isOperationLegal(ISD::SRA_PARTS, NVT)) {
-      ExpandShiftParts(ISD::SRA_PARTS, Node->getOperand(0), Node->getOperand(1),
-                       Lo, Hi);
+    TargetLowering::LegalizeAction Action =
+      TLI.getOperationAction(ISD::SRA_PARTS, NVT);
+    if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
+        Action == TargetLowering::Custom) {
+      ExpandShiftParts(ISD::SRA_PARTS, Node->getOperand(0), ShiftAmt, Lo, Hi);
       break;
     }
 
     // Otherwise, emit a libcall.
     Lo = ExpandLibCall("__ashrdi3", Node, Hi);
     break;
-  case ISD::SRL:
+  }
+
+  case ISD::SRL: {
     // If the target wants custom lowering, do so.
+    SDOperand ShiftAmt = LegalizeOp(Node->getOperand(1));
     if (TLI.getOperationAction(ISD::SRL, VT) == TargetLowering::Custom) {
-      SDOperand Op = DAG.getNode(ISD::SRL, VT, Node->getOperand(0),
-                                 LegalizeOp(Node->getOperand(1)));
+      SDOperand Op = DAG.getNode(ISD::SRL, VT, Node->getOperand(0), ShiftAmt);
       Op = TLI.LowerOperation(Op, DAG);
       if (Op.Val) {
         // Now that the custom expander is done, expand the result, which is
@@ -3913,28 +4147,58 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
     }
 
     // If we can emit an efficient shift operation, do so now.
-    if (ExpandShift(ISD::SRL, Node->getOperand(0), Node->getOperand(1), Lo, Hi))
+    if (ExpandShift(ISD::SRL, Node->getOperand(0), ShiftAmt, Lo, Hi))
       break;
 
     // If this target supports SRL_PARTS, use it.
-    if (TLI.isOperationLegal(ISD::SRL_PARTS, NVT)) {
-      ExpandShiftParts(ISD::SRL_PARTS, Node->getOperand(0), Node->getOperand(1),
-                       Lo, Hi);
+    TargetLowering::LegalizeAction Action =
+      TLI.getOperationAction(ISD::SRL_PARTS, NVT);
+    if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
+        Action == TargetLowering::Custom) {
+      ExpandShiftParts(ISD::SRL_PARTS, Node->getOperand(0), ShiftAmt, Lo, Hi);
       break;
     }
 
     // Otherwise, emit a libcall.
     Lo = ExpandLibCall("__lshrdi3", Node, Hi);
     break;
+  }
 
   case ISD::ADD:
-    ExpandByParts(ISD::ADD_PARTS, Node->getOperand(0), Node->getOperand(1),
-                  Lo, Hi);
-    break;
-  case ISD::SUB:
-    ExpandByParts(ISD::SUB_PARTS, Node->getOperand(0), Node->getOperand(1),
-                  Lo, Hi);
+  case ISD::SUB: {
+    // If the target wants to custom expand this, let them.
+    if (TLI.getOperationAction(Node->getOpcode(), VT) ==
+            TargetLowering::Custom) {
+      Op = TLI.LowerOperation(Op, DAG);
+      if (Op.Val) {
+        ExpandOp(Op, Lo, Hi);
+        break;
+      }
+    }
+    
+    // Expand the subcomponents.
+    SDOperand LHSL, LHSH, RHSL, RHSH;
+    ExpandOp(Node->getOperand(0), LHSL, LHSH);
+    ExpandOp(Node->getOperand(1), RHSL, RHSH);
+    std::vector<MVT::ValueType> VTs;
+    std::vector<SDOperand> LoOps, HiOps;
+    VTs.push_back(LHSL.getValueType());
+    VTs.push_back(MVT::Flag);
+    LoOps.push_back(LHSL);
+    LoOps.push_back(RHSL);
+    HiOps.push_back(LHSH);
+    HiOps.push_back(RHSH);
+    if (Node->getOpcode() == ISD::ADD) {
+      Lo = DAG.getNode(ISD::ADDC, VTs, LoOps);
+      HiOps.push_back(Lo.getValue(1));
+      Hi = DAG.getNode(ISD::ADDE, VTs, HiOps);
+    } else {
+      Lo = DAG.getNode(ISD::SUBC, VTs, LoOps);
+      HiOps.push_back(Lo.getValue(1));
+      Hi = DAG.getNode(ISD::SUBE, VTs, HiOps);
+    }
     break;
+  }
   case ISD::MUL: {
     if (TLI.isOperationLegal(ISD::MULHU, NVT)) {
       SDOperand LL, LH, RL, RH;
@@ -3964,7 +4228,7 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
       }
       Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
     } else {
-      Lo = ExpandLibCall("__muldi3" , Node, Hi); break;
+      Lo = ExpandLibCall("__muldi3" , Node, Hi);
     }
     break;
   }
@@ -3974,17 +4238,175 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
   case ISD::UREM: Lo = ExpandLibCall("__umoddi3", Node, Hi); break;
   }
 
-  // Remember in a map if the values will be reused later.
-  bool isNew = ExpandedNodes.insert(std::make_pair(Op,
-                                          std::make_pair(Lo, Hi))).second;
-  assert(isNew && "Value already expanded?!?");
-  
   // Make sure the resultant values have been legalized themselves, unless this
   // is a type that requires multi-step expansion.
   if (getTypeAction(NVT) != Expand && NVT != MVT::isVoid) {
     Lo = LegalizeOp(Lo);
     Hi = LegalizeOp(Hi);
   }
+
+  // Remember in a map if the values will be reused later.
+  bool isNew =
+    ExpandedNodes.insert(std::make_pair(Op, std::make_pair(Lo, Hi))).second;
+  assert(isNew && "Value already expanded?!?");
+}
+
+/// SplitVectorOp - Given an operand of MVT::Vector type, break it down into
+/// two smaller values of MVT::Vector type.
+void SelectionDAGLegalize::SplitVectorOp(SDOperand Op, SDOperand &Lo,
+                                         SDOperand &Hi) {
+  assert(Op.getValueType() == MVT::Vector && "Cannot split non-vector type!");
+  SDNode *Node = Op.Val;
+  unsigned NumElements = cast<ConstantSDNode>(*(Node->op_end()-2))->getValue();
+  assert(NumElements > 1 && "Cannot split a single element vector!");
+  unsigned NewNumElts = NumElements/2;
+  SDOperand NewNumEltsNode = DAG.getConstant(NewNumElts, MVT::i32);
+  SDOperand TypeNode = *(Node->op_end()-1);
+  
+  // See if we already split it.
+  std::map<SDOperand, std::pair<SDOperand, SDOperand> >::iterator I
+    = SplitNodes.find(Op);
+  if (I != SplitNodes.end()) {
+    Lo = I->second.first;
+    Hi = I->second.second;
+    return;
+  }
+  
+  switch (Node->getOpcode()) {
+  default: assert(0 && "Unknown vector operation!");
+  case ISD::VBUILD_VECTOR: {
+    std::vector<SDOperand> LoOps(Node->op_begin(), Node->op_begin()+NewNumElts);
+    LoOps.push_back(NewNumEltsNode);
+    LoOps.push_back(TypeNode);
+    Lo = DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, LoOps);
+
+    std::vector<SDOperand> HiOps(Node->op_begin()+NewNumElts, Node->op_end()-2);
+    HiOps.push_back(NewNumEltsNode);
+    HiOps.push_back(TypeNode);
+    Hi = DAG.getNode(ISD::VBUILD_VECTOR, MVT::Vector, HiOps);
+    break;
+  }
+  case ISD::VADD:
+  case ISD::VSUB:
+  case ISD::VMUL:
+  case ISD::VSDIV:
+  case ISD::VUDIV:
+  case ISD::VAND:
+  case ISD::VOR:
+  case ISD::VXOR: {
+    SDOperand LL, LH, RL, RH;
+    SplitVectorOp(Node->getOperand(0), LL, LH);
+    SplitVectorOp(Node->getOperand(1), RL, RH);
+    
+    Lo = DAG.getNode(Node->getOpcode(), MVT::Vector, LL, RL,
+                     NewNumEltsNode, TypeNode);
+    Hi = DAG.getNode(Node->getOpcode(), MVT::Vector, LH, RH,
+                     NewNumEltsNode, TypeNode);
+    break;
+  }
+  case ISD::VLOAD: {
+    SDOperand Ch = Node->getOperand(0);   // Legalize the chain.
+    SDOperand Ptr = Node->getOperand(1);  // Legalize the pointer.
+    MVT::ValueType EVT = cast<VTSDNode>(TypeNode)->getVT();
+    
+    Lo = DAG.getVecLoad(NewNumElts, EVT, Ch, Ptr, Node->getOperand(2));
+    unsigned IncrementSize = NewNumElts * MVT::getSizeInBits(EVT)/8;
+    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                      getIntPtrConstant(IncrementSize));
+    // FIXME: This creates a bogus srcvalue!
+    Hi = DAG.getVecLoad(NewNumElts, EVT, Ch, Ptr, Node->getOperand(2));
+    
+    // Build a factor node to remember that this load is independent of the
+    // other one.
+    SDOperand TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+                               Hi.getValue(1));
+    
+    // Remember that we legalized the chain.
+    AddLegalizedOperand(Op.getValue(1), LegalizeOp(TF));
+    if (!TLI.isLittleEndian())
+      std::swap(Lo, Hi);
+    break;
+  }
+  }
+      
+  // Remember in a map if the values will be reused later.
+  bool isNew =
+    SplitNodes.insert(std::make_pair(Op, std::make_pair(Lo, Hi))).second;
+  assert(isNew && "Value already expanded?!?");
+}
+
+
+/// PackVectorOp - Given an operand of MVT::Vector type, convert it into the
+/// equivalent operation that returns a scalar (e.g. F32) or packed value
+/// (e.g. MVT::V4F32).  When this is called, we know that PackedVT is the right
+/// type for the result.
+SDOperand SelectionDAGLegalize::PackVectorOp(SDOperand Op, 
+                                             MVT::ValueType NewVT) {
+  // FIXME: THIS IS A TEMPORARY HACK
+  if (Op.getValueType() == NewVT) return Op;
+    
+  assert(Op.getValueType() == MVT::Vector && "Bad PackVectorOp invocation!");
+  SDNode *Node = Op.Val;
+  
+  // See if we already packed it.
+  std::map<SDOperand, SDOperand>::iterator I = PackedNodes.find(Op);
+  if (I != PackedNodes.end()) return I->second;
+  
+  SDOperand Result;
+  switch (Node->getOpcode()) {
+  default: 
+    Node->dump(); std::cerr << "\n";
+    assert(0 && "Unknown vector operation in PackVectorOp!");
+  case ISD::VADD:
+  case ISD::VSUB:
+  case ISD::VMUL:
+  case ISD::VSDIV:
+  case ISD::VUDIV:
+  case ISD::VAND:
+  case ISD::VOR:
+  case ISD::VXOR:
+    Result = DAG.getNode(getScalarizedOpcode(Node->getOpcode(), NewVT),
+                         NewVT, 
+                         PackVectorOp(Node->getOperand(0), NewVT),
+                         PackVectorOp(Node->getOperand(1), NewVT));
+    break;
+  case ISD::VLOAD: {
+    SDOperand Ch = LegalizeOp(Node->getOperand(0));   // Legalize the chain.
+    SDOperand Ptr = LegalizeOp(Node->getOperand(1));  // Legalize the pointer.
+    
+    Result = DAG.getLoad(NewVT, Ch, Ptr, Node->getOperand(2));
+    
+    // Remember that we legalized the chain.
+    AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1)));
+    break;
+  }
+  case ISD::VBUILD_VECTOR:
+    if (!MVT::isVector(NewVT)) {
+      // Returning a scalar?
+      Result = Node->getOperand(0);
+    } else {
+      // Returning a BUILD_VECTOR?
+      std::vector<SDOperand> Ops(Node->op_begin(), Node->op_end()-2);
+      Result = DAG.getNode(ISD::BUILD_VECTOR, NewVT, Ops);
+    }
+    break;
+  case ISD::VINSERT_VECTOR_ELT:
+    if (!MVT::isVector(NewVT)) {
+      // Returning a scalar?  Must be the inserted element.
+      Result = Node->getOperand(1);
+    } else {
+      Result = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT,
+                           PackVectorOp(Node->getOperand(0), NewVT),
+                           Node->getOperand(1), Node->getOperand(2));
+    }
+    break;
+  }
+
+  if (TLI.isTypeLegal(NewVT))
+    Result = LegalizeOp(Result);
+  bool isNew = PackedNodes.insert(std::make_pair(Op, Result)).second;
+  assert(isNew && "Value already packed?");
+  return Result;
 }
 
 
@@ -3993,6 +4415,6 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){
 void SelectionDAG::Legalize() {
   /// run - This is the main entry point to this class.
   ///
-  SelectionDAGLegalize(*this).Run();
+  SelectionDAGLegalize(*this).LegalizeDAG();
 }