[llvm-commits] [llvm] r52408 - in /llvm/trunk/lib/CodeGen/SelectionDAG: LegalizeFloatTypes.cpp LegalizeIntegerTypes.cpp LegalizeTypes.cpp LegalizeTypes.h LegalizeTypesExpand.cpp LegalizeTypesFloatToInt.cpp LegalizeTypesPromote.cpp LegalizeTypesScalarize.cpp LegalizeTypesSplit.cpp LegalizeVectorTypes.cpp

Duncan Sands baldrick at free.fr
Tue Jun 17 07:27:01 PDT 2008


Author: baldrick
Date: Tue Jun 17 09:27:01 2008
New Revision: 52408

URL: http://llvm.org/viewvc/llvm-project?rev=52408&view=rev
Log:
Split type expansion into ExpandInteger and ExpandFloat
rather than bundling them together.  Rename FloatToInt
to PromoteFloat (better, if not perfect).  Reorganize
files by types rather than by operations.

Added:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
Removed:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesFloatToInt.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp
Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h

Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp?rev=52408&view=auto

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp (added)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp Tue Jun 17 09:27:01 2008
@@ -0,0 +1,452 @@
+//===-------- LegalizeFloatTypes.cpp - Legalization of float types --------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements float type expansion and conversion of float types to
+// integer types on behalf of LegalizeTypes.
+// Converting to integer is the act of turning a computation in an illegal
+// floating point type into a computation in an integer type of the same size.
+// For example, turning f32 arithmetic into operations using i32.  Also known as
+// "soft float".  The result is equivalent to bitcasting the float value to the
+// integer type.
+// Expansion is the act of changing a computation in an illegal type to be a
+// computation in multiple registers of a smaller type.  For example,
+// implementing ppcf128 arithmetic in two f64 registers.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LegalizeTypes.h"
+#include "llvm/CodeGen/PseudoSourceValue.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+using namespace llvm;
+
+/// GetFPLibCall - Return the right libcall for the given floating point type.
+static RTLIB::Libcall GetFPLibCall(MVT VT,
+                                   RTLIB::Libcall Call_F32,
+                                   RTLIB::Libcall Call_F64,
+                                   RTLIB::Libcall Call_F80,
+                                   RTLIB::Libcall Call_PPCF128) {
+  return
+    VT == MVT::f32 ? Call_F32 :
+    VT == MVT::f64 ? Call_F64 :
+    VT == MVT::f80 ? Call_F80 :
+    VT == MVT::ppcf128 ? Call_PPCF128 :
+    RTLIB::UNKNOWN_LIBCALL;
+}
+
+//===----------------------------------------------------------------------===//
+//  Result Float to Integer Conversion.
+//===----------------------------------------------------------------------===//
+
+void DAGTypeLegalizer::PromoteFloatResult(SDNode *N, unsigned ResNo) {
+  DEBUG(cerr << "Promote float result " << ResNo << ": "; N->dump(&DAG);
+        cerr << "\n");
+  SDOperand R = SDOperand();
+
+  // FIXME: Custom lowering for float-to-int?
+#if 0
+  // See if the target wants to custom convert this node to an integer.
+  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
+      TargetLowering::Custom) {
+    // If the target wants to, allow it to lower this itself.
+    if (SDNode *P = TLI.FloatToIntOperationResult(N, DAG)) {
+      // Everything that once used N now uses P.  We are guaranteed that the
+      // result value types of N and the result value types of P match.
+      ReplaceNodeWith(N, P);
+      return;
+    }
+  }
+#endif
+
+  switch (N->getOpcode()) {
+  default:
+#ifndef NDEBUG
+    cerr << "PromoteFloatResult #" << ResNo << ": ";
+    N->dump(&DAG); cerr << "\n";
+#endif
+    assert(0 && "Do not know how to convert the result of this operator!");
+    abort();
+
+    case ISD::BIT_CONVERT: R = PromoteFloatRes_BIT_CONVERT(N); break;
+    case ISD::BUILD_PAIR:  R = PromoteFloatRes_BUILD_PAIR(N); break;
+    case ISD::ConstantFP:
+      R = PromoteFloatRes_ConstantFP(cast<ConstantFPSDNode>(N));
+      break;
+    case ISD::FCOPYSIGN:   R = PromoteFloatRes_FCOPYSIGN(N); break;
+    case ISD::LOAD:        R = PromoteFloatRes_LOAD(N); break;
+    case ISD::SINT_TO_FP:
+    case ISD::UINT_TO_FP:  R = PromoteFloatRes_XINT_TO_FP(N); break;
+
+    case ISD::FADD: R = PromoteFloatRes_FADD(N); break;
+    case ISD::FMUL: R = PromoteFloatRes_FMUL(N); break;
+    case ISD::FSUB: R = PromoteFloatRes_FSUB(N); break;
+  }
+
+  // If R is null, the sub-method took care of registering the result.
+  if (R.Val)
+    SetPromotedFloat(SDOperand(N, ResNo), R);
+}
+
+SDOperand DAGTypeLegalizer::PromoteFloatRes_BIT_CONVERT(SDNode *N) {
+  return BitConvertToInteger(N->getOperand(0));
+}
+
+SDOperand DAGTypeLegalizer::PromoteFloatRes_BUILD_PAIR(SDNode *N) {
+  // Convert the inputs to integers, and build a new pair out of them.
+  return DAG.getNode(ISD::BUILD_PAIR,
+                     TLI.getTypeToTransformTo(N->getValueType(0)),
+                     BitConvertToInteger(N->getOperand(0)),
+                     BitConvertToInteger(N->getOperand(1)));
+}
+
+SDOperand DAGTypeLegalizer::PromoteFloatRes_ConstantFP(ConstantFPSDNode *N) {
+  return DAG.getConstant(N->getValueAPF().convertToAPInt(),
+                         TLI.getTypeToTransformTo(N->getValueType(0)));
+}
+
+SDOperand DAGTypeLegalizer::PromoteFloatRes_FADD(SDNode *N) {
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  SDOperand Ops[2] = { GetPromotedFloat(N->getOperand(0)),
+                       GetPromotedFloat(N->getOperand(1)) };
+  return MakeLibCall(GetFPLibCall(N->getValueType(0),
+                                  RTLIB::ADD_F32,
+                                  RTLIB::ADD_F64,
+                                  RTLIB::ADD_F80,
+                                  RTLIB::ADD_PPCF128),
+                     NVT, Ops, 2, false/*sign irrelevant*/);
+}
+
+SDOperand DAGTypeLegalizer::PromoteFloatRes_FCOPYSIGN(SDNode *N) {
+  SDOperand LHS = GetPromotedFloat(N->getOperand(0));
+  SDOperand RHS = BitConvertToInteger(N->getOperand(1));
+
+  MVT LVT = LHS.getValueType();
+  MVT RVT = RHS.getValueType();
+
+  unsigned LSize = LVT.getSizeInBits();
+  unsigned RSize = RVT.getSizeInBits();
+
+  // First get the sign bit of second operand.
+  SDOperand SignBit = DAG.getNode(ISD::SHL, RVT, DAG.getConstant(1, RVT),
+                                  DAG.getConstant(RSize - 1,
+                                                  TLI.getShiftAmountTy()));
+  SignBit = DAG.getNode(ISD::AND, RVT, RHS, SignBit);
+
+  // Shift right or sign-extend it if the two operands have different types.
+  int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits();
+  if (SizeDiff > 0) {
+    SignBit = DAG.getNode(ISD::SRL, RVT, SignBit,
+                          DAG.getConstant(SizeDiff, TLI.getShiftAmountTy()));
+    SignBit = DAG.getNode(ISD::TRUNCATE, LVT, SignBit);
+  } else if (SizeDiff < 0) {
+    SignBit = DAG.getNode(ISD::ANY_EXTEND, LVT, SignBit);
+    SignBit = DAG.getNode(ISD::SHL, LVT, SignBit,
+                          DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy()));
+  }
+
+  // Clear the sign bit of the first operand.
+  SDOperand Mask = DAG.getNode(ISD::SHL, LVT, DAG.getConstant(1, LVT),
+                               DAG.getConstant(LSize - 1,
+                                               TLI.getShiftAmountTy()));
+  Mask = DAG.getNode(ISD::SUB, LVT, Mask, DAG.getConstant(1, LVT));
+  LHS = DAG.getNode(ISD::AND, LVT, LHS, Mask);
+
+  // Or the value with the sign bit.
+  return DAG.getNode(ISD::OR, LVT, LHS, SignBit);
+}
+
+SDOperand DAGTypeLegalizer::PromoteFloatRes_FMUL(SDNode *N) {
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  SDOperand Ops[2] = { GetPromotedFloat(N->getOperand(0)),
+                       GetPromotedFloat(N->getOperand(1)) };
+  return MakeLibCall(GetFPLibCall(N->getValueType(0),
+                                  RTLIB::MUL_F32,
+                                  RTLIB::MUL_F64,
+                                  RTLIB::MUL_F80,
+                                  RTLIB::MUL_PPCF128),
+                     NVT, Ops, 2, false/*sign irrelevant*/);
+}
+
+SDOperand DAGTypeLegalizer::PromoteFloatRes_FSUB(SDNode *N) {
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  SDOperand Ops[2] = { GetPromotedFloat(N->getOperand(0)),
+                       GetPromotedFloat(N->getOperand(1)) };
+  return MakeLibCall(GetFPLibCall(N->getValueType(0),
+                                  RTLIB::SUB_F32,
+                                  RTLIB::SUB_F64,
+                                  RTLIB::SUB_F80,
+                                  RTLIB::SUB_PPCF128),
+                     NVT, Ops, 2, false/*sign irrelevant*/);
+}
+
+SDOperand DAGTypeLegalizer::PromoteFloatRes_LOAD(SDNode *N) {
+  LoadSDNode *L = cast<LoadSDNode>(N);
+  MVT VT = N->getValueType(0);
+  MVT NVT = TLI.getTypeToTransformTo(VT);
+
+  if (L->getExtensionType() == ISD::NON_EXTLOAD)
+     return DAG.getLoad(L->getAddressingMode(), L->getExtensionType(),
+                        NVT, L->getChain(), L->getBasePtr(), L->getOffset(),
+                        L->getSrcValue(), L->getSrcValueOffset(), NVT,
+                        L->isVolatile(), L->getAlignment());
+
+  // Do a non-extending load followed by FP_EXTEND.
+  SDOperand NL = DAG.getLoad(L->getAddressingMode(), ISD::NON_EXTLOAD,
+                             L->getMemoryVT(), L->getChain(),
+                             L->getBasePtr(), L->getOffset(),
+                             L->getSrcValue(), L->getSrcValueOffset(),
+                             L->getMemoryVT(),
+                             L->isVolatile(), L->getAlignment());
+  return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, VT, NL));
+}
+
+SDOperand DAGTypeLegalizer::PromoteFloatRes_XINT_TO_FP(SDNode *N) {
+  bool isSigned = N->getOpcode() == ISD::SINT_TO_FP;
+  MVT DestVT = N->getValueType(0);
+  SDOperand Op = N->getOperand(0);
+
+  if (Op.getValueType() == MVT::i32) {
+    // simple 32-bit [signed|unsigned] integer to float/double expansion
+
+    // Get the stack frame index of a 8 byte buffer.
+    SDOperand StackSlot = DAG.CreateStackTemporary(MVT::f64);
+
+    // word offset constant for Hi/Lo address computation
+    SDOperand Offset =
+      DAG.getConstant(MVT(MVT::i32).getSizeInBits() / 8,
+                      TLI.getPointerTy());
+    // set up Hi and Lo (into buffer) address based on endian
+    SDOperand Hi = StackSlot;
+    SDOperand Lo = DAG.getNode(ISD::ADD, TLI.getPointerTy(), StackSlot, Offset);
+    if (TLI.isLittleEndian())
+      std::swap(Hi, Lo);
+
+    // if signed map to unsigned space
+    SDOperand OpMapped;
+    if (isSigned) {
+      // constant used to invert sign bit (signed to unsigned mapping)
+      SDOperand SignBit = DAG.getConstant(0x80000000u, MVT::i32);
+      OpMapped = DAG.getNode(ISD::XOR, MVT::i32, Op, SignBit);
+    } else {
+      OpMapped = Op;
+    }
+    // store the lo of the constructed double - based on integer input
+    SDOperand Store1 = DAG.getStore(DAG.getEntryNode(),
+                                    OpMapped, Lo, NULL, 0);
+    // 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.getStore(Store1, InitialHi, Hi, NULL, 0);
+    // load the constructed double
+    SDOperand Load = DAG.getLoad(MVT::f64, Store2, StackSlot, NULL, 0);
+    // 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 (DestVT.bitsLT(MVT::f64)) {
+      Result = DAG.getNode(ISD::FP_ROUND, DestVT, Sub,
+                           DAG.getIntPtrConstant(0));
+    } else if (DestVT.bitsGT(MVT::f64)) {
+      Result = DAG.getNode(ISD::FP_EXTEND, DestVT, Sub);
+    }
+    return BitConvertToInteger(Result);
+  }
+  assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet");
+  SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op);
+
+  SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultType(Op), Op,
+                                   DAG.getConstant(0, Op.getValueType()),
+                                   ISD::SETLT);
+  SDOperand Zero = DAG.getIntPtrConstant(0), Four = DAG.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 (Op.getValueType().getSimpleVT()) {
+  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 = ConstantInt::get(Type::Int64Ty, 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,
+                             PseudoSourceValue::getConstantPool(), 0);
+  else {
+    FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, DestVT,
+                                DAG.getEntryNode(), CPIdx,
+                                PseudoSourceValue::getConstantPool(), 0,
+                                MVT::f32);
+  }
+
+  return BitConvertToInteger(DAG.getNode(ISD::FADD, DestVT, Tmp1, FudgeInReg));
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Operand Float to Integer Conversion..
+//===----------------------------------------------------------------------===//
+
+bool DAGTypeLegalizer::PromoteFloatOperand(SDNode *N, unsigned OpNo) {
+  DEBUG(cerr << "Promote float operand " << OpNo << ": "; N->dump(&DAG);
+        cerr << "\n");
+  SDOperand Res(0, 0);
+
+  // FIXME: Custom lowering for float-to-int?
+#if 0
+  if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
+      == TargetLowering::Custom)
+    Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
+#endif
+
+  if (Res.Val == 0) {
+    switch (N->getOpcode()) {
+    default:
+#ifndef NDEBUG
+      cerr << "PromoteFloatOperand Op #" << OpNo << ": ";
+      N->dump(&DAG); cerr << "\n";
+#endif
+      assert(0 && "Do not know how to convert this operator's operand!");
+      abort();
+
+      case ISD::BIT_CONVERT: Res = PromoteFloatOp_BIT_CONVERT(N); break;
+    }
+  }
+
+  // If the result is null, the sub-method took care of registering results etc.
+  if (!Res.Val) return false;
+
+  // If the result is N, the sub-method updated N in place.  Check to see if any
+  // operands are new, and if so, mark them.
+  if (Res.Val == N) {
+    // Mark N as new and remark N and its operands.  This allows us to correctly
+    // revisit N if it needs another step of promotion and allows us to visit
+    // any new operands to N.
+    ReanalyzeNode(N);
+    return true;
+  }
+
+  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
+         "Invalid operand expansion");
+
+  ReplaceValueWith(SDOperand(N, 0), Res);
+  return false;
+}
+
+SDOperand DAGTypeLegalizer::PromoteFloatOp_BIT_CONVERT(SDNode *N) {
+  return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0),
+                     GetPromotedFloat(N->getOperand(0)));
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Float Result Expansion
+//===----------------------------------------------------------------------===//
+
+/// ExpandFloatResult - This method is called when the specified result of the
+/// specified node is found to need expansion.  At this point, the node may also
+/// have invalid operands or may have other results that need promotion, we just
+/// know that (at least) one result needs expansion.
+void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) {
+  DEBUG(cerr << "Expand float result: "; N->dump(&DAG); cerr << "\n");
+  SDOperand Lo, Hi;
+  Lo = Hi = SDOperand();
+
+  // See if the target wants to custom expand this node.
+  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
+          TargetLowering::Custom) {
+    // If the target wants to, allow it to lower this itself.
+    if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
+      // Everything that once used N now uses P.  We are guaranteed that the
+      // result value types of N and the result value types of P match.
+      ReplaceNodeWith(N, P);
+      return;
+    }
+  }
+
+  switch (N->getOpcode()) {
+  default:
+#ifndef NDEBUG
+    cerr << "ExpandFloatResult #" << ResNo << ": ";
+    N->dump(&DAG); cerr << "\n";
+#endif
+    assert(0 && "Do not know how to expand the result of this operator!");
+    abort();
+  }
+
+  // If Lo/Hi is null, the sub-method took care of registering results etc.
+  if (Lo.Val)
+    SetExpandedFloat(SDOperand(N, ResNo), Lo, Hi);
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Float Operand Expansion
+//===----------------------------------------------------------------------===//
+
+/// ExpandFloatOperand - This method is called when the specified operand of the
+/// specified node is found to need expansion.  At this point, all of the result
+/// types of the node are known to be legal, but other operands of the node may
+/// need promotion or expansion as well as the specified one.
+bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
+  DEBUG(cerr << "Expand float operand: "; N->dump(&DAG); cerr << "\n");
+  SDOperand Res(0, 0);
+
+  if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
+      == TargetLowering::Custom)
+    Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
+
+  if (Res.Val == 0) {
+    switch (N->getOpcode()) {
+    default:
+  #ifndef NDEBUG
+      cerr << "ExpandFloatOperand Op #" << OpNo << ": ";
+      N->dump(&DAG); cerr << "\n";
+  #endif
+      assert(0 && "Do not know how to expand this operator's operand!");
+      abort();
+    }
+  }
+
+  // If the result is null, the sub-method took care of registering results etc.
+  if (!Res.Val) return false;
+  // If the result is N, the sub-method updated N in place.  Check to see if any
+  // operands are new, and if so, mark them.
+  if (Res.Val == N) {
+    // Mark N as new and remark N and its operands.  This allows us to correctly
+    // revisit N if it needs another step of expansion and allows us to visit
+    // any new operands to N.
+    ReanalyzeNode(N);
+    return true;
+  }
+
+  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
+         "Invalid operand expansion");
+
+  ReplaceValueWith(SDOperand(N, 0), Res);
+  return false;
+}

Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp?rev=52408&view=auto

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp (added)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp Tue Jun 17 09:27:01 2008
@@ -0,0 +1,2174 @@
+//===----- LegalizeIntegerTypes.cpp - Legalization of integer types -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements integer type expansion and promotion for LegalizeTypes.
+// Promotion is the act of changing a computation in an illegal type into a
+// computation in a larger type.  For example, implementing i8 arithmetic in an
+// i32 register (often needed on powerpc).
+// Expansion is the act of changing a computation in an illegal type into a
+// computation in multiple registers of a smaller type.  For example,
+// implementing i64 arithmetic in two i32 registers (often needed on 32-bit
+// targets).
+//
+//===----------------------------------------------------------------------===//
+
+#include "LegalizeTypes.h"
+#include "llvm/Constants.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+//  Integer Result Promotion
+//===----------------------------------------------------------------------===//
+
+/// PromoteIntegerResult - This method is called when a result of a node is
+/// found to be in need of promotion to a larger type.  At this point, the node
+/// may also have invalid operands or may have other results that need
+/// expansion, we just know that (at least) one result needs promotion.
+void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) {
+  DEBUG(cerr << "Promote integer result: "; N->dump(&DAG); cerr << "\n");
+  SDOperand Result = SDOperand();
+
+  switch (N->getOpcode()) {
+  default:
+#ifndef NDEBUG
+    cerr << "PromoteIntegerResult #" << ResNo << ": ";
+    N->dump(&DAG); cerr << "\n";
+#endif
+    assert(0 && "Do not know how to promote this operator!");
+    abort();
+  case ISD::UNDEF:    Result = PromoteIntRes_UNDEF(N); break;
+  case ISD::Constant: Result = PromoteIntRes_Constant(N); break;
+
+  case ISD::TRUNCATE:    Result = PromoteIntRes_TRUNCATE(N); break;
+  case ISD::SIGN_EXTEND:
+  case ISD::ZERO_EXTEND:
+  case ISD::ANY_EXTEND:  Result = PromoteIntRes_INT_EXTEND(N); break;
+  case ISD::FP_ROUND:    Result = PromoteIntRes_FP_ROUND(N); break;
+  case ISD::FP_TO_SINT:
+  case ISD::FP_TO_UINT:  Result = PromoteIntRes_FP_TO_XINT(N); break;
+  case ISD::SETCC:    Result = PromoteIntRes_SETCC(N); break;
+  case ISD::LOAD:     Result = PromoteIntRes_LOAD(cast<LoadSDNode>(N)); break;
+  case ISD::BUILD_PAIR:  Result = PromoteIntRes_BUILD_PAIR(N); break;
+  case ISD::BIT_CONVERT: Result = PromoteIntRes_BIT_CONVERT(N); break;
+
+  case ISD::AND:
+  case ISD::OR:
+  case ISD::XOR:
+  case ISD::ADD:
+  case ISD::SUB:
+  case ISD::MUL:      Result = PromoteIntRes_SimpleIntBinOp(N); break;
+
+  case ISD::SDIV:
+  case ISD::SREM:     Result = PromoteIntRes_SDIV(N); break;
+
+  case ISD::UDIV:
+  case ISD::UREM:     Result = PromoteIntRes_UDIV(N); break;
+
+  case ISD::SHL:      Result = PromoteIntRes_SHL(N); break;
+  case ISD::SRA:      Result = PromoteIntRes_SRA(N); break;
+  case ISD::SRL:      Result = PromoteIntRes_SRL(N); break;
+
+  case ISD::SELECT:    Result = PromoteIntRes_SELECT(N); break;
+  case ISD::SELECT_CC: Result = PromoteIntRes_SELECT_CC(N); break;
+
+  case ISD::CTLZ:     Result = PromoteIntRes_CTLZ(N); break;
+  case ISD::CTPOP:    Result = PromoteIntRes_CTPOP(N); break;
+  case ISD::CTTZ:     Result = PromoteIntRes_CTTZ(N); break;
+
+  case ISD::EXTRACT_VECTOR_ELT:
+    Result = PromoteIntRes_EXTRACT_VECTOR_ELT(N);
+    break;
+  }
+
+  // If Result is null, the sub-method took care of registering the result.
+  if (Result.Val)
+    SetPromotedInteger(SDOperand(N, ResNo), Result);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) {
+  return DAG.getNode(ISD::UNDEF, TLI.getTypeToTransformTo(N->getValueType(0)));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_Constant(SDNode *N) {
+  MVT VT = N->getValueType(0);
+  // Zero extend things like i1, sign extend everything else.  It shouldn't
+  // matter in theory which one we pick, but this tends to give better code?
+  unsigned Opc = VT.isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
+  SDOperand Result = DAG.getNode(Opc, TLI.getTypeToTransformTo(VT),
+                                 SDOperand(N, 0));
+  assert(isa<ConstantSDNode>(Result) && "Didn't constant fold ext?");
+  return Result;
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) {
+  SDOperand Res;
+
+  switch (getTypeAction(N->getOperand(0).getValueType())) {
+  default: assert(0 && "Unknown type action!");
+  case Legal:
+  case ExpandInteger:
+    Res = N->getOperand(0);
+    break;
+  case PromoteInteger:
+    Res = GetPromotedInteger(N->getOperand(0));
+    break;
+  }
+
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  assert(Res.getValueType().getSizeInBits() >= NVT.getSizeInBits() &&
+         "Truncation doesn't make sense!");
+  if (Res.getValueType() == NVT)
+    return Res;
+
+  // Truncate to NVT instead of VT
+  return DAG.getNode(ISD::TRUNCATE, NVT, Res);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) {
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+
+  if (getTypeAction(N->getOperand(0).getValueType()) == PromoteInteger) {
+    SDOperand Res = GetPromotedInteger(N->getOperand(0));
+    assert(Res.getValueType().getSizeInBits() <= NVT.getSizeInBits() &&
+           "Extension doesn't make sense!");
+
+    // If the result and operand types are the same after promotion, simplify
+    // to an in-register extension.
+    if (NVT == Res.getValueType()) {
+      // The high bits are not guaranteed to be anything.  Insert an extend.
+      if (N->getOpcode() == ISD::SIGN_EXTEND)
+        return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res,
+                           DAG.getValueType(N->getOperand(0).getValueType()));
+      if (N->getOpcode() == ISD::ZERO_EXTEND)
+        return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType());
+      assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!");
+      return Res;
+    }
+  }
+
+  // Otherwise, just extend the original operand all the way to the larger type.
+  return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_FP_ROUND(SDNode *N) {
+  // NOTE: Assumes input is legal.
+  if (N->getConstantOperandVal(1) == 0)
+    return DAG.getNode(ISD::FP_ROUND_INREG, N->getOperand(0).getValueType(),
+                       N->getOperand(0), DAG.getValueType(N->getValueType(0)));
+  // If the precision discard isn't needed, just return the operand unrounded.
+  return N->getOperand(0);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) {
+  unsigned NewOpc = N->getOpcode();
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+
+  // If we're promoting a UINT to a larger size, check to see if the new node
+  // will be legal.  If it isn't, check to see if FP_TO_SINT is legal, since
+  // we can use that instead.  This allows us to generate better code for
+  // FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not
+  // legal, such as PowerPC.
+  if (N->getOpcode() == ISD::FP_TO_UINT) {
+    if (!TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) &&
+        (TLI.isOperationLegal(ISD::FP_TO_SINT, NVT) ||
+         TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom))
+      NewOpc = ISD::FP_TO_SINT;
+  }
+
+  return DAG.getNode(NewOpc, NVT, N->getOperand(0));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) {
+  assert(isTypeLegal(TLI.getSetCCResultType(N->getOperand(0)))
+         && "SetCC type is not legal??");
+  return DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(N->getOperand(0)),
+                     N->getOperand(0), N->getOperand(1), N->getOperand(2));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) {
+  // FIXME: Add support for indexed loads.
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  ISD::LoadExtType ExtType =
+    ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType();
+  SDOperand Res = DAG.getExtLoad(ExtType, NVT, N->getChain(), N->getBasePtr(),
+                                 N->getSrcValue(), N->getSrcValueOffset(),
+                                 N->getMemoryVT(), N->isVolatile(),
+                                 N->getAlignment());
+
+  // Legalized the chain result - switch anything that used the old chain to
+  // use the new one.
+  ReplaceValueWith(SDOperand(N, 1), Res.getValue(1));
+  return Res;
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_BUILD_PAIR(SDNode *N) {
+  // The pair element type may be legal, or may not promote to the same type as
+  // the result, for example i14 = BUILD_PAIR (i7, i7).  Handle all cases.
+  return DAG.getNode(ISD::ANY_EXTEND,
+                     TLI.getTypeToTransformTo(N->getValueType(0)),
+                     JoinIntegers(N->getOperand(0), N->getOperand(1)));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) {
+  SDOperand InOp = N->getOperand(0);
+  MVT InVT = InOp.getValueType();
+  MVT NInVT = TLI.getTypeToTransformTo(InVT);
+  MVT OutVT = TLI.getTypeToTransformTo(N->getValueType(0));
+
+  switch (getTypeAction(InVT)) {
+  default:
+    assert(false && "Unknown type action!");
+    break;
+  case Legal:
+    break;
+  case PromoteInteger:
+    if (OutVT.getSizeInBits() == NInVT.getSizeInBits())
+      // The input promotes to the same size.  Convert the promoted value.
+      return DAG.getNode(ISD::BIT_CONVERT, OutVT, GetPromotedInteger(InOp));
+    break;
+  case PromoteFloat:
+    // Promote the integer operand by hand.
+    return DAG.getNode(ISD::ANY_EXTEND, OutVT, GetPromotedFloat(InOp));
+  case ExpandInteger:
+  case ExpandFloat:
+    break;
+  case Scalarize:
+    // Convert the element to an integer and promote it by hand.
+    return DAG.getNode(ISD::ANY_EXTEND, OutVT,
+                       BitConvertToInteger(GetScalarizedVector(InOp)));
+  case Split:
+    // For example, i32 = BIT_CONVERT v2i16 on alpha.  Convert the split
+    // pieces of the input into integers and reassemble in the final type.
+    SDOperand Lo, Hi;
+    GetSplitVector(N->getOperand(0), Lo, Hi);
+    Lo = BitConvertToInteger(Lo);
+    Hi = BitConvertToInteger(Hi);
+
+    if (TLI.isBigEndian())
+      std::swap(Lo, Hi);
+
+    InOp = DAG.getNode(ISD::ANY_EXTEND,
+                       MVT::getIntegerVT(OutVT.getSizeInBits()),
+                       JoinIntegers(Lo, Hi));
+    return DAG.getNode(ISD::BIT_CONVERT, OutVT, InOp);
+  }
+
+  // Otherwise, lower the bit-convert to a store/load from the stack, then
+  // promote the load.
+  SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
+  return PromoteIntRes_LOAD(cast<LoadSDNode>(Op.Val));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) {
+  // The input may have strange things in the top bits of the registers, but
+  // these operations don't care.  They may have weird bits going out, but
+  // that too is okay if they are integer operations.
+  SDOperand LHS = GetPromotedInteger(N->getOperand(0));
+  SDOperand RHS = GetPromotedInteger(N->getOperand(1));
+  return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SDIV(SDNode *N) {
+  // Sign extend the input.
+  SDOperand LHS = GetPromotedInteger(N->getOperand(0));
+  SDOperand RHS = GetPromotedInteger(N->getOperand(1));
+  MVT VT = N->getValueType(0);
+  LHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, LHS.getValueType(), LHS,
+                    DAG.getValueType(VT));
+  RHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, RHS.getValueType(), RHS,
+                    DAG.getValueType(VT));
+
+  return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) {
+  // Zero extend the input.
+  SDOperand LHS = GetPromotedInteger(N->getOperand(0));
+  SDOperand RHS = GetPromotedInteger(N->getOperand(1));
+  MVT VT = N->getValueType(0);
+  LHS = DAG.getZeroExtendInReg(LHS, VT);
+  RHS = DAG.getZeroExtendInReg(RHS, VT);
+
+  return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SHL(SDNode *N) {
+  return DAG.getNode(ISD::SHL, TLI.getTypeToTransformTo(N->getValueType(0)),
+                     GetPromotedInteger(N->getOperand(0)), N->getOperand(1));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) {
+  // The input value must be properly sign extended.
+  MVT VT = N->getValueType(0);
+  MVT NVT = TLI.getTypeToTransformTo(VT);
+  SDOperand Res = GetPromotedInteger(N->getOperand(0));
+  Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, DAG.getValueType(VT));
+  return DAG.getNode(ISD::SRA, NVT, Res, N->getOperand(1));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) {
+  // The input value must be properly zero extended.
+  MVT VT = N->getValueType(0);
+  MVT NVT = TLI.getTypeToTransformTo(VT);
+  SDOperand Res = ZExtPromotedInteger(N->getOperand(0));
+  return DAG.getNode(ISD::SRL, NVT, Res, N->getOperand(1));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SELECT(SDNode *N) {
+  SDOperand LHS = GetPromotedInteger(N->getOperand(1));
+  SDOperand RHS = GetPromotedInteger(N->getOperand(2));
+  return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) {
+  SDOperand LHS = GetPromotedInteger(N->getOperand(2));
+  SDOperand RHS = GetPromotedInteger(N->getOperand(3));
+  return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0),
+                     N->getOperand(1), LHS, RHS, N->getOperand(4));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) {
+  SDOperand Op = GetPromotedInteger(N->getOperand(0));
+  MVT OVT = N->getValueType(0);
+  MVT NVT = Op.getValueType();
+  // Zero extend to the promoted type and do the count there.
+  Op = DAG.getNode(ISD::CTLZ, NVT, DAG.getZeroExtendInReg(Op, OVT));
+  // Subtract off the extra leading bits in the bigger type.
+  return DAG.getNode(ISD::SUB, NVT, Op,
+                     DAG.getConstant(NVT.getSizeInBits() -
+                                     OVT.getSizeInBits(), NVT));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_CTPOP(SDNode *N) {
+  SDOperand Op = GetPromotedInteger(N->getOperand(0));
+  MVT OVT = N->getValueType(0);
+  MVT NVT = Op.getValueType();
+  // Zero extend to the promoted type and do the count there.
+  return DAG.getNode(ISD::CTPOP, NVT, DAG.getZeroExtendInReg(Op, OVT));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) {
+  SDOperand Op = GetPromotedInteger(N->getOperand(0));
+  MVT OVT = N->getValueType(0);
+  MVT NVT = Op.getValueType();
+  // The count is the same in the promoted type except if the original
+  // value was zero.  This can be handled by setting the bit just off
+  // the top of the original type.
+  Op = DAG.getNode(ISD::OR, NVT, Op,
+                   // FIXME: Do this using an APINT constant.
+                   DAG.getConstant(1UL << OVT.getSizeInBits(), NVT));
+  return DAG.getNode(ISD::CTTZ, NVT, Op);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) {
+  MVT OldVT = N->getValueType(0);
+  SDOperand OldVec = N->getOperand(0);
+  unsigned OldElts = OldVec.getValueType().getVectorNumElements();
+
+  if (OldElts == 1) {
+    assert(!isTypeLegal(OldVec.getValueType()) &&
+           "Legal one-element vector of a type needing promotion!");
+    // It is tempting to follow GetScalarizedVector by a call to
+    // GetPromotedInteger, but this would be wrong because the
+    // scalarized value may not yet have been processed.
+    return DAG.getNode(ISD::ANY_EXTEND, TLI.getTypeToTransformTo(OldVT),
+                       GetScalarizedVector(OldVec));
+  }
+
+  // Convert to a vector half as long with an element type of twice the width,
+  // for example <4 x i16> -> <2 x i32>.
+  assert(!(OldElts & 1) && "Odd length vectors not supported!");
+  MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits());
+  assert(OldVT.isSimple() && NewVT.isSimple());
+
+  SDOperand NewVec = DAG.getNode(ISD::BIT_CONVERT,
+                                 MVT::getVectorVT(NewVT, OldElts / 2),
+                                 OldVec);
+
+  // Extract the element at OldIdx / 2 from the new vector.
+  SDOperand OldIdx = N->getOperand(1);
+  SDOperand NewIdx = DAG.getNode(ISD::SRL, OldIdx.getValueType(), OldIdx,
+                                 DAG.getConstant(1, TLI.getShiftAmountTy()));
+  SDOperand Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, NewIdx);
+
+  // Select the appropriate half of the element: Lo if OldIdx was even,
+  // Hi if it was odd.
+  SDOperand Lo = Elt;
+  SDOperand Hi = DAG.getNode(ISD::SRL, NewVT, Elt,
+                             DAG.getConstant(OldVT.getSizeInBits(),
+                                             TLI.getShiftAmountTy()));
+  if (TLI.isBigEndian())
+    std::swap(Lo, Hi);
+
+  SDOperand Odd = DAG.getNode(ISD::AND, OldIdx.getValueType(), OldIdx,
+                              DAG.getConstant(1, TLI.getShiftAmountTy()));
+  return DAG.getNode(ISD::SELECT, NewVT, Odd, Hi, Lo);
+}
+
+//===----------------------------------------------------------------------===//
+//  Integer Operand Promotion
+//===----------------------------------------------------------------------===//
+
+/// PromoteIntegerOperand - This method is called when the specified operand of
+/// the specified node is found to need promotion.  At this point, all of the
+/// result types of the node are known to be legal, but other operands of the
+/// node may need promotion or expansion as well as the specified one.
+bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) {
+  DEBUG(cerr << "Promote integer operand: "; N->dump(&DAG); cerr << "\n");
+  SDOperand Res;
+  switch (N->getOpcode()) {
+    default:
+#ifndef NDEBUG
+    cerr << "PromoteIntegerOperand Op #" << OpNo << ": ";
+    N->dump(&DAG); cerr << "\n";
+#endif
+    assert(0 && "Do not know how to promote this operator's operand!");
+    abort();
+
+  case ISD::ANY_EXTEND:  Res = PromoteIntOp_ANY_EXTEND(N); break;
+  case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break;
+  case ISD::SIGN_EXTEND: Res = PromoteIntOp_SIGN_EXTEND(N); break;
+  case ISD::TRUNCATE:    Res = PromoteIntOp_TRUNCATE(N); break;
+  case ISD::FP_EXTEND:   Res = PromoteIntOp_FP_EXTEND(N); break;
+  case ISD::FP_ROUND:    Res = PromoteIntOp_FP_ROUND(N); break;
+  case ISD::SINT_TO_FP:
+  case ISD::UINT_TO_FP:  Res = PromoteIntOp_INT_TO_FP(N); break;
+  case ISD::BUILD_PAIR:  Res = PromoteIntOp_BUILD_PAIR(N); break;
+
+  case ISD::SELECT:      Res = PromoteIntOp_SELECT(N, OpNo); break;
+  case ISD::BRCOND:      Res = PromoteIntOp_BRCOND(N, OpNo); break;
+  case ISD::BR_CC:       Res = PromoteIntOp_BR_CC(N, OpNo); break;
+  case ISD::SETCC:       Res = PromoteIntOp_SETCC(N, OpNo); break;
+
+  case ISD::STORE:       Res = PromoteIntOp_STORE(cast<StoreSDNode>(N),
+                                                    OpNo); break;
+
+  case ISD::BUILD_VECTOR: Res = PromoteIntOp_BUILD_VECTOR(N); break;
+  case ISD::INSERT_VECTOR_ELT:
+    Res = PromoteIntOp_INSERT_VECTOR_ELT(N, OpNo);
+    break;
+
+  case ISD::MEMBARRIER:  Res = PromoteIntOp_MEMBARRIER(N); break;
+  }
+
+  // If the result is null, the sub-method took care of registering results etc.
+  if (!Res.Val) return false;
+  // If the result is N, the sub-method updated N in place.
+  if (Res.Val == N) {
+    // Mark N as new and remark N and its operands.  This allows us to correctly
+    // revisit N if it needs another step of promotion and allows us to visit
+    // any new operands to N.
+    ReanalyzeNode(N);
+    return true;
+  }
+
+  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
+         "Invalid operand expansion");
+
+  ReplaceValueWith(SDOperand(N, 0), Res);
+  return false;
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) {
+  SDOperand Op = GetPromotedInteger(N->getOperand(0));
+  return DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) {
+  SDOperand Op = GetPromotedInteger(N->getOperand(0));
+  Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
+  return DAG.getZeroExtendInReg(Op, N->getOperand(0).getValueType());
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_SIGN_EXTEND(SDNode *N) {
+  SDOperand Op = GetPromotedInteger(N->getOperand(0));
+  Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
+  return DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(),
+                     Op, DAG.getValueType(N->getOperand(0).getValueType()));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) {
+  SDOperand Op = GetPromotedInteger(N->getOperand(0));
+  return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), Op);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_FP_EXTEND(SDNode *N) {
+  SDOperand Op = GetPromotedInteger(N->getOperand(0));
+  return DAG.getNode(ISD::FP_EXTEND, N->getValueType(0), Op);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_FP_ROUND(SDNode *N) {
+  SDOperand Op = GetPromotedInteger(N->getOperand(0));
+  return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Op,
+                     DAG.getIntPtrConstant(0));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_INT_TO_FP(SDNode *N) {
+  SDOperand In = GetPromotedInteger(N->getOperand(0));
+  MVT OpVT = N->getOperand(0).getValueType();
+  if (N->getOpcode() == ISD::UINT_TO_FP)
+    In = DAG.getZeroExtendInReg(In, OpVT);
+  else
+    In = DAG.getNode(ISD::SIGN_EXTEND_INREG, In.getValueType(),
+                     In, DAG.getValueType(OpVT));
+
+  return DAG.UpdateNodeOperands(SDOperand(N, 0), In);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) {
+  // Since the result type is legal, the operands must promote to it.
+  MVT OVT = N->getOperand(0).getValueType();
+  SDOperand Lo = GetPromotedInteger(N->getOperand(0));
+  SDOperand Hi = GetPromotedInteger(N->getOperand(1));
+  assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?");
+
+  Lo = DAG.getZeroExtendInReg(Lo, OVT);
+  Hi = DAG.getNode(ISD::SHL, N->getValueType(0), Hi,
+                   DAG.getConstant(OVT.getSizeInBits(),
+                                   TLI.getShiftAmountTy()));
+  return DAG.getNode(ISD::OR, N->getValueType(0), Lo, Hi);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_SELECT(SDNode *N, unsigned OpNo) {
+  assert(OpNo == 0 && "Only know how to promote condition");
+  SDOperand Cond = GetPromotedInteger(N->getOperand(0));  // Promote condition.
+
+  // The top bits of the promoted condition are not necessarily zero, ensure
+  // that the value is properly zero extended.
+  unsigned BitWidth = Cond.getValueSizeInBits();
+  if (!DAG.MaskedValueIsZero(Cond,
+                             APInt::getHighBitsSet(BitWidth, BitWidth-1)))
+    Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
+
+  // The chain (Op#0) and basic block destination (Op#2) are always legal types.
+  return DAG.UpdateNodeOperands(SDOperand(N, 0), Cond, N->getOperand(1),
+                                N->getOperand(2));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo) {
+  assert(OpNo == 1 && "only know how to promote condition");
+  SDOperand Cond = GetPromotedInteger(N->getOperand(1));  // Promote condition.
+
+  // The top bits of the promoted condition are not necessarily zero, ensure
+  // that the value is properly zero extended.
+  unsigned BitWidth = Cond.getValueSizeInBits();
+  if (!DAG.MaskedValueIsZero(Cond,
+                             APInt::getHighBitsSet(BitWidth, BitWidth-1)))
+    Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
+
+  // The chain (Op#0) and basic block destination (Op#2) are always legal types.
+  return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0), Cond,
+                                N->getOperand(2));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) {
+  assert(OpNo == 2 && "Don't know how to promote this operand");
+
+  SDOperand LHS = N->getOperand(2);
+  SDOperand RHS = N->getOperand(3);
+  PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(1))->get());
+
+  // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always
+  // legal types.
+  return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
+                                N->getOperand(1), LHS, RHS, N->getOperand(4));
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_SETCC(SDNode *N, unsigned OpNo) {
+  assert(OpNo == 0 && "Don't know how to promote this operand");
+
+  SDOperand LHS = N->getOperand(0);
+  SDOperand RHS = N->getOperand(1);
+  PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(2))->get());
+
+  // The CC (#2) is always legal.
+  return DAG.UpdateNodeOperands(SDOperand(N, 0), LHS, RHS, N->getOperand(2));
+}
+
+/// PromoteSetCCOperands - Promote the operands of a comparison.  This code is
+/// shared among BR_CC, SELECT_CC, and SETCC handlers.
+void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS,
+                                            ISD::CondCode CCCode) {
+  MVT VT = NewLHS.getValueType();
+
+  // Get the promoted values.
+  NewLHS = GetPromotedInteger(NewLHS);
+  NewRHS = GetPromotedInteger(NewRHS);
+
+  // If this is an FP compare, the operands have already been extended.
+  if (!NewLHS.getValueType().isInteger())
+    return;
+
+  // 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 (CCCode) {
+  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.
+    NewLHS = DAG.getZeroExtendInReg(NewLHS, VT);
+    NewRHS = DAG.getZeroExtendInReg(NewRHS, VT);
+    return;
+  case ISD::SETGE:
+  case ISD::SETGT:
+  case ISD::SETLT:
+  case ISD::SETLE:
+    NewLHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewLHS.getValueType(), NewLHS,
+                         DAG.getValueType(VT));
+    NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS,
+                         DAG.getValueType(VT));
+    return;
+  }
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){
+  // FIXME: Add support for indexed stores.
+  SDOperand Ch = N->getChain(), Ptr = N->getBasePtr();
+  int SVOffset = N->getSrcValueOffset();
+  unsigned Alignment = N->getAlignment();
+  bool isVolatile = N->isVolatile();
+
+  SDOperand Val = GetPromotedInteger(N->getValue());  // Get promoted value.
+
+  assert(!N->isTruncatingStore() && "Cannot promote this store operand!");
+
+  // Truncate the value and store the result.
+  return DAG.getTruncStore(Ch, Val, Ptr, N->getSrcValue(),
+                           SVOffset, N->getMemoryVT(),
+                           isVolatile, Alignment);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) {
+  // The vector type is legal but the element type is not.  This implies
+  // that the vector is a power-of-two in length and that the element
+  // type does not have a strange size (eg: it is not i1).
+  MVT VecVT = N->getValueType(0);
+  unsigned NumElts = VecVT.getVectorNumElements();
+  assert(!(NumElts & 1) && "Legal vector of one illegal element?");
+
+  // Build a vector of half the length out of elements of twice the bitwidth.
+  // For example <4 x i16> -> <2 x i32>.
+  MVT OldVT = N->getOperand(0).getValueType();
+  MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits());
+  assert(OldVT.isSimple() && NewVT.isSimple());
+
+  std::vector<SDOperand> NewElts;
+  NewElts.reserve(NumElts/2);
+
+  for (unsigned i = 0; i < NumElts; i += 2) {
+    // Combine two successive elements into one promoted element.
+    SDOperand Lo = N->getOperand(i);
+    SDOperand Hi = N->getOperand(i+1);
+    if (TLI.isBigEndian())
+      std::swap(Lo, Hi);
+    NewElts.push_back(JoinIntegers(Lo, Hi));
+  }
+
+  SDOperand NewVec = DAG.getNode(ISD::BUILD_VECTOR,
+                                 MVT::getVectorVT(NewVT, NewElts.size()),
+                                 &NewElts[0], NewElts.size());
+
+  // Convert the new vector to the old vector type.
+  return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N,
+                                                             unsigned OpNo) {
+  if (OpNo == 1) {
+    // Promote the inserted value.  This is valid because the type does not
+    // have to match the vector element type.
+
+    // Check that any extra bits introduced will be truncated away.
+    assert(N->getOperand(1).getValueType().getSizeInBits() >=
+           N->getValueType(0).getVectorElementType().getSizeInBits() &&
+           "Type of inserted value narrower than vector element type!");
+    return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
+                                  GetPromotedInteger(N->getOperand(1)),
+                                  N->getOperand(2));
+  }
+
+  assert(OpNo == 2 && "Different operand and result vector types?");
+
+  // Promote the index.
+  SDOperand Idx = N->getOperand(2);
+  Idx = DAG.getZeroExtendInReg(GetPromotedInteger(Idx), Idx.getValueType());
+  return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
+                                N->getOperand(1), Idx);
+}
+
+SDOperand DAGTypeLegalizer::PromoteIntOp_MEMBARRIER(SDNode *N) {
+  SDOperand NewOps[6];
+  NewOps[0] = N->getOperand(0);
+  for (unsigned i = 1; i < array_lengthof(NewOps); ++i) {
+    SDOperand Flag = GetPromotedInteger(N->getOperand(i));
+    NewOps[i] = DAG.getZeroExtendInReg(Flag, MVT::i1);
+  }
+  return DAG.UpdateNodeOperands(SDOperand (N, 0), NewOps,
+                                array_lengthof(NewOps));
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Integer Result Expansion
+//===----------------------------------------------------------------------===//
+
+/// ExpandIntegerResult - This method is called when the specified result of the
+/// specified node is found to need expansion.  At this point, the node may also
+/// have invalid operands or may have other results that need promotion, we just
+/// know that (at least) one result needs expansion.
+void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) {
+  DEBUG(cerr << "Expand integer result: "; N->dump(&DAG); cerr << "\n");
+  SDOperand Lo, Hi;
+  Lo = Hi = SDOperand();
+
+  // See if the target wants to custom expand this node.
+  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
+          TargetLowering::Custom) {
+    // If the target wants to, allow it to lower this itself.
+    if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
+      // Everything that once used N now uses P.  We are guaranteed that the
+      // result value types of N and the result value types of P match.
+      ReplaceNodeWith(N, P);
+      return;
+    }
+  }
+
+  switch (N->getOpcode()) {
+  default:
+#ifndef NDEBUG
+    cerr << "ExpandIntegerResult #" << ResNo << ": ";
+    N->dump(&DAG); cerr << "\n";
+#endif
+    assert(0&&"Do not know how to expand the result of this operator!");
+    abort();
+
+  case ISD::UNDEF:       ExpandIntRes_UNDEF(N, Lo, Hi); break;
+  case ISD::Constant:    ExpandIntRes_Constant(N, Lo, Hi); break;
+  case ISD::BUILD_PAIR:  ExpandIntRes_BUILD_PAIR(N, Lo, Hi); break;
+  case ISD::MERGE_VALUES: ExpandIntRes_MERGE_VALUES(N, Lo, Hi); break;
+  case ISD::ANY_EXTEND:  ExpandIntRes_ANY_EXTEND(N, Lo, Hi); break;
+  case ISD::ZERO_EXTEND: ExpandIntRes_ZERO_EXTEND(N, Lo, Hi); break;
+  case ISD::SIGN_EXTEND: ExpandIntRes_SIGN_EXTEND(N, Lo, Hi); break;
+  case ISD::AssertZext:  ExpandIntRes_AssertZext(N, Lo, Hi); break;
+  case ISD::TRUNCATE:    ExpandIntRes_TRUNCATE(N, Lo, Hi); break;
+  case ISD::BIT_CONVERT: ExpandIntRes_BIT_CONVERT(N, Lo, Hi); break;
+  case ISD::SIGN_EXTEND_INREG: ExpandIntRes_SIGN_EXTEND_INREG(N, Lo, Hi); break;
+  case ISD::FP_TO_SINT:  ExpandIntRes_FP_TO_SINT(N, Lo, Hi); break;
+  case ISD::FP_TO_UINT:  ExpandIntRes_FP_TO_UINT(N, Lo, Hi); break;
+  case ISD::LOAD:        ExpandIntRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
+
+  case ISD::AND:
+  case ISD::OR:
+  case ISD::XOR:         ExpandIntRes_Logical(N, Lo, Hi); break;
+  case ISD::BSWAP:       ExpandIntRes_BSWAP(N, Lo, Hi); break;
+  case ISD::ADD:
+  case ISD::SUB:         ExpandIntRes_ADDSUB(N, Lo, Hi); break;
+  case ISD::ADDC:
+  case ISD::SUBC:        ExpandIntRes_ADDSUBC(N, Lo, Hi); break;
+  case ISD::ADDE:
+  case ISD::SUBE:        ExpandIntRes_ADDSUBE(N, Lo, Hi); break;
+  case ISD::SELECT:      ExpandIntRes_SELECT(N, Lo, Hi); break;
+  case ISD::SELECT_CC:   ExpandIntRes_SELECT_CC(N, Lo, Hi); break;
+  case ISD::MUL:         ExpandIntRes_MUL(N, Lo, Hi); break;
+  case ISD::SDIV:        ExpandIntRes_SDIV(N, Lo, Hi); break;
+  case ISD::SREM:        ExpandIntRes_SREM(N, Lo, Hi); break;
+  case ISD::UDIV:        ExpandIntRes_UDIV(N, Lo, Hi); break;
+  case ISD::UREM:        ExpandIntRes_UREM(N, Lo, Hi); break;
+  case ISD::SHL:
+  case ISD::SRA:
+  case ISD::SRL:         ExpandIntRes_Shift(N, Lo, Hi); break;
+
+  case ISD::CTLZ:        ExpandIntRes_CTLZ(N, Lo, Hi); break;
+  case ISD::CTPOP:       ExpandIntRes_CTPOP(N, Lo, Hi); break;
+  case ISD::CTTZ:        ExpandIntRes_CTTZ(N, Lo, Hi); break;
+
+  case ISD::EXTRACT_VECTOR_ELT:
+    ExpandIntRes_EXTRACT_VECTOR_ELT(N, Lo, Hi);
+    break;
+  }
+
+  // If Lo/Hi is null, the sub-method took care of registering results etc.
+  if (Lo.Val)
+    SetExpandedInteger(SDOperand(N, ResNo), Lo, Hi);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_UNDEF(SDNode *N,
+                                          SDOperand &Lo, SDOperand &Hi) {
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  Lo = Hi = DAG.getNode(ISD::UNDEF, NVT);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N,
+                                             SDOperand &Lo, SDOperand &Hi) {
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  unsigned NBitWidth = NVT.getSizeInBits();
+  const APInt &Cst = cast<ConstantSDNode>(N)->getAPIntValue();
+  Lo = DAG.getConstant(APInt(Cst).trunc(NBitWidth), NVT);
+  Hi = DAG.getConstant(Cst.lshr(NBitWidth).trunc(NBitWidth), NVT);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_BUILD_PAIR(SDNode *N,
+                                               SDOperand &Lo, SDOperand &Hi) {
+  // Return the operands.
+  Lo = N->getOperand(0);
+  Hi = N->getOperand(1);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_MERGE_VALUES(SDNode *N,
+                                                 SDOperand &Lo, SDOperand &Hi) {
+  // A MERGE_VALUES node can produce any number of values.  We know that the
+  // first illegal one needs to be expanded into Lo/Hi.
+  unsigned i;
+
+  // The string of legal results gets turns into the input operands, which have
+  // the same type.
+  for (i = 0; isTypeLegal(N->getValueType(i)); ++i)
+    ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i)));
+
+  // The first illegal result must be the one that needs to be expanded.
+  GetExpandedInteger(N->getOperand(i), Lo, Hi);
+
+  // Legalize the rest of the results into the input operands whether they are
+  // legal or not.
+  unsigned e = N->getNumValues();
+  for (++i; i != e; ++i)
+    ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i)));
+}
+
+void DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N,
+                                               SDOperand &Lo, SDOperand &Hi) {
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  SDOperand Op = N->getOperand(0);
+  if (Op.getValueType().bitsLE(NVT)) {
+    // The low part is any extension of the input (which degenerates to a copy).
+    Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, Op);
+    Hi = DAG.getNode(ISD::UNDEF, NVT);   // The high part is undefined.
+  } else {
+    // For example, extension of an i48 to an i64.  The operand type necessarily
+    // promotes to the result type, so will end up being expanded too.
+    assert(getTypeAction(Op.getValueType()) == PromoteInteger &&
+           "Only know how to promote this result!");
+    SDOperand Res = GetPromotedInteger(Op);
+    assert(Res.getValueType() == N->getValueType(0) &&
+           "Operand over promoted?");
+    // Split the promoted operand.  This will simplify when it is expanded.
+    SplitInteger(Res, Lo, Hi);
+  }
+}
+
+void DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N,
+                                                SDOperand &Lo, SDOperand &Hi) {
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  SDOperand Op = N->getOperand(0);
+  if (Op.getValueType().bitsLE(NVT)) {
+    // The low part is zero extension of the input (which degenerates to a copy).
+    Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, N->getOperand(0));
+    Hi = DAG.getConstant(0, NVT);   // The high part is just a zero.
+  } else {
+    // For example, extension of an i48 to an i64.  The operand type necessarily
+    // promotes to the result type, so will end up being expanded too.
+    assert(getTypeAction(Op.getValueType()) == PromoteInteger &&
+           "Only know how to promote this result!");
+    SDOperand Res = GetPromotedInteger(Op);
+    assert(Res.getValueType() == N->getValueType(0) &&
+           "Operand over promoted?");
+    // Split the promoted operand.  This will simplify when it is expanded.
+    SplitInteger(Res, Lo, Hi);
+    unsigned ExcessBits =
+      Op.getValueType().getSizeInBits() - NVT.getSizeInBits();
+    Hi = DAG.getZeroExtendInReg(Hi, MVT::getIntegerVT(ExcessBits));
+  }
+}
+
+void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N,
+                                                SDOperand &Lo, SDOperand &Hi) {
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  SDOperand Op = N->getOperand(0);
+  if (Op.getValueType().bitsLE(NVT)) {
+    // The low part is sign extension of the input (which degenerates to a copy).
+    Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, N->getOperand(0));
+    // The high part is obtained by SRA'ing all but one of the bits of low part.
+    unsigned LoSize = NVT.getSizeInBits();
+    Hi = DAG.getNode(ISD::SRA, NVT, Lo,
+                     DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
+  } else {
+    // For example, extension of an i48 to an i64.  The operand type necessarily
+    // promotes to the result type, so will end up being expanded too.
+    assert(getTypeAction(Op.getValueType()) == PromoteInteger &&
+           "Only know how to promote this result!");
+    SDOperand Res = GetPromotedInteger(Op);
+    assert(Res.getValueType() == N->getValueType(0) &&
+           "Operand over promoted?");
+    // Split the promoted operand.  This will simplify when it is expanded.
+    SplitInteger(Res, Lo, Hi);
+    unsigned ExcessBits =
+      Op.getValueType().getSizeInBits() - NVT.getSizeInBits();
+    Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi,
+                     DAG.getValueType(MVT::getIntegerVT(ExcessBits)));
+  }
+}
+
+void DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N,
+                                               SDOperand &Lo, SDOperand &Hi) {
+  GetExpandedInteger(N->getOperand(0), Lo, Hi);
+  MVT NVT = Lo.getValueType();
+  MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
+  unsigned NVTBits = NVT.getSizeInBits();
+  unsigned EVTBits = EVT.getSizeInBits();
+
+  if (NVTBits < EVTBits) {
+    Hi = DAG.getNode(ISD::AssertZext, NVT, Hi,
+                     DAG.getValueType(MVT::getIntegerVT(EVTBits - NVTBits)));
+  } else {
+    Lo = DAG.getNode(ISD::AssertZext, NVT, Lo, DAG.getValueType(EVT));
+    // The high part must be zero, make it explicit.
+    Hi = DAG.getConstant(0, NVT);
+  }
+}
+
+void DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N,
+                                             SDOperand &Lo, SDOperand &Hi) {
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  Lo = DAG.getNode(ISD::TRUNCATE, NVT, N->getOperand(0));
+  Hi = DAG.getNode(ISD::SRL, N->getOperand(0).getValueType(), N->getOperand(0),
+                   DAG.getConstant(NVT.getSizeInBits(),
+                                   TLI.getShiftAmountTy()));
+  Hi = DAG.getNode(ISD::TRUNCATE, NVT, Hi);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_BIT_CONVERT(SDNode *N,
+                                                SDOperand &Lo, SDOperand &Hi) {
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  SDOperand InOp = N->getOperand(0);
+  MVT InVT = InOp.getValueType();
+
+  // Handle some special cases efficiently.
+  switch (getTypeAction(InVT)) {
+    default:
+      assert(false && "Unknown type action!");
+    case Legal:
+    case PromoteInteger:
+      break;
+    case PromoteFloat:
+      // Convert the integer operand instead.
+      SplitInteger(GetPromotedFloat(InOp), Lo, Hi);
+      Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
+      Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
+      return;
+    case ExpandInteger:
+      // Convert the expanded pieces of the input.
+      GetExpandedInteger(InOp, Lo, Hi);
+      Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
+      Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
+      return;
+    case ExpandFloat:
+      // Convert the expanded pieces of the input.
+      GetExpandedFloat(InOp, Lo, Hi);
+      Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
+      Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
+      return;
+    case Split:
+      // Convert the split parts of the input if it was split in two.
+      GetSplitVector(InOp, Lo, Hi);
+      if (Lo.getValueType() == Hi.getValueType()) {
+        if (TLI.isBigEndian())
+          std::swap(Lo, Hi);
+        Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
+        Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
+        return;
+      }
+      break;
+    case Scalarize:
+      // Convert the element instead.
+      SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)), Lo, Hi);
+      Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
+      Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
+      return;
+  }
+
+  // Lower the bit-convert to a store/load from the stack, then expand the load.
+  SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
+  ExpandIntRes_LOAD(cast<LoadSDNode>(Op.Val), Lo, Hi);
+}
+
+void DAGTypeLegalizer::
+ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+  GetExpandedInteger(N->getOperand(0), Lo, Hi);
+  MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
+
+  if (EVT.bitsLE(Lo.getValueType())) {
+    // sext_inreg the low part if needed.
+    Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, Lo.getValueType(), Lo,
+                     N->getOperand(1));
+
+    // The high part gets the sign extension from the lo-part.  This handles
+    // things like sextinreg V:i64 from i8.
+    Hi = DAG.getNode(ISD::SRA, Hi.getValueType(), Lo,
+                     DAG.getConstant(Hi.getValueType().getSizeInBits()-1,
+                                     TLI.getShiftAmountTy()));
+  } else {
+    // For example, extension of an i48 to an i64.  Leave the low part alone,
+    // sext_inreg the high part.
+    unsigned ExcessBits =
+      EVT.getSizeInBits() - Lo.getValueType().getSizeInBits();
+    Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi,
+                     DAG.getValueType(MVT::getIntegerVT(ExcessBits)));
+  }
+}
+
+void DAGTypeLegalizer::ExpandIntRes_FP_TO_SINT(SDNode *N, SDOperand &Lo,
+                                               SDOperand &Hi) {
+  MVT VT = N->getValueType(0);
+  SDOperand Op = N->getOperand(0);
+  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
+  if (VT == MVT::i64) {
+    if (Op.getValueType() == MVT::f32)
+      LC = RTLIB::FPTOSINT_F32_I64;
+    else if (Op.getValueType() == MVT::f64)
+      LC = RTLIB::FPTOSINT_F64_I64;
+    else if (Op.getValueType() == MVT::f80)
+      LC = RTLIB::FPTOSINT_F80_I64;
+    else if (Op.getValueType() == MVT::ppcf128)
+      LC = RTLIB::FPTOSINT_PPCF128_I64;
+  } else if (VT == MVT::i128) {
+    if (Op.getValueType() == MVT::f32)
+      LC = RTLIB::FPTOSINT_F32_I128;
+    else if (Op.getValueType() == MVT::f64)
+      LC = RTLIB::FPTOSINT_F64_I128;
+    else if (Op.getValueType() == MVT::f80)
+      LC = RTLIB::FPTOSINT_F80_I128;
+    else if (Op.getValueType() == MVT::ppcf128)
+      LC = RTLIB::FPTOSINT_PPCF128_I128;
+  } else {
+    assert(0 && "Unexpected fp-to-sint conversion!");
+  }
+  SplitInteger(MakeLibCall(LC, VT, &Op, 1, true/*sign irrelevant*/), Lo, Hi);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDOperand &Lo,
+                                               SDOperand &Hi) {
+  MVT VT = N->getValueType(0);
+  SDOperand Op = N->getOperand(0);
+  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
+  if (VT == MVT::i64) {
+    if (Op.getValueType() == MVT::f32)
+      LC = RTLIB::FPTOUINT_F32_I64;
+    else if (Op.getValueType() == MVT::f64)
+      LC = RTLIB::FPTOUINT_F64_I64;
+    else if (Op.getValueType() == MVT::f80)
+      LC = RTLIB::FPTOUINT_F80_I64;
+    else if (Op.getValueType() == MVT::ppcf128)
+      LC = RTLIB::FPTOUINT_PPCF128_I64;
+  } else if (VT == MVT::i128) {
+    if (Op.getValueType() == MVT::f32)
+      LC = RTLIB::FPTOUINT_F32_I128;
+    else if (Op.getValueType() == MVT::f64)
+      LC = RTLIB::FPTOUINT_F64_I128;
+    else if (Op.getValueType() == MVT::f80)
+      LC = RTLIB::FPTOUINT_F80_I128;
+    else if (Op.getValueType() == MVT::ppcf128)
+      LC = RTLIB::FPTOUINT_PPCF128_I128;
+  } else {
+    assert(0 && "Unexpected fp-to-uint conversion!");
+  }
+  SplitInteger(MakeLibCall(LC, VT, &Op, 1, false/*sign irrelevant*/), Lo, Hi);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
+                                         SDOperand &Lo, SDOperand &Hi) {
+  // FIXME: Add support for indexed loads.
+  MVT VT = N->getValueType(0);
+  MVT NVT = TLI.getTypeToTransformTo(VT);
+  SDOperand Ch  = N->getChain();    // Legalize the chain.
+  SDOperand Ptr = N->getBasePtr();  // Legalize the pointer.
+  ISD::LoadExtType ExtType = N->getExtensionType();
+  int SVOffset = N->getSrcValueOffset();
+  unsigned Alignment = N->getAlignment();
+  bool isVolatile = N->isVolatile();
+
+  assert(!(NVT.getSizeInBits() & 7) && "Expanded type not byte sized!");
+
+  if (ExtType == ISD::NON_EXTLOAD) {
+    Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
+                     isVolatile, Alignment);
+    // Increment the pointer to the other half.
+    unsigned IncrementSize = NVT.getSizeInBits()/8;
+    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                      DAG.getIntPtrConstant(IncrementSize));
+    Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
+                     isVolatile, MinAlign(Alignment, IncrementSize));
+
+    // Build a factor node to remember that this load is independent of the
+    // other one.
+    Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+                     Hi.getValue(1));
+
+    // Handle endianness of the load.
+    if (TLI.isBigEndian())
+      std::swap(Lo, Hi);
+  } else if (N->getMemoryVT().bitsLE(NVT)) {
+    MVT EVT = N->getMemoryVT();
+
+    Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, EVT,
+                        isVolatile, Alignment);
+
+    // Remember the chain.
+    Ch = Lo.getValue(1);
+
+    if (ExtType == ISD::SEXTLOAD) {
+      // The high part is obtained by SRA'ing all but one of the bits of the
+      // lo part.
+      unsigned LoSize = Lo.getValueType().getSizeInBits();
+      Hi = DAG.getNode(ISD::SRA, NVT, Lo,
+                       DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
+    } else if (ExtType == ISD::ZEXTLOAD) {
+      // The high part is just a zero.
+      Hi = DAG.getConstant(0, NVT);
+    } else {
+      assert(ExtType == ISD::EXTLOAD && "Unknown extload!");
+      // The high part is undefined.
+      Hi = DAG.getNode(ISD::UNDEF, NVT);
+    }
+  } else if (TLI.isLittleEndian()) {
+    // Little-endian - low bits are at low addresses.
+    Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
+                     isVolatile, Alignment);
+
+    unsigned ExcessBits =
+      N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
+    MVT NEVT = MVT::getIntegerVT(ExcessBits);
+
+    // Increment the pointer to the other half.
+    unsigned IncrementSize = NVT.getSizeInBits()/8;
+    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                      DAG.getIntPtrConstant(IncrementSize));
+    Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(),
+                        SVOffset+IncrementSize, NEVT,
+                        isVolatile, MinAlign(Alignment, IncrementSize));
+
+    // Build a factor node to remember that this load is independent of the
+    // other one.
+    Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+                     Hi.getValue(1));
+  } else {
+    // Big-endian - high bits are at low addresses.  Favor aligned loads at
+    // the cost of some bit-fiddling.
+    MVT EVT = N->getMemoryVT();
+    unsigned EBytes = EVT.getStoreSizeInBits()/8;
+    unsigned IncrementSize = NVT.getSizeInBits()/8;
+    unsigned ExcessBits = (EBytes - IncrementSize)*8;
+
+    // Load both the high bits and maybe some of the low bits.
+    Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
+                        MVT::getIntegerVT(EVT.getSizeInBits() - ExcessBits),
+                        isVolatile, Alignment);
+
+    // Increment the pointer to the other half.
+    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                      DAG.getIntPtrConstant(IncrementSize));
+    // Load the rest of the low bits.
+    Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Ch, Ptr, N->getSrcValue(),
+                        SVOffset+IncrementSize,
+                        MVT::getIntegerVT(ExcessBits),
+                        isVolatile, MinAlign(Alignment, IncrementSize));
+
+    // Build a factor node to remember that this load is independent of the
+    // other one.
+    Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
+                     Hi.getValue(1));
+
+    if (ExcessBits < NVT.getSizeInBits()) {
+      // Transfer low bits from the bottom of Hi to the top of Lo.
+      Lo = DAG.getNode(ISD::OR, NVT, Lo,
+                       DAG.getNode(ISD::SHL, NVT, Hi,
+                                   DAG.getConstant(ExcessBits,
+                                                   TLI.getShiftAmountTy())));
+      // Move high bits to the right position in Hi.
+      Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, NVT, Hi,
+                       DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
+                                       TLI.getShiftAmountTy()));
+    }
+  }
+
+  // Legalized the chain result - switch anything that used the old chain to
+  // use the new one.
+  ReplaceValueWith(SDOperand(N, 1), Ch);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_Logical(SDNode *N,
+                                            SDOperand &Lo, SDOperand &Hi) {
+  SDOperand LL, LH, RL, RH;
+  GetExpandedInteger(N->getOperand(0), LL, LH);
+  GetExpandedInteger(N->getOperand(1), RL, RH);
+  Lo = DAG.getNode(N->getOpcode(), LL.getValueType(), LL, RL);
+  Hi = DAG.getNode(N->getOpcode(), LL.getValueType(), LH, RH);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_BSWAP(SDNode *N,
+                                          SDOperand &Lo, SDOperand &Hi) {
+  GetExpandedInteger(N->getOperand(0), Hi, Lo);  // Note swapped operands.
+  Lo = DAG.getNode(ISD::BSWAP, Lo.getValueType(), Lo);
+  Hi = DAG.getNode(ISD::BSWAP, Hi.getValueType(), Hi);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_SELECT(SDNode *N,
+                                           SDOperand &Lo, SDOperand &Hi) {
+  SDOperand LL, LH, RL, RH;
+  GetExpandedInteger(N->getOperand(1), LL, LH);
+  GetExpandedInteger(N->getOperand(2), RL, RH);
+  Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LL, RL);
+  Hi = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LH, RH);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_SELECT_CC(SDNode *N,
+                                              SDOperand &Lo, SDOperand &Hi) {
+  SDOperand LL, LH, RL, RH;
+  GetExpandedInteger(N->getOperand(2), LL, LH);
+  GetExpandedInteger(N->getOperand(3), RL, RH);
+  Lo = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0),
+                   N->getOperand(1), LL, RL, N->getOperand(4));
+  Hi = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0),
+                   N->getOperand(1), LH, RH, N->getOperand(4));
+}
+
+void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N,
+                                           SDOperand &Lo, SDOperand &Hi) {
+  // Expand the subcomponents.
+  SDOperand LHSL, LHSH, RHSL, RHSH;
+  GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
+  GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
+  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
+  SDOperand LoOps[2] = { LHSL, RHSL };
+  SDOperand HiOps[3] = { LHSH, RHSH };
+
+  if (N->getOpcode() == ISD::ADD) {
+    Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
+    HiOps[2] = Lo.getValue(1);
+    Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3);
+  } else {
+    Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2);
+    HiOps[2] = Lo.getValue(1);
+    Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3);
+  }
+}
+
+void DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N,
+                                            SDOperand &Lo, SDOperand &Hi) {
+  // Expand the subcomponents.
+  SDOperand LHSL, LHSH, RHSL, RHSH;
+  GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
+  GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
+  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
+  SDOperand LoOps[2] = { LHSL, RHSL };
+  SDOperand HiOps[3] = { LHSH, RHSH };
+
+  if (N->getOpcode() == ISD::ADDC) {
+    Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
+    HiOps[2] = Lo.getValue(1);
+    Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3);
+  } else {
+    Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2);
+    HiOps[2] = Lo.getValue(1);
+    Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3);
+  }
+
+  // Legalized the flag result - switch anything that used the old flag to
+  // use the new one.
+  ReplaceValueWith(SDOperand(N, 1), Hi.getValue(1));
+}
+
+void DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N,
+                                            SDOperand &Lo, SDOperand &Hi) {
+  // Expand the subcomponents.
+  SDOperand LHSL, LHSH, RHSL, RHSH;
+  GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
+  GetExpandedInteger(N->getOperand(1), RHSL, RHSH);
+  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
+  SDOperand LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
+  SDOperand HiOps[3] = { LHSH, RHSH };
+
+  Lo = DAG.getNode(N->getOpcode(), VTList, LoOps, 3);
+  HiOps[2] = Lo.getValue(1);
+  Hi = DAG.getNode(N->getOpcode(), VTList, HiOps, 3);
+
+  // Legalized the flag result - switch anything that used the old flag to
+  // use the new one.
+  ReplaceValueWith(SDOperand(N, 1), Hi.getValue(1));
+}
+
+void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
+                                        SDOperand &Lo, SDOperand &Hi) {
+  MVT VT = N->getValueType(0);
+  MVT NVT = TLI.getTypeToTransformTo(VT);
+
+  bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, NVT);
+  bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, NVT);
+  bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, NVT);
+  bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, NVT);
+  if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) {
+    SDOperand LL, LH, RL, RH;
+    GetExpandedInteger(N->getOperand(0), LL, LH);
+    GetExpandedInteger(N->getOperand(1), RL, RH);
+    unsigned OuterBitSize = VT.getSizeInBits();
+    unsigned BitSize = NVT.getSizeInBits();
+    unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
+    unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
+
+    if (DAG.MaskedValueIsZero(N->getOperand(0),
+                              APInt::getHighBitsSet(OuterBitSize, LHSSB)) &&
+        DAG.MaskedValueIsZero(N->getOperand(1),
+                              APInt::getHighBitsSet(OuterBitSize, RHSSB))) {
+      // The inputs are both zero-extended.
+      if (HasUMUL_LOHI) {
+        // We can emit a umul_lohi.
+        Lo = DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL);
+        Hi = SDOperand(Lo.Val, 1);
+        return;
+      }
+      if (HasMULHU) {
+        // We can emit a mulhu+mul.
+        Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
+        Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL);
+        return;
+      }
+    }
+    if (LHSSB > BitSize && RHSSB > BitSize) {
+      // The input values are both sign-extended.
+      if (HasSMUL_LOHI) {
+        // We can emit a smul_lohi.
+        Lo = DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL);
+        Hi = SDOperand(Lo.Val, 1);
+        return;
+      }
+      if (HasMULHS) {
+        // We can emit a mulhs+mul.
+        Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
+        Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL);
+        return;
+      }
+    }
+    if (HasUMUL_LOHI) {
+      // Lo,Hi = umul LHS, RHS.
+      SDOperand UMulLOHI = DAG.getNode(ISD::UMUL_LOHI,
+                                       DAG.getVTList(NVT, NVT), LL, RL);
+      Lo = UMulLOHI;
+      Hi = UMulLOHI.getValue(1);
+      RH = DAG.getNode(ISD::MUL, NVT, LL, RH);
+      LH = DAG.getNode(ISD::MUL, NVT, LH, RL);
+      Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH);
+      Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
+      return;
+    }
+  }
+
+  // If nothing else, we can make a libcall.
+  SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
+  SplitInteger(MakeLibCall(RTLIB::MUL_I64, VT, Ops, 2, true/*sign irrelevant*/),
+               Lo, Hi);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
+                                         SDOperand &Lo, SDOperand &Hi) {
+  assert(N->getValueType(0) == MVT::i64 && "Unsupported sdiv!");
+  SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
+  SplitInteger(MakeLibCall(RTLIB::SDIV_I64, N->getValueType(0), Ops, 2, true),
+               Lo, Hi);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N,
+                                         SDOperand &Lo, SDOperand &Hi) {
+  assert(N->getValueType(0) == MVT::i64 && "Unsupported srem!");
+  SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
+  SplitInteger(MakeLibCall(RTLIB::SREM_I64, N->getValueType(0), Ops, 2, true),
+               Lo, Hi);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N,
+                                         SDOperand &Lo, SDOperand &Hi) {
+  assert(N->getValueType(0) == MVT::i64 && "Unsupported udiv!");
+  SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
+  SplitInteger(MakeLibCall(RTLIB::UDIV_I64, N->getValueType(0), Ops, 2, false),
+               Lo, Hi);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N,
+                                         SDOperand &Lo, SDOperand &Hi) {
+  assert(N->getValueType(0) == MVT::i64 && "Unsupported urem!");
+  SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
+  SplitInteger(MakeLibCall(RTLIB::UREM_I64, N->getValueType(0), Ops, 2, false),
+               Lo, Hi);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,
+                                          SDOperand &Lo, SDOperand &Hi) {
+  MVT VT = N->getValueType(0);
+
+  // If we can emit an efficient shift operation, do so now.  Check to see if
+  // the RHS is a constant.
+  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
+    return ExpandShiftByConstant(N, CN->getValue(), Lo, Hi);
+
+  // If we can determine that the high bit of the shift is zero or one, even if
+  // the low bits are variable, emit this shift in an optimized form.
+  if (ExpandShiftWithKnownAmountBit(N, Lo, Hi))
+    return;
+
+  // If this target supports shift_PARTS, use it.  First, map to the _PARTS opc.
+  unsigned PartsOpc;
+  if (N->getOpcode() == ISD::SHL) {
+    PartsOpc = ISD::SHL_PARTS;
+  } else if (N->getOpcode() == ISD::SRL) {
+    PartsOpc = ISD::SRL_PARTS;
+  } else {
+    assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
+    PartsOpc = ISD::SRA_PARTS;
+  }
+
+  // Next check to see if the target supports this SHL_PARTS operation or if it
+  // will custom expand it.
+  MVT NVT = TLI.getTypeToTransformTo(VT);
+  TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT);
+  if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
+      Action == TargetLowering::Custom) {
+    // Expand the subcomponents.
+    SDOperand LHSL, LHSH;
+    GetExpandedInteger(N->getOperand(0), LHSL, LHSH);
+
+    SDOperand Ops[] = { LHSL, LHSH, N->getOperand(1) };
+    MVT VT = LHSL.getValueType();
+    Lo = DAG.getNode(PartsOpc, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3);
+    Hi = Lo.getValue(1);
+    return;
+  }
+
+  // Otherwise, emit a libcall.
+  assert(VT == MVT::i64 && "Unsupported shift!");
+
+  RTLIB::Libcall LC;
+  bool isSigned;
+  if (N->getOpcode() == ISD::SHL) {
+    LC = RTLIB::SHL_I64;
+    isSigned = false; /*sign irrelevant*/
+  } else if (N->getOpcode() == ISD::SRL) {
+    LC = RTLIB::SRL_I64;
+    isSigned = false;
+  } else {
+    assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
+    LC = RTLIB::SRA_I64;
+    isSigned = true;
+  }
+
+  SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
+  SplitInteger(MakeLibCall(LC, VT, Ops, 2, isSigned), Lo, Hi);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_CTLZ(SDNode *N,
+                                         SDOperand &Lo, SDOperand &Hi) {
+  // ctlz (HiLo) -> Hi != 0 ? ctlz(Hi) : (ctlz(Lo)+32)
+  GetExpandedInteger(N->getOperand(0), Lo, Hi);
+  MVT NVT = Lo.getValueType();
+
+  SDOperand HiNotZero = DAG.getSetCC(TLI.getSetCCResultType(Hi), Hi,
+                                     DAG.getConstant(0, NVT), ISD::SETNE);
+
+  SDOperand LoLZ = DAG.getNode(ISD::CTLZ, NVT, Lo);
+  SDOperand HiLZ = DAG.getNode(ISD::CTLZ, NVT, Hi);
+
+  Lo = DAG.getNode(ISD::SELECT, NVT, HiNotZero, HiLZ,
+                   DAG.getNode(ISD::ADD, NVT, LoLZ,
+                               DAG.getConstant(NVT.getSizeInBits(), NVT)));
+  Hi = DAG.getConstant(0, NVT);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_CTPOP(SDNode *N,
+                                          SDOperand &Lo, SDOperand &Hi) {
+  // ctpop(HiLo) -> ctpop(Hi)+ctpop(Lo)
+  GetExpandedInteger(N->getOperand(0), Lo, Hi);
+  MVT NVT = Lo.getValueType();
+  Lo = DAG.getNode(ISD::ADD, NVT, DAG.getNode(ISD::CTPOP, NVT, Lo),
+                   DAG.getNode(ISD::CTPOP, NVT, Hi));
+  Hi = DAG.getConstant(0, NVT);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N,
+                                         SDOperand &Lo, SDOperand &Hi) {
+  // cttz (HiLo) -> Lo != 0 ? cttz(Lo) : (cttz(Hi)+32)
+  GetExpandedInteger(N->getOperand(0), Lo, Hi);
+  MVT NVT = Lo.getValueType();
+
+  SDOperand LoNotZero = DAG.getSetCC(TLI.getSetCCResultType(Lo), Lo,
+                                     DAG.getConstant(0, NVT), ISD::SETNE);
+
+  SDOperand LoLZ = DAG.getNode(ISD::CTTZ, NVT, Lo);
+  SDOperand HiLZ = DAG.getNode(ISD::CTTZ, NVT, Hi);
+
+  Lo = DAG.getNode(ISD::SELECT, NVT, LoNotZero, LoLZ,
+                   DAG.getNode(ISD::ADD, NVT, HiLZ,
+                               DAG.getConstant(NVT.getSizeInBits(), NVT)));
+  Hi = DAG.getConstant(0, NVT);
+}
+
+void DAGTypeLegalizer::ExpandIntRes_EXTRACT_VECTOR_ELT(SDNode *N,
+                                                       SDOperand &Lo,
+                                                       SDOperand &Hi) {
+  SDOperand OldVec = N->getOperand(0);
+  unsigned OldElts = OldVec.getValueType().getVectorNumElements();
+
+  // Convert to a vector of the expanded element type, for example
+  // <2 x i64> -> <4 x i32>.
+  MVT OldVT = N->getValueType(0);
+  MVT NewVT = TLI.getTypeToTransformTo(OldVT);
+  assert(OldVT.getSizeInBits() == 2 * NewVT.getSizeInBits() &&
+         "Do not know how to handle this expansion!");
+
+  SDOperand NewVec = DAG.getNode(ISD::BIT_CONVERT,
+                                 MVT::getVectorVT(NewVT, 2*OldElts),
+                                 OldVec);
+
+  // Extract the elements at 2 * Idx and 2 * Idx + 1 from the new vector.
+  SDOperand Idx = N->getOperand(1);
+
+  // Make sure the type of Idx is big enough to hold the new values.
+  if (Idx.getValueType().bitsLT(TLI.getPointerTy()))
+    Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx);
+
+  Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, Idx);
+  Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx);
+
+  Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx,
+                    DAG.getConstant(1, Idx.getValueType()));
+  Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx);
+
+  if (TLI.isBigEndian())
+    std::swap(Lo, Hi);
+}
+
+/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded,
+/// and the shift amount is a constant 'Amt'.  Expand the operation.
+void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt,
+                                             SDOperand &Lo, SDOperand &Hi) {
+  // Expand the incoming operand to be shifted, so that we have its parts
+  SDOperand InL, InH;
+  GetExpandedInteger(N->getOperand(0), InL, InH);
+
+  MVT NVT = InL.getValueType();
+  unsigned VTBits = N->getValueType(0).getSizeInBits();
+  unsigned NVTBits = NVT.getSizeInBits();
+  MVT ShTy = N->getOperand(1).getValueType();
+
+  if (N->getOpcode() == ISD::SHL) {
+    if (Amt > VTBits) {
+      Lo = Hi = DAG.getConstant(0, NVT);
+    } else if (Amt > NVTBits) {
+      Lo = DAG.getConstant(0, NVT);
+      Hi = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt-NVTBits,ShTy));
+    } else if (Amt == NVTBits) {
+      Lo = DAG.getConstant(0, NVT);
+      Hi = InL;
+    } else {
+      Lo = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt, ShTy));
+      Hi = DAG.getNode(ISD::OR, NVT,
+                       DAG.getNode(ISD::SHL, NVT, InH,
+                                   DAG.getConstant(Amt, ShTy)),
+                       DAG.getNode(ISD::SRL, NVT, InL,
+                                   DAG.getConstant(NVTBits-Amt, ShTy)));
+    }
+    return;
+  }
+
+  if (N->getOpcode() == ISD::SRL) {
+    if (Amt > VTBits) {
+      Lo = DAG.getConstant(0, NVT);
+      Hi = DAG.getConstant(0, NVT);
+    } else if (Amt > NVTBits) {
+      Lo = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy));
+      Hi = DAG.getConstant(0, NVT);
+    } else if (Amt == NVTBits) {
+      Lo = InH;
+      Hi = DAG.getConstant(0, NVT);
+    } else {
+      Lo = DAG.getNode(ISD::OR, NVT,
+                       DAG.getNode(ISD::SRL, NVT, InL,
+                                   DAG.getConstant(Amt, ShTy)),
+                       DAG.getNode(ISD::SHL, NVT, InH,
+                                   DAG.getConstant(NVTBits-Amt, ShTy)));
+      Hi = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt, ShTy));
+    }
+    return;
+  }
+
+  assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
+  if (Amt > VTBits) {
+    Hi = Lo = DAG.getNode(ISD::SRA, NVT, InH,
+                          DAG.getConstant(NVTBits-1, ShTy));
+  } else if (Amt > NVTBits) {
+    Lo = DAG.getNode(ISD::SRA, NVT, InH,
+                     DAG.getConstant(Amt-NVTBits, ShTy));
+    Hi = DAG.getNode(ISD::SRA, NVT, InH,
+                     DAG.getConstant(NVTBits-1, ShTy));
+  } else if (Amt == NVTBits) {
+    Lo = InH;
+    Hi = DAG.getNode(ISD::SRA, NVT, InH,
+                     DAG.getConstant(NVTBits-1, ShTy));
+  } else {
+    Lo = DAG.getNode(ISD::OR, NVT,
+                     DAG.getNode(ISD::SRL, NVT, InL,
+                                 DAG.getConstant(Amt, ShTy)),
+                     DAG.getNode(ISD::SHL, NVT, InH,
+                                 DAG.getConstant(NVTBits-Amt, ShTy)));
+    Hi = DAG.getNode(ISD::SRA, NVT, InH, DAG.getConstant(Amt, ShTy));
+  }
+}
+
+/// ExpandShiftWithKnownAmountBit - Try to determine whether we can simplify
+/// this shift based on knowledge of the high bit of the shift amount.  If we
+/// can tell this, we know that it is >= 32 or < 32, without knowing the actual
+/// shift amount.
+bool DAGTypeLegalizer::
+ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+  SDOperand Amt = N->getOperand(1);
+  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
+  MVT ShTy = Amt.getValueType();
+  unsigned ShBits = ShTy.getSizeInBits();
+  unsigned NVTBits = NVT.getSizeInBits();
+  assert(isPowerOf2_32(NVTBits) &&
+         "Expanded integer type size not a power of two!");
+
+  APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits));
+  APInt KnownZero, KnownOne;
+  DAG.ComputeMaskedBits(N->getOperand(1), HighBitMask, KnownZero, KnownOne);
+
+  // If we don't know anything about the high bits, exit.
+  if (((KnownZero|KnownOne) & HighBitMask) == 0)
+    return false;
+
+  // Get the incoming operand to be shifted.
+  SDOperand InL, InH;
+  GetExpandedInteger(N->getOperand(0), InL, InH);
+
+  // If we know that any of the high bits of the shift amount are one, then we
+  // can do this as a couple of simple shifts.
+  if (KnownOne.intersects(HighBitMask)) {
+    // Mask out the high bit, which we know is set.
+    Amt = DAG.getNode(ISD::AND, ShTy, Amt,
+                      DAG.getConstant(~HighBitMask, ShTy));
+
+    switch (N->getOpcode()) {
+    default: assert(0 && "Unknown shift");
+    case ISD::SHL:
+      Lo = DAG.getConstant(0, NVT);              // Low part is zero.
+      Hi = DAG.getNode(ISD::SHL, NVT, InL, Amt); // High part from Lo part.
+      return true;
+    case ISD::SRL:
+      Hi = DAG.getConstant(0, NVT);              // Hi part is zero.
+      Lo = DAG.getNode(ISD::SRL, NVT, InH, Amt); // Lo part from Hi part.
+      return true;
+    case ISD::SRA:
+      Hi = DAG.getNode(ISD::SRA, NVT, InH,       // Sign extend high part.
+                       DAG.getConstant(NVTBits-1, ShTy));
+      Lo = DAG.getNode(ISD::SRA, NVT, InH, Amt); // Lo part from Hi part.
+      return true;
+    }
+  }
+
+  // If we know that all of the high bits of the shift amount are zero, then we
+  // can do this as a couple of simple shifts.
+  if ((KnownZero & HighBitMask) == HighBitMask) {
+    // Compute 32-amt.
+    SDOperand Amt2 = DAG.getNode(ISD::SUB, ShTy,
+                                 DAG.getConstant(NVTBits, ShTy),
+                                 Amt);
+    unsigned Op1, Op2;
+    switch (N->getOpcode()) {
+    default: assert(0 && "Unknown shift");
+    case ISD::SHL:  Op1 = ISD::SHL; Op2 = ISD::SRL; break;
+    case ISD::SRL:
+    case ISD::SRA:  Op1 = ISD::SRL; Op2 = ISD::SHL; break;
+    }
+
+    Lo = DAG.getNode(N->getOpcode(), NVT, InL, Amt);
+    Hi = DAG.getNode(ISD::OR, NVT,
+                     DAG.getNode(Op1, NVT, InH, Amt),
+                     DAG.getNode(Op2, NVT, InL, Amt2));
+    return true;
+  }
+
+  return false;
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Integer Operand Expansion
+//===----------------------------------------------------------------------===//
+
+/// ExpandIntegerOperand - This method is called when the specified operand of
+/// the specified node is found to need expansion.  At this point, all of the
+/// result types of the node are known to be legal, but other operands of the
+/// node may need promotion or expansion as well as the specified one.
+bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) {
+  DEBUG(cerr << "Expand integer operand: "; N->dump(&DAG); cerr << "\n");
+  SDOperand Res(0, 0);
+
+  if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
+      == TargetLowering::Custom)
+    Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
+
+  if (Res.Val == 0) {
+    switch (N->getOpcode()) {
+    default:
+  #ifndef NDEBUG
+      cerr << "ExpandIntegerOperand Op #" << OpNo << ": ";
+      N->dump(&DAG); cerr << "\n";
+  #endif
+      assert(0 && "Do not know how to expand this operator's operand!");
+      abort();
+
+    case ISD::TRUNCATE:        Res = ExpandIntOp_TRUNCATE(N); break;
+    case ISD::BIT_CONVERT:     Res = ExpandIntOp_BIT_CONVERT(N); break;
+
+    case ISD::SINT_TO_FP:
+      Res = ExpandIntOp_SINT_TO_FP(N->getOperand(0), N->getValueType(0));
+      break;
+    case ISD::UINT_TO_FP:
+      Res = ExpandIntOp_UINT_TO_FP(N->getOperand(0), N->getValueType(0));
+      break;
+    case ISD::EXTRACT_ELEMENT: Res = ExpandIntOp_EXTRACT_ELEMENT(N); break;
+
+    case ISD::BR_CC:           Res = ExpandIntOp_BR_CC(N); break;
+    case ISD::SETCC:           Res = ExpandIntOp_SETCC(N); break;
+
+    case ISD::STORE:
+      Res = ExpandIntOp_STORE(cast<StoreSDNode>(N), OpNo);
+      break;
+
+    case ISD::BUILD_VECTOR: Res = ExpandIntOp_BUILD_VECTOR(N); break;
+    }
+  }
+
+  // If the result is null, the sub-method took care of registering results etc.
+  if (!Res.Val) return false;
+  // If the result is N, the sub-method updated N in place.  Check to see if any
+  // operands are new, and if so, mark them.
+  if (Res.Val == N) {
+    // Mark N as new and remark N and its operands.  This allows us to correctly
+    // revisit N if it needs another step of expansion and allows us to visit
+    // any new operands to N.
+    ReanalyzeNode(N);
+    return true;
+  }
+
+  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
+         "Invalid operand expansion");
+
+  ReplaceValueWith(SDOperand(N, 0), Res);
+  return false;
+}
+
+SDOperand DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) {
+  SDOperand InL, InH;
+  GetExpandedInteger(N->getOperand(0), InL, InH);
+  // Just truncate the low part of the source.
+  return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), InL);
+}
+
+SDOperand DAGTypeLegalizer::ExpandIntOp_BIT_CONVERT(SDNode *N) {
+  if (N->getValueType(0).isVector()) {
+    // An illegal integer type is being converted to a legal vector type.
+    // Make a two element vector out of the expanded parts and convert that
+    // instead, but only if the new vector type is legal (otherwise there
+    // is no point, and it might create expansion loops).  For example, on
+    // x86 this turns v1i64 = BIT_CONVERT i64 into v1i64 = BIT_CONVERT v2i32.
+    MVT OVT = N->getOperand(0).getValueType();
+    MVT NVT = MVT::getVectorVT(TLI.getTypeToTransformTo(OVT), 2);
+
+    if (isTypeLegal(NVT)) {
+      SDOperand Parts[2];
+      GetExpandedInteger(N->getOperand(0), Parts[0], Parts[1]);
+
+      if (TLI.isBigEndian())
+        std::swap(Parts[0], Parts[1]);
+
+      SDOperand Vec = DAG.getNode(ISD::BUILD_VECTOR, NVT, Parts, 2);
+      return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Vec);
+    }
+  }
+
+  // Otherwise, store to a temporary and load out again as the new type.
+  return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
+}
+
+SDOperand DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDOperand Source,
+                                                     MVT DestTy) {
+  // We know the destination is legal, but that the input needs to be expanded.
+  MVT SourceVT = Source.getValueType();
+
+  // Check to see if the target has a custom way to lower this.  If so, use it.
+  switch (TLI.getOperationAction(ISD::SINT_TO_FP, SourceVT)) {
+  default: assert(0 && "This action not implemented for this operation!");
+  case TargetLowering::Legal:
+  case TargetLowering::Expand:
+    break;   // This case is handled below.
+  case TargetLowering::Custom:
+    SDOperand NV = TLI.LowerOperation(DAG.getNode(ISD::SINT_TO_FP, DestTy,
+                                                  Source), DAG);
+    if (NV.Val) return NV;
+    break;   // The target lowered this.
+  }
+
+  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
+  if (SourceVT == MVT::i64) {
+    if (DestTy == MVT::f32)
+      LC = RTLIB::SINTTOFP_I64_F32;
+    else {
+      assert(DestTy == MVT::f64 && "Unknown fp value type!");
+      LC = RTLIB::SINTTOFP_I64_F64;
+    }
+  } else if (SourceVT == MVT::i128) {
+    if (DestTy == MVT::f32)
+      LC = RTLIB::SINTTOFP_I128_F32;
+    else if (DestTy == MVT::f64)
+      LC = RTLIB::SINTTOFP_I128_F64;
+    else if (DestTy == MVT::f80)
+      LC = RTLIB::SINTTOFP_I128_F80;
+    else {
+      assert(DestTy == MVT::ppcf128 && "Unknown fp value type!");
+      LC = RTLIB::SINTTOFP_I128_PPCF128;
+    }
+  } else {
+    assert(0 && "Unknown int value type!");
+  }
+
+  assert(LC != RTLIB::UNKNOWN_LIBCALL &&
+         "Don't know how to expand this SINT_TO_FP!");
+  return MakeLibCall(LC, DestTy, &Source, 1, true);
+}
+
+SDOperand DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDOperand Source,
+                                                     MVT DestTy) {
+  // We know the destination is legal, but that the input needs to be expanded.
+  assert(getTypeAction(Source.getValueType()) == ExpandInteger &&
+         "This is not an expansion!");
+
+  // If this is unsigned, and not supported, first perform the conversion to
+  // signed, then adjust the result if the sign bit is set.
+  SDOperand SignedConv = ExpandIntOp_SINT_TO_FP(Source, DestTy);
+
+  // The 64-bit value loaded will be incorrectly if the 'sign bit' of the
+  // incoming integer is set.  To handle this, we dynamically test to see if
+  // it is set, and, if so, add a fudge factor.
+  SDOperand Lo, Hi;
+  GetExpandedInteger(Source, Lo, Hi);
+
+  SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi), Hi,
+                                   DAG.getConstant(0, Hi.getValueType()),
+                                   ISD::SETLT);
+  SDOperand Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4);
+  SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
+                                    SignSet, Four, Zero);
+  uint64_t FF = 0x5f800000ULL;
+  if (TLI.isLittleEndian()) FF <<= 32;
+  Constant *FudgeFactor = ConstantInt::get((Type*)Type::Int64Ty, FF);
+
+  SDOperand CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy());
+  CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
+  SDOperand FudgeInReg;
+  if (DestTy == MVT::f32)
+    FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, NULL, 0);
+  else if (DestTy.bitsGT(MVT::f32))
+    // FIXME: Avoid the extend by construction the right constantpool?
+    FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, DestTy, DAG.getEntryNode(),
+                                CPIdx, NULL, 0, MVT::f32);
+  else
+    assert(0 && "Unexpected conversion");
+
+  return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg);
+}
+
+SDOperand DAGTypeLegalizer::ExpandIntOp_EXTRACT_ELEMENT(SDNode *N) {
+  SDOperand Lo, Hi;
+  GetExpandedInteger(N->getOperand(0), Lo, Hi);
+  return cast<ConstantSDNode>(N->getOperand(1))->getValue() ? Hi : Lo;
+}
+
+SDOperand DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
+  SDOperand NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
+  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
+  ExpandSetCCOperands(NewLHS, NewRHS, CCCode);
+
+  // If ExpandSetCCOperands returned a scalar, we need to compare the result
+  // against zero to select between true and false values.
+  if (NewRHS.Val == 0) {
+    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
+    CCCode = ISD::SETNE;
+  }
+
+  // Update N to have the operands specified.
+  return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
+                                DAG.getCondCode(CCCode), NewLHS, NewRHS,
+                                N->getOperand(4));
+}
+
+SDOperand DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
+  SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
+  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
+  ExpandSetCCOperands(NewLHS, NewRHS, CCCode);
+
+  // If ExpandSetCCOperands returned a scalar, use it.
+  if (NewRHS.Val == 0) return NewLHS;
+
+  // Otherwise, update N to have the operands specified.
+  return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS,
+                                DAG.getCondCode(CCCode));
+}
+
+/// ExpandSetCCOperands - Expand the operands of a comparison.  This code is
+/// shared among BR_CC, SELECT_CC, and SETCC handlers.
+void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
+                                           ISD::CondCode &CCCode) {
+  SDOperand LHSLo, LHSHi, RHSLo, RHSHi;
+  GetExpandedInteger(NewLHS, LHSLo, LHSHi);
+  GetExpandedInteger(NewRHS, RHSLo, RHSHi);
+
+  MVT VT = NewLHS.getValueType();
+  if (VT == MVT::ppcf128) {
+    // FIXME:  This generated code sucks.  We want to generate
+    //         FCMP crN, hi1, hi2
+    //         BNE crN, L:
+    //         FCMP crN, lo1, lo2
+    // The following can be improved, but not that much.
+    SDOperand Tmp1, Tmp2, Tmp3;
+    Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, ISD::SETEQ);
+    Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, CCCode);
+    Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
+    Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, ISD::SETNE);
+    Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, CCCode);
+    Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
+    NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3);
+    NewRHS = SDOperand();   // LHS is the result, not a compare.
+    return;
+  }
+
+  if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) {
+    if (RHSLo == RHSHi)
+      if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo))
+        if (RHSCST->isAllOnesValue()) {
+          // Equality comparison to -1.
+          NewLHS = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi);
+          NewRHS = RHSLo;
+          return;
+        }
+
+    NewLHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo);
+    NewRHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi);
+    NewLHS = DAG.getNode(ISD::OR, NewLHS.getValueType(), NewLHS, NewRHS);
+    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
+    return;
+  }
+
+  // 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>(NewRHS))
+    if ((CCCode == ISD::SETLT && CST->isNullValue()) ||     // X < 0
+        (CCCode == ISD::SETGT && CST->isAllOnesValue())) {  // X > -1
+      NewLHS = LHSHi;
+      NewRHS = RHSHi;
+      return;
+    }
+
+  // FIXME: This generated code sucks.
+  ISD::CondCode LowCC;
+  switch (CCCode) {
+  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)
+  TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, NULL);
+  SDOperand Tmp1, Tmp2;
+  Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, LowCC,
+                           false, DagCombineInfo);
+  if (!Tmp1.Val)
+    Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, LowCC);
+  Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
+                           CCCode, false, DagCombineInfo);
+  if (!Tmp2.Val)
+    Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
+                       DAG.getCondCode(CCCode));
+
+  ConstantSDNode *Tmp1C = dyn_cast<ConstantSDNode>(Tmp1.Val);
+  ConstantSDNode *Tmp2C = dyn_cast<ConstantSDNode>(Tmp2.Val);
+  if ((Tmp1C && Tmp1C->isNullValue()) ||
+      (Tmp2C && Tmp2C->isNullValue() &&
+       (CCCode == ISD::SETLE || CCCode == ISD::SETGE ||
+        CCCode == ISD::SETUGE || CCCode == ISD::SETULE)) ||
+      (Tmp2C && Tmp2C->getAPIntValue() == 1 &&
+       (CCCode == ISD::SETLT || CCCode == ISD::SETGT ||
+        CCCode == ISD::SETUGT || CCCode == ISD::SETULT))) {
+    // low part is known false, returns high part.
+    // For LE / GE, if high part is known false, ignore the low part.
+    // For LT / GT, if high part is known true, ignore the low part.
+    NewLHS = Tmp2;
+    NewRHS = SDOperand();
+    return;
+  }
+
+  NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
+                             ISD::SETEQ, false, DagCombineInfo);
+  if (!NewLHS.Val)
+    NewLHS = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
+                          ISD::SETEQ);
+  NewLHS = DAG.getNode(ISD::SELECT, Tmp1.getValueType(),
+                       NewLHS, Tmp1, Tmp2);
+  NewRHS = SDOperand();
+}
+
+SDOperand DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) {
+  // FIXME: Add support for indexed stores.
+  assert(OpNo == 1 && "Can only expand the stored value so far");
+
+  MVT VT = N->getOperand(1).getValueType();
+  MVT NVT = TLI.getTypeToTransformTo(VT);
+  SDOperand Ch  = N->getChain();
+  SDOperand Ptr = N->getBasePtr();
+  int SVOffset = N->getSrcValueOffset();
+  unsigned Alignment = N->getAlignment();
+  bool isVolatile = N->isVolatile();
+  SDOperand Lo, Hi;
+
+  assert(!(NVT.getSizeInBits() & 7) && "Expanded type not byte sized!");
+
+  if (!N->isTruncatingStore()) {
+    unsigned IncrementSize = 0;
+    GetExpandedInteger(N->getValue(), Lo, Hi);
+    IncrementSize = Hi.getValueType().getSizeInBits()/8;
+
+    if (TLI.isBigEndian())
+      std::swap(Lo, Hi);
+
+    Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(),
+                      SVOffset, isVolatile, Alignment);
+
+    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                      DAG.getIntPtrConstant(IncrementSize));
+    assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!");
+    Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
+                      isVolatile, MinAlign(Alignment, IncrementSize));
+    return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+  } else if (N->getMemoryVT().bitsLE(NVT)) {
+    GetExpandedInteger(N->getValue(), Lo, Hi);
+    return DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
+                             N->getMemoryVT(), isVolatile, Alignment);
+  } else if (TLI.isLittleEndian()) {
+    // Little-endian - low bits are at low addresses.
+    GetExpandedInteger(N->getValue(), Lo, Hi);
+
+    Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
+                      isVolatile, Alignment);
+
+    unsigned ExcessBits =
+      N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
+    MVT NEVT = MVT::getIntegerVT(ExcessBits);
+
+    // Increment the pointer to the other half.
+    unsigned IncrementSize = NVT.getSizeInBits()/8;
+    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                      DAG.getIntPtrConstant(IncrementSize));
+    Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(),
+                           SVOffset+IncrementSize, NEVT,
+                           isVolatile, MinAlign(Alignment, IncrementSize));
+    return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+  } else {
+    // Big-endian - high bits are at low addresses.  Favor aligned stores at
+    // the cost of some bit-fiddling.
+    GetExpandedInteger(N->getValue(), Lo, Hi);
+
+    MVT EVT = N->getMemoryVT();
+    unsigned EBytes = EVT.getStoreSizeInBits()/8;
+    unsigned IncrementSize = NVT.getSizeInBits()/8;
+    unsigned ExcessBits = (EBytes - IncrementSize)*8;
+    MVT HiVT = MVT::getIntegerVT(EVT.getSizeInBits() - ExcessBits);
+
+    if (ExcessBits < NVT.getSizeInBits()) {
+      // Transfer high bits from the top of Lo to the bottom of Hi.
+      Hi = DAG.getNode(ISD::SHL, NVT, Hi,
+                       DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
+                                       TLI.getShiftAmountTy()));
+      Hi = DAG.getNode(ISD::OR, NVT, Hi,
+                       DAG.getNode(ISD::SRL, NVT, Lo,
+                                   DAG.getConstant(ExcessBits,
+                                                   TLI.getShiftAmountTy())));
+    }
+
+    // Store both the high bits and maybe some of the low bits.
+    Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(),
+                           SVOffset, HiVT, isVolatile, Alignment);
+
+    // Increment the pointer to the other half.
+    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                      DAG.getIntPtrConstant(IncrementSize));
+    // Store the lowest ExcessBits bits in the second half.
+    Lo = DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(),
+                           SVOffset+IncrementSize,
+                           MVT::getIntegerVT(ExcessBits),
+                           isVolatile, MinAlign(Alignment, IncrementSize));
+    return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+  }
+}
+
+SDOperand DAGTypeLegalizer::ExpandIntOp_BUILD_VECTOR(SDNode *N) {
+  // The vector type is legal but the element type needs expansion.
+  MVT VecVT = N->getValueType(0);
+  unsigned NumElts = VecVT.getVectorNumElements();
+  MVT OldVT = N->getOperand(0).getValueType();
+  MVT NewVT = TLI.getTypeToTransformTo(OldVT);
+
+  assert(OldVT.getSizeInBits() == 2 * NewVT.getSizeInBits() &&
+         "Do not know how to expand this operand!");
+
+  // Build a vector of twice the length out of the expanded elements.
+  // For example <2 x i64> -> <4 x i32>.
+  std::vector<SDOperand> NewElts;
+  NewElts.reserve(NumElts*2);
+
+  for (unsigned i = 0; i < NumElts; ++i) {
+    SDOperand Lo, Hi;
+    GetExpandedInteger(N->getOperand(i), Lo, Hi);
+    if (TLI.isBigEndian())
+      std::swap(Lo, Hi);
+    NewElts.push_back(Lo);
+    NewElts.push_back(Hi);
+  }
+
+  SDOperand NewVec = DAG.getNode(ISD::BUILD_VECTOR,
+                                 MVT::getVectorVT(NewVT, NewElts.size()),
+                                 &NewElts[0], NewElts.size());
+
+  // Convert the new vector to the old vector type.
+  return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
+}

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp?rev=52408&r1=52407&r2=52408&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp Tue Jun 17 09:27:01 2008
@@ -42,7 +42,7 @@
   // The root of the dag may dangle to deleted nodes until the type legalizer is
   // done.  Set it to null to avoid confusion.
   DAG.setRoot(SDOperand());
-  
+
   // Walk all nodes in the graph, assigning them a NodeID of 'ReadyToProcess'
   // (and remembering them) if they are leaves and assigning 'NewNode' if
   // non-leaves.
@@ -55,14 +55,14 @@
       I->setNodeId(NewNode);
     }
   }
-  
+
   // Now that we have a set of nodes to process, handle them all.
   while (!Worklist.empty()) {
     SDNode *N = Worklist.back();
     Worklist.pop_back();
     assert(N->getNodeId() == ReadyToProcess &&
            "Node should be ready if on worklist!");
-    
+
     // Scan the values produced by the node, checking to see if any result
     // types are illegal.
     unsigned i = 0;
@@ -74,14 +74,17 @@
         assert(false && "Unknown action!");
       case Legal:
         break;
-      case Promote:
-        PromoteResult(N, i);
+      case PromoteInteger:
+        PromoteIntegerResult(N, i);
         goto NodeDone;
-      case Expand:
-        ExpandResult(N, i);
+      case ExpandInteger:
+        ExpandIntegerResult(N, i);
         goto NodeDone;
-      case FloatToInt:
-        FloatToIntResult(N, i);
+      case PromoteFloat:
+        PromoteFloatResult(N, i);
+        goto NodeDone;
+      case ExpandFloat:
+        ExpandFloatResult(N, i);
         goto NodeDone;
       case Scalarize:
         ScalarizeResult(N, i);
@@ -104,14 +107,17 @@
         assert(false && "Unknown action!");
       case Legal:
         continue;
-      case Promote:
-        NeedsRevisit = PromoteOperand(N, i);
+      case PromoteInteger:
+        NeedsRevisit = PromoteIntegerOperand(N, i);
+        break;
+      case ExpandInteger:
+        NeedsRevisit = ExpandIntegerOperand(N, i);
         break;
-      case Expand:
-        NeedsRevisit = ExpandOperand(N, i);
+      case PromoteFloat:
+        NeedsRevisit = PromoteFloatOperand(N, i);
         break;
-      case FloatToInt:
-        NeedsRevisit = FloatToIntOperand(N, i);
+      case ExpandFloat:
+        NeedsRevisit = ExpandFloatOperand(N, i);
         break;
       case Scalarize:
         NeedsRevisit = ScalarizeOperand(N, i);
@@ -126,7 +132,7 @@
     // If the node needs revisiting, don't add all users to the worklist etc.
     if (NeedsRevisit)
       continue;
-    
+
     if (i == NumOperands)
       DEBUG(cerr << "Legally typed node: "; N->dump(&DAG); cerr << "\n");
     }
@@ -135,37 +141,37 @@
     // If we reach here, the node was processed, potentially creating new nodes.
     // Mark it as processed and add its users to the worklist as appropriate.
     N->setNodeId(Processed);
-    
+
     for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end();
          UI != E; ++UI) {
       SDNode *User = UI->getUser();
       int NodeID = User->getNodeId();
       assert(NodeID != ReadyToProcess && NodeID != Processed &&
              "Invalid node id for user of unprocessed node!");
-      
+
       // This node has two options: it can either be a new node or its Node ID
       // may be a count of the number of operands it has that are not ready.
       if (NodeID > 0) {
         User->setNodeId(NodeID-1);
-        
+
         // If this was the last use it was waiting on, add it to the ready list.
         if (NodeID-1 == ReadyToProcess)
           Worklist.push_back(User);
         continue;
       }
-      
+
       // Otherwise, this node is new: this is the first operand of it that
       // became ready.  Its new NodeID is the number of operands it has minus 1
       // (as this node is now processed).
       assert(NodeID == NewNode && "Unknown node ID!");
       User->setNodeId(User->getNumOperands()-1);
-      
+
       // If the node only has a single operand, it is now ready.
       if (User->getNumOperands() == 1)
         Worklist.push_back(User);
     }
   }
-  
+
   // If the root changed (e.g. it was a dead load, update the root).
   DAG.setRoot(Dummy.getValue());
 
@@ -315,8 +321,8 @@
   NodeUpdateListener NUL(*this);
   DAG.ReplaceAllUsesOfValueWith(From, To, &NUL);
 
-  // The old node may still be present in a map like ExpandedNodes or
-  // PromotedNodes.  Inform maps about the replacement.
+  // The old node may still be present in a map like ExpandedIntegers or
+  // PromotedIntegers.  Inform maps about the replacement.
   NoteReplacement(From, To);
 }
 
@@ -336,8 +342,8 @@
   NodeUpdateListener NUL(*this);
   DAG.ReplaceAllUsesWith(From, To, &NUL);
 
-  // The old node may still be present in a map like ExpandedNodes or
-  // PromotedNodes.  Inform maps about the replacement.
+  // The old node may still be present in a map like ExpandedIntegers or
+  // PromotedIntegers.  Inform maps about the replacement.
   for (unsigned i = 0, e = From->getNumValues(); i != e; ++i) {
     assert(From->getValueType(i) == To->getValueType(i) &&
            "Node results don't match");
@@ -380,29 +386,38 @@
         I->second = Replacement;
     }
 
-    for (DenseMap<SDOperand, SDOperand>::iterator I = PromotedNodes.begin(),
-         E = PromotedNodes.end(); I != E; ++I) {
+    for (DenseMap<SDOperand, SDOperand>::iterator I = PromotedIntegers.begin(),
+         E = PromotedIntegers.end(); I != E; ++I) {
       assert(I->first != N);
       if (I->second == N)
         I->second = Replacement;
     }
 
-    for (DenseMap<SDOperand, SDOperand>::iterator I = FloatToIntedNodes.begin(),
-         E = FloatToIntedNodes.end(); I != E; ++I) {
+    for (DenseMap<SDOperand, SDOperand>::iterator I = PromotedFloats.begin(),
+         E = PromotedFloats.end(); I != E; ++I) {
       assert(I->first != N);
       if (I->second == N)
         I->second = Replacement;
     }
 
-    for (DenseMap<SDOperand, SDOperand>::iterator I = ScalarizedNodes.begin(),
-         E = ScalarizedNodes.end(); I != E; ++I) {
+    for (DenseMap<SDOperand, SDOperand>::iterator I = ScalarizedVectors.begin(),
+         E = ScalarizedVectors.end(); I != E; ++I) {
       assert(I->first != N);
       if (I->second == N)
         I->second = Replacement;
     }
 
     for (DenseMap<SDOperand, std::pair<SDOperand, SDOperand> >::iterator
-         I = ExpandedNodes.begin(), E = ExpandedNodes.end(); I != E; ++I) {
+         I = ExpandedIntegers.begin(), E = ExpandedIntegers.end(); I != E; ++I){
+      assert(I->first != N);
+      if (I->second.first == N)
+        I->second.first = Replacement;
+      if (I->second.second == N)
+        I->second.second = Replacement;
+    }
+
+    for (DenseMap<SDOperand, std::pair<SDOperand, SDOperand> >::iterator
+         I = ExpandedFloats.begin(), E = ExpandedFloats.end(); I != E; ++I) {
       assert(I->first != N);
       if (I->second.first == N)
         I->second.first = Replacement;
@@ -411,7 +426,7 @@
     }
 
     for (DenseMap<SDOperand, std::pair<SDOperand, SDOperand> >::iterator
-         I = SplitNodes.begin(), E = SplitNodes.end(); I != E; ++I) {
+         I = SplitVectors.begin(), E = SplitVectors.end(); I != E; ++I) {
       assert(I->first != N);
       if (I->second.first == N)
         I->second.first = Replacement;
@@ -422,36 +437,62 @@
 }
 
 
-void DAGTypeLegalizer::SetPromotedOp(SDOperand Op, SDOperand Result) {
+void DAGTypeLegalizer::SetPromotedInteger(SDOperand Op, SDOperand Result) {
   ExpungeNode(Result);
   AnalyzeNewNode(Result.Val);
 
-  SDOperand &OpEntry = PromotedNodes[Op];
+  SDOperand &OpEntry = PromotedIntegers[Op];
   assert(OpEntry.Val == 0 && "Node is already promoted!");
   OpEntry = Result;
 }
 
-void DAGTypeLegalizer::SetIntegerOp(SDOperand Op, SDOperand Result) {
+void DAGTypeLegalizer::SetPromotedFloat(SDOperand Op, SDOperand Result) {
   ExpungeNode(Result);
   AnalyzeNewNode(Result.Val);
 
-  SDOperand &OpEntry = FloatToIntedNodes[Op];
+  SDOperand &OpEntry = PromotedFloats[Op];
   assert(OpEntry.Val == 0 && "Node is already converted to integer!");
   OpEntry = Result;
 }
 
-void DAGTypeLegalizer::SetScalarizedOp(SDOperand Op, SDOperand Result) {
+void DAGTypeLegalizer::SetScalarizedVector(SDOperand Op, SDOperand Result) {
   ExpungeNode(Result);
   AnalyzeNewNode(Result.Val);
 
-  SDOperand &OpEntry = ScalarizedNodes[Op];
+  SDOperand &OpEntry = ScalarizedVectors[Op];
   assert(OpEntry.Val == 0 && "Node is already scalarized!");
   OpEntry = Result;
 }
 
-void DAGTypeLegalizer::GetExpandedOp(SDOperand Op, SDOperand &Lo, 
-                                     SDOperand &Hi) {
-  std::pair<SDOperand, SDOperand> &Entry = ExpandedNodes[Op];
+void DAGTypeLegalizer::GetExpandedInteger(SDOperand Op, SDOperand &Lo,
+                                          SDOperand &Hi) {
+  std::pair<SDOperand, SDOperand> &Entry = ExpandedIntegers[Op];
+  RemapNode(Entry.first);
+  RemapNode(Entry.second);
+  assert(Entry.first.Val && "Operand isn't expanded");
+  Lo = Entry.first;
+  Hi = Entry.second;
+}
+
+void DAGTypeLegalizer::SetExpandedInteger(SDOperand Op, SDOperand Lo,
+                                          SDOperand Hi) {
+  ExpungeNode(Lo);
+  ExpungeNode(Hi);
+
+  // Lo/Hi may have been newly allocated, if so, add nodeid's as relevant.
+  AnalyzeNewNode(Lo.Val);
+  AnalyzeNewNode(Hi.Val);
+
+  // Remember that this is the result of the node.
+  std::pair<SDOperand, SDOperand> &Entry = ExpandedIntegers[Op];
+  assert(Entry.first.Val == 0 && "Node already expanded");
+  Entry.first = Lo;
+  Entry.second = Hi;
+}
+
+void DAGTypeLegalizer::GetExpandedFloat(SDOperand Op, SDOperand &Lo,
+                                        SDOperand &Hi) {
+  std::pair<SDOperand, SDOperand> &Entry = ExpandedFloats[Op];
   RemapNode(Entry.first);
   RemapNode(Entry.second);
   assert(Entry.first.Val && "Operand isn't expanded");
@@ -459,7 +500,8 @@
   Hi = Entry.second;
 }
 
-void DAGTypeLegalizer::SetExpandedOp(SDOperand Op, SDOperand Lo, SDOperand Hi) {
+void DAGTypeLegalizer::SetExpandedFloat(SDOperand Op, SDOperand Lo,
+                                        SDOperand Hi) {
   ExpungeNode(Lo);
   ExpungeNode(Hi);
 
@@ -468,14 +510,15 @@
   AnalyzeNewNode(Hi.Val);
 
   // Remember that this is the result of the node.
-  std::pair<SDOperand, SDOperand> &Entry = ExpandedNodes[Op];
+  std::pair<SDOperand, SDOperand> &Entry = ExpandedFloats[Op];
   assert(Entry.first.Val == 0 && "Node already expanded");
   Entry.first = Lo;
   Entry.second = Hi;
 }
 
-void DAGTypeLegalizer::GetSplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi) {
-  std::pair<SDOperand, SDOperand> &Entry = SplitNodes[Op];
+void DAGTypeLegalizer::GetSplitVector(SDOperand Op, SDOperand &Lo,
+                                      SDOperand &Hi) {
+  std::pair<SDOperand, SDOperand> &Entry = SplitVectors[Op];
   RemapNode(Entry.first);
   RemapNode(Entry.second);
   assert(Entry.first.Val && "Operand isn't split");
@@ -483,7 +526,8 @@
   Hi = Entry.second;
 }
 
-void DAGTypeLegalizer::SetSplitOp(SDOperand Op, SDOperand Lo, SDOperand Hi) {
+void DAGTypeLegalizer::SetSplitVector(SDOperand Op, SDOperand Lo,
+                                      SDOperand Hi) {
   ExpungeNode(Lo);
   ExpungeNode(Hi);
 
@@ -492,7 +536,7 @@
   AnalyzeNewNode(Hi.Val);
 
   // Remember that this is the result of the node.
-  std::pair<SDOperand, SDOperand> &Entry = SplitNodes[Op];
+  std::pair<SDOperand, SDOperand> &Entry = SplitVectors[Op];
   assert(Entry.first.Val == 0 && "Node already split");
   Entry.first = Lo;
   Entry.second = Hi;
@@ -505,11 +549,11 @@
   return DAG.getNode(ISD::BIT_CONVERT, MVT::getIntegerVT(BitWidth), Op);
 }
 
-SDOperand DAGTypeLegalizer::CreateStackStoreLoad(SDOperand Op, 
+SDOperand DAGTypeLegalizer::CreateStackStoreLoad(SDOperand Op,
                                                  MVT DestVT) {
   // Create the stack frame object.
   SDOperand FIPtr = DAG.CreateStackTemporary(DestVT);
-  
+
   // Emit a store to the stack slot.
   SDOperand Store = DAG.getStore(DAG.getEntryNode(), Op, FIPtr, NULL, 0);
   // Result is a load from the stack slot.
@@ -605,6 +649,6 @@
 /// the graph.
 void SelectionDAG::LegalizeTypes() {
   if (ViewLegalizeTypesDAGs) viewGraph();
-  
+
   DAGTypeLegalizer(*this).run();
 }

Modified: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h?rev=52408&r1=52407&r2=52408&view=diff

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.h Tue Jun 17 09:27:01 2008
@@ -47,31 +47,32 @@
     /// ReadyToProcess - All operands have been processed, so this node is ready
     /// to be handled.
     ReadyToProcess = 0,
-    
+
     /// NewNode - This is a new node that was created in the process of
     /// legalizing some other node.
     NewNode = -1,
-    
+
     /// Processed - This is a node that has already been processed.
     Processed = -2
-    
+
     // 1+ - This is a node which has this many unlegalized operands.
   };
 private:
   enum LegalizeAction {
-    Legal,      // The target natively supports this type.
-    Promote,    // This type should be executed in a larger type.
-    Expand,     // This type should be split into two types of half the size.
-    FloatToInt, // Convert a floating point type to an integer of the same size.
-    Scalarize,  // Replace this one-element vector type with its element type.
-    Split       // This vector type should be split into smaller vectors.
+    Legal,          // The target natively supports this type.
+    PromoteInteger, // Replace this integer type with a larger one.
+    ExpandInteger,  // Split this integer type into two of half the size.
+    PromoteFloat,   // Convert this float type to a same size integer type.
+    ExpandFloat,    // Split this float type into two of half the size.
+    Scalarize,      // Replace this one-element vector type with its element type.
+    Split           // This vector type should be split into smaller vectors.
   };
 
   /// ValueTypeActions - This is a bitvector that contains two bits for each
   /// simple value type, where the two bits correspond to the LegalizeAction
   /// enum from TargetLowering.  This can be queried with "getTypeAction(VT)".
   TargetLowering::ValueTypeActionImpl ValueTypeActions;
-  
+
   /// getTypeAction - Return how we should legalize values of this type, either
   /// it is already legal, or we need to promote it to a larger integer type, or
   /// we need to expand it into multiple registers of a smaller integer type, or
@@ -84,16 +85,19 @@
     case TargetLowering::Legal:
       return Legal;
     case TargetLowering::Promote:
-      return Promote;
+      return PromoteInteger;
     case TargetLowering::Expand:
       // Expand can mean
       // 1) split scalar in half, 2) convert a float to an integer,
       // 3) scalarize a single-element vector, 4) split a vector in two.
       if (!VT.isVector()) {
-        if (VT.getSizeInBits() == TLI.getTypeToTransformTo(VT).getSizeInBits())
-          return FloatToInt;
+        if (VT.isInteger())
+          return ExpandInteger;
+        else if (VT.getSizeInBits() ==
+                 TLI.getTypeToTransformTo(VT).getSizeInBits())
+          return PromoteFloat;
         else
-          return Expand;
+          return ExpandFloat;
       } else if (VT.getVectorNumElements() == 1) {
         return Scalarize;
       } else {
@@ -107,26 +111,30 @@
     return ValueTypeActions.getTypeAction(VT) == TargetLowering::Legal;
   }
 
-  /// PromotedNodes - For nodes that are below legal width, this map indicates
-  /// what promoted value to use.
-  DenseMap<SDOperand, SDOperand> PromotedNodes;
-  
-  /// ExpandedNodes - For nodes that need to be expanded this map indicates
-  /// which operands are the expanded version of the input.
-  DenseMap<SDOperand, std::pair<SDOperand, SDOperand> > ExpandedNodes;
+  /// PromotedIntegers - For integer nodes that are below legal width, this map
+  /// indicates what promoted value to use.
+  DenseMap<SDOperand, SDOperand> PromotedIntegers;
+
+  /// ExpandedIntegers - For integer nodes that need to be expanded this map
+  /// indicates which operands are the expanded version of the input.
+  DenseMap<SDOperand, std::pair<SDOperand, SDOperand> > ExpandedIntegers;
 
-  /// FloatToIntedNodes - For floating point nodes converted to integers of
+  /// PromotedFloats - For floating point nodes converted to integers of
   /// the same size, this map indicates the converted value to use.
-  DenseMap<SDOperand, SDOperand> FloatToIntedNodes;
+  DenseMap<SDOperand, SDOperand> PromotedFloats;
+
+  /// ExpandedFloats - For float nodes that need to be expanded this map
+  /// indicates which operands are the expanded version of the input.
+  DenseMap<SDOperand, std::pair<SDOperand, SDOperand> > ExpandedFloats;
 
-  /// ScalarizedNodes - For nodes that are <1 x ty>, this map indicates the
+  /// ScalarizedVectors - For nodes that are <1 x ty>, this map indicates the
   /// scalar value of type 'ty' to use.
-  DenseMap<SDOperand, SDOperand> ScalarizedNodes;
+  DenseMap<SDOperand, SDOperand> ScalarizedVectors;
 
-  /// SplitNodes - For nodes that need to be split this map indicates
+  /// SplitVectors - For nodes that need to be split this map indicates
   /// which operands are the expanded version of the input.
-  DenseMap<SDOperand, std::pair<SDOperand, SDOperand> > SplitNodes;
-  
+  DenseMap<SDOperand, std::pair<SDOperand, SDOperand> > SplitVectors;
+
   /// ReplacedNodes - For nodes that have been replaced with another,
   /// indicates the replacement node to use.
   DenseMap<SDOperand, SDOperand> ReplacedNodes;
@@ -135,17 +143,17 @@
   /// pushed onto this worklist, all operands of a node must have already been
   /// processed.
   SmallVector<SDNode*, 128> Worklist;
-  
+
 public:
   explicit DAGTypeLegalizer(SelectionDAG &dag)
     : TLI(dag.getTargetLoweringInfo()), DAG(dag),
     ValueTypeActions(TLI.getValueTypeActions()) {
     assert(MVT::LAST_VALUETYPE <= 32 &&
            "Too many value types for ValueTypeActions to hold!");
-  }      
-  
+  }
+
   void run();
-  
+
   /// ReanalyzeNode - Recompute the NodeID and correct processed operands
   /// for the specified node, adding it to the worklist if ready.
   void ReanalyzeNode(SDNode *N) {
@@ -183,174 +191,186 @@
                                     SDOperand Index);
 
   //===--------------------------------------------------------------------===//
-  // Promotion Support: LegalizeTypesPromote.cpp
+  // Integer Promotion Support: LegalizeIntegerTypes.cpp
   //===--------------------------------------------------------------------===//
-  
-  SDOperand GetPromotedOp(SDOperand Op) {
-    SDOperand &PromotedOp = PromotedNodes[Op];
+
+  SDOperand GetPromotedInteger(SDOperand Op) {
+    SDOperand &PromotedOp = PromotedIntegers[Op];
     RemapNode(PromotedOp);
     assert(PromotedOp.Val && "Operand wasn't promoted?");
     return PromotedOp;
   }
-  void SetPromotedOp(SDOperand Op, SDOperand Result);
-  
-  /// GetPromotedZExtOp - Get a promoted operand and zero extend it to the final
-  /// size.
-  SDOperand GetPromotedZExtOp(SDOperand Op) {
+  void SetPromotedInteger(SDOperand Op, SDOperand Result);
+
+  /// ZExtPromotedInteger - Get a promoted operand and zero extend it to the
+  /// final size.
+  SDOperand ZExtPromotedInteger(SDOperand Op) {
     MVT OldVT = Op.getValueType();
-    Op = GetPromotedOp(Op);
+    Op = GetPromotedInteger(Op);
     return DAG.getZeroExtendInReg(Op, OldVT);
-  }    
-    
-  // Result Promotion.
-  void PromoteResult(SDNode *N, unsigned ResNo);
-  SDOperand PromoteResult_BIT_CONVERT(SDNode *N);
-  SDOperand PromoteResult_BUILD_PAIR(SDNode *N);
-  SDOperand PromoteResult_Constant(SDNode *N);
-  SDOperand PromoteResult_CTLZ(SDNode *N);
-  SDOperand PromoteResult_CTPOP(SDNode *N);
-  SDOperand PromoteResult_CTTZ(SDNode *N);
-  SDOperand PromoteResult_EXTRACT_VECTOR_ELT(SDNode *N);
-  SDOperand PromoteResult_FP_ROUND(SDNode *N);
-  SDOperand PromoteResult_FP_TO_XINT(SDNode *N);
-  SDOperand PromoteResult_INT_EXTEND(SDNode *N);
-  SDOperand PromoteResult_LOAD(LoadSDNode *N);
-  SDOperand PromoteResult_SDIV(SDNode *N);
-  SDOperand PromoteResult_SELECT   (SDNode *N);
-  SDOperand PromoteResult_SELECT_CC(SDNode *N);
-  SDOperand PromoteResult_SETCC(SDNode *N);
-  SDOperand PromoteResult_SHL(SDNode *N);
-  SDOperand PromoteResult_SimpleIntBinOp(SDNode *N);
-  SDOperand PromoteResult_SRA(SDNode *N);
-  SDOperand PromoteResult_SRL(SDNode *N);
-  SDOperand PromoteResult_TRUNCATE(SDNode *N);
-  SDOperand PromoteResult_UDIV(SDNode *N);
-  SDOperand PromoteResult_UNDEF(SDNode *N);
-
-  // Operand Promotion.
-  bool PromoteOperand(SDNode *N, unsigned OperandNo);
-  SDOperand PromoteOperand_ANY_EXTEND(SDNode *N);
-  SDOperand PromoteOperand_BUILD_PAIR(SDNode *N);
-  SDOperand PromoteOperand_BR_CC(SDNode *N, unsigned OpNo);
-  SDOperand PromoteOperand_BRCOND(SDNode *N, unsigned OpNo);
-  SDOperand PromoteOperand_BUILD_VECTOR(SDNode *N);
-  SDOperand PromoteOperand_FP_EXTEND(SDNode *N);
-  SDOperand PromoteOperand_FP_ROUND(SDNode *N);
-  SDOperand PromoteOperand_INT_TO_FP(SDNode *N);
-  SDOperand PromoteOperand_INSERT_VECTOR_ELT(SDNode *N, unsigned OpNo);
-  SDOperand PromoteOperand_MEMBARRIER(SDNode *N);
-  SDOperand PromoteOperand_RET(SDNode *N, unsigned OpNo);
-  SDOperand PromoteOperand_SELECT(SDNode *N, unsigned OpNo);
-  SDOperand PromoteOperand_SETCC(SDNode *N, unsigned OpNo);
-  SDOperand PromoteOperand_SIGN_EXTEND(SDNode *N);
-  SDOperand PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo);
-  SDOperand PromoteOperand_TRUNCATE(SDNode *N);
-  SDOperand PromoteOperand_ZERO_EXTEND(SDNode *N);
+  }
+
+  // Integer Result Promotion.
+  void PromoteIntegerResult(SDNode *N, unsigned ResNo);
+  SDOperand PromoteIntRes_BIT_CONVERT(SDNode *N);
+  SDOperand PromoteIntRes_BUILD_PAIR(SDNode *N);
+  SDOperand PromoteIntRes_Constant(SDNode *N);
+  SDOperand PromoteIntRes_CTLZ(SDNode *N);
+  SDOperand PromoteIntRes_CTPOP(SDNode *N);
+  SDOperand PromoteIntRes_CTTZ(SDNode *N);
+  SDOperand PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N);
+  SDOperand PromoteIntRes_FP_ROUND(SDNode *N);
+  SDOperand PromoteIntRes_FP_TO_XINT(SDNode *N);
+  SDOperand PromoteIntRes_INT_EXTEND(SDNode *N);
+  SDOperand PromoteIntRes_LOAD(LoadSDNode *N);
+  SDOperand PromoteIntRes_SDIV(SDNode *N);
+  SDOperand PromoteIntRes_SELECT   (SDNode *N);
+  SDOperand PromoteIntRes_SELECT_CC(SDNode *N);
+  SDOperand PromoteIntRes_SETCC(SDNode *N);
+  SDOperand PromoteIntRes_SHL(SDNode *N);
+  SDOperand PromoteIntRes_SimpleIntBinOp(SDNode *N);
+  SDOperand PromoteIntRes_SRA(SDNode *N);
+  SDOperand PromoteIntRes_SRL(SDNode *N);
+  SDOperand PromoteIntRes_TRUNCATE(SDNode *N);
+  SDOperand PromoteIntRes_UDIV(SDNode *N);
+  SDOperand PromoteIntRes_UNDEF(SDNode *N);
+
+  // Integer Operand Promotion.
+  bool PromoteIntegerOperand(SDNode *N, unsigned OperandNo);
+  SDOperand PromoteIntOp_ANY_EXTEND(SDNode *N);
+  SDOperand PromoteIntOp_BUILD_PAIR(SDNode *N);
+  SDOperand PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo);
+  SDOperand PromoteIntOp_BRCOND(SDNode *N, unsigned OpNo);
+  SDOperand PromoteIntOp_BUILD_VECTOR(SDNode *N);
+  SDOperand PromoteIntOp_FP_EXTEND(SDNode *N);
+  SDOperand PromoteIntOp_FP_ROUND(SDNode *N);
+  SDOperand PromoteIntOp_INT_TO_FP(SDNode *N);
+  SDOperand PromoteIntOp_INSERT_VECTOR_ELT(SDNode *N, unsigned OpNo);
+  SDOperand PromoteIntOp_MEMBARRIER(SDNode *N);
+  SDOperand PromoteIntOp_SELECT(SDNode *N, unsigned OpNo);
+  SDOperand PromoteIntOp_SETCC(SDNode *N, unsigned OpNo);
+  SDOperand PromoteIntOp_SIGN_EXTEND(SDNode *N);
+  SDOperand PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo);
+  SDOperand PromoteIntOp_TRUNCATE(SDNode *N);
+  SDOperand PromoteIntOp_ZERO_EXTEND(SDNode *N);
 
   void PromoteSetCCOperands(SDOperand &LHS,SDOperand &RHS, ISD::CondCode Code);
 
   //===--------------------------------------------------------------------===//
-  // Expansion Support: LegalizeTypesExpand.cpp
+  // Integer Expansion Support: LegalizeIntegerTypes.cpp
   //===--------------------------------------------------------------------===//
-  
-  void GetExpandedOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi);
-  void SetExpandedOp(SDOperand Op, SDOperand Lo, SDOperand Hi);
-    
-  // Result Expansion.
-  void ExpandResult(SDNode *N, unsigned ResNo);
-  void ExpandResult_ANY_EXTEND (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_AssertZext (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_BIT_CONVERT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_BUILD_PAIR (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_Constant   (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_CTLZ       (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_CTPOP      (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_CTTZ       (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_EXTRACT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_LOAD       (LoadSDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_MERGE_VALUES(SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_SIGN_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_TRUNCATE   (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_UNDEF      (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_ZERO_EXTEND(SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_FP_TO_SINT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_FP_TO_UINT (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-
-  void ExpandResult_Logical    (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_BSWAP      (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_ADDSUB     (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_ADDSUBC    (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_ADDSUBE    (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_SELECT     (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_SELECT_CC  (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_MUL        (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_SDIV       (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_SREM       (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_UDIV       (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_UREM       (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  void ExpandResult_Shift      (SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  
-  void ExpandShiftByConstant(SDNode *N, unsigned Amt, 
+
+  void GetExpandedInteger(SDOperand Op, SDOperand &Lo, SDOperand &Hi);
+  void SetExpandedInteger(SDOperand Op, SDOperand Lo, SDOperand Hi);
+
+  // Integer Result Expansion.
+  void ExpandIntegerResult(SDNode *N, unsigned ResNo);
+  void ExpandIntRes_ANY_EXTEND        (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_AssertZext        (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_BIT_CONVERT       (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_BUILD_PAIR        (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_Constant          (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_CTLZ              (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_CTPOP             (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_CTTZ              (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_EXTRACT_VECTOR_ELT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_LOAD          (LoadSDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_MERGE_VALUES      (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_SIGN_EXTEND       (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_SIGN_EXTEND_INREG (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_TRUNCATE          (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_UNDEF             (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_ZERO_EXTEND       (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_FP_TO_SINT        (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_FP_TO_UINT        (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+
+  void ExpandIntRes_Logical           (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_BSWAP             (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_ADDSUB            (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_ADDSUBC           (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_ADDSUBE           (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_SELECT            (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_SELECT_CC         (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_MUL               (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_SDIV              (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_SREM              (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_UDIV              (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_UREM              (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+  void ExpandIntRes_Shift             (SDNode *N, SDOperand &Lo, SDOperand &Hi);
+
+  void ExpandShiftByConstant(SDNode *N, unsigned Amt,
                              SDOperand &Lo, SDOperand &Hi);
   bool ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi);
 
-  // Operand Expansion.
-  bool ExpandOperand(SDNode *N, unsigned OperandNo);
-  SDOperand ExpandOperand_BIT_CONVERT(SDNode *N);
-  SDOperand ExpandOperand_BR_CC(SDNode *N);
-  SDOperand ExpandOperand_BUILD_VECTOR(SDNode *N);
-  SDOperand ExpandOperand_EXTRACT_ELEMENT(SDNode *N);
-  SDOperand ExpandOperand_SETCC(SDNode *N);
-  SDOperand ExpandOperand_SINT_TO_FP(SDOperand Source, MVT DestTy);
-  SDOperand ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo);
-  SDOperand ExpandOperand_TRUNCATE(SDNode *N);
-  SDOperand ExpandOperand_UINT_TO_FP(SDOperand Source, MVT DestTy);
+  // Integer Operand Expansion.
+  bool ExpandIntegerOperand(SDNode *N, unsigned OperandNo);
+  SDOperand ExpandIntOp_BIT_CONVERT(SDNode *N);
+  SDOperand ExpandIntOp_BR_CC(SDNode *N);
+  SDOperand ExpandIntOp_BUILD_VECTOR(SDNode *N);
+  SDOperand ExpandIntOp_EXTRACT_ELEMENT(SDNode *N);
+  SDOperand ExpandIntOp_SETCC(SDNode *N);
+  SDOperand ExpandIntOp_SINT_TO_FP(SDOperand Source, MVT DestTy);
+  SDOperand ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo);
+  SDOperand ExpandIntOp_TRUNCATE(SDNode *N);
+  SDOperand ExpandIntOp_UINT_TO_FP(SDOperand Source, MVT DestTy);
 
   void ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
                            ISD::CondCode &CCCode);
-  
+
   //===--------------------------------------------------------------------===//
-  // Float to Integer Conversion Support: LegalizeTypesFloatToInt.cpp
+  // Float to Integer Conversion Support: LegalizeFloatTypes.cpp
   //===--------------------------------------------------------------------===//
 
-  SDOperand GetIntegerOp(SDOperand Op) {
-    SDOperand &IntegerOp = FloatToIntedNodes[Op];
-    RemapNode(IntegerOp);
-    assert(IntegerOp.Val && "Operand wasn't converted to integer?");
-    return IntegerOp;
+  SDOperand GetPromotedFloat(SDOperand Op) {
+    SDOperand &PromotedOp = PromotedFloats[Op];
+    RemapNode(PromotedOp);
+    assert(PromotedOp.Val && "Operand wasn't converted to integer?");
+    return PromotedOp;
   }
-  void SetIntegerOp(SDOperand Op, SDOperand Result);
+  void SetPromotedFloat(SDOperand Op, SDOperand Result);
 
   // Result Float to Integer Conversion.
-  void FloatToIntResult(SDNode *N, unsigned OpNo);
-  SDOperand FloatToIntRes_BIT_CONVERT(SDNode *N);
-  SDOperand FloatToIntRes_BUILD_PAIR(SDNode *N);
-  SDOperand FloatToIntRes_ConstantFP(ConstantFPSDNode *N);
-  SDOperand FloatToIntRes_FADD(SDNode *N);
-  SDOperand FloatToIntRes_FCOPYSIGN(SDNode *N);
-  SDOperand FloatToIntRes_FMUL(SDNode *N);
-  SDOperand FloatToIntRes_FSUB(SDNode *N);
-  SDOperand FloatToIntRes_LOAD(SDNode *N);
-  SDOperand FloatToIntRes_XINT_TO_FP(SDNode *N);
+  void PromoteFloatResult(SDNode *N, unsigned OpNo);
+  SDOperand PromoteFloatRes_BIT_CONVERT(SDNode *N);
+  SDOperand PromoteFloatRes_BUILD_PAIR(SDNode *N);
+  SDOperand PromoteFloatRes_ConstantFP(ConstantFPSDNode *N);
+  SDOperand PromoteFloatRes_FADD(SDNode *N);
+  SDOperand PromoteFloatRes_FCOPYSIGN(SDNode *N);
+  SDOperand PromoteFloatRes_FMUL(SDNode *N);
+  SDOperand PromoteFloatRes_FSUB(SDNode *N);
+  SDOperand PromoteFloatRes_LOAD(SDNode *N);
+  SDOperand PromoteFloatRes_XINT_TO_FP(SDNode *N);
 
   // Operand Float to Integer Conversion.
-  bool FloatToIntOperand(SDNode *N, unsigned OpNo);
-  SDOperand FloatToIntOp_BIT_CONVERT(SDNode *N);
+  bool PromoteFloatOperand(SDNode *N, unsigned OpNo);
+  SDOperand PromoteFloatOp_BIT_CONVERT(SDNode *N);
+
+  //===--------------------------------------------------------------------===//
+  // Float Expansion Support: LegalizeFloatTypes.cpp
+  //===--------------------------------------------------------------------===//
+
+  void GetExpandedFloat(SDOperand Op, SDOperand &Lo, SDOperand &Hi);
+  void SetExpandedFloat(SDOperand Op, SDOperand Lo, SDOperand Hi);
+
+  // Float Result Expansion.
+  void ExpandFloatResult(SDNode *N, unsigned ResNo);
+
+  // Float Operand Expansion.
+  bool ExpandFloatOperand(SDNode *N, unsigned OperandNo);
 
   //===--------------------------------------------------------------------===//
-  // Scalarization Support: LegalizeTypesScalarize.cpp
+  // Scalarization Support: LegalizeVectorTypes.cpp
   //===--------------------------------------------------------------------===//
-  
-  SDOperand GetScalarizedOp(SDOperand Op) {
-    SDOperand &ScalarOp = ScalarizedNodes[Op];
-    RemapNode(ScalarOp);
-    assert(ScalarOp.Val && "Operand wasn't scalarized?");
-    return ScalarOp;
+
+  SDOperand GetScalarizedVector(SDOperand Op) {
+    SDOperand &ScalarizedOp = ScalarizedVectors[Op];
+    RemapNode(ScalarizedOp);
+    assert(ScalarizedOp.Val && "Operand wasn't scalarized?");
+    return ScalarizedOp;
   }
-  void SetScalarizedOp(SDOperand Op, SDOperand Result);
-    
-  // Result Vector Scalarization: <1 x ty> -> ty.
+  void SetScalarizedVector(SDOperand Op, SDOperand Result);
+
+  // Vector Result Scalarization: <1 x ty> -> ty.
   void ScalarizeResult(SDNode *N, unsigned OpNo);
   SDOperand ScalarizeRes_BinOp(SDNode *N);
   SDOperand ScalarizeRes_UnaryOp(SDNode *N);
@@ -363,20 +383,20 @@
   SDOperand ScalarizeRes_UNDEF(SDNode *N);
   SDOperand ScalarizeRes_VECTOR_SHUFFLE(SDNode *N);
 
-  // Operand Vector Scalarization: <1 x ty> -> ty.
+  // Vector Operand Scalarization: <1 x ty> -> ty.
   bool ScalarizeOperand(SDNode *N, unsigned OpNo);
   SDOperand ScalarizeOp_BIT_CONVERT(SDNode *N);
   SDOperand ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N);
   SDOperand ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo);
 
   //===--------------------------------------------------------------------===//
-  // Vector Splitting Support: LegalizeTypesSplit.cpp
+  // Vector Splitting Support: LegalizeVectorTypes.cpp
   //===--------------------------------------------------------------------===//
-  
-  void GetSplitOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi);
-  void SetSplitOp(SDOperand Op, SDOperand Lo, SDOperand Hi);
-  
-  // Result Vector Splitting: <128 x ty> -> 2 x <64 x ty>.
+
+  void GetSplitVector(SDOperand Op, SDOperand &Lo, SDOperand &Hi);
+  void SetSplitVector(SDOperand Op, SDOperand Lo, SDOperand Hi);
+
+  // Vector Result Splitting: <128 x ty> -> 2 x <64 x ty>.
   void SplitResult(SDNode *N, unsigned OpNo);
 
   void SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi);
@@ -392,8 +412,8 @@
   void SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi);
   void SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi);
   void SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi);
-  
-  // Operand Vector Splitting: <128 x ty> -> 2 x <64 x ty>.
+
+  // Vector Operand Splitting: <128 x ty> -> 2 x <64 x ty>.
   bool SplitOperand(SDNode *N, unsigned OpNo);
 
   SDOperand SplitOp_BIT_CONVERT(SDNode *N);

Removed: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp?rev=52407&view=auto

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp (removed)
@@ -1,1465 +0,0 @@
-//===-- LegalizeTypesExpand.cpp - Expansion for LegalizeTypes -------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements expansion support for LegalizeTypes.  Expansion is the
-// act of changing a computation in an invalid type to be a computation in
-// multiple registers of a smaller type.  For example, implementing i64
-// arithmetic in two i32 registers (as is often needed on 32-bit targets, for
-// example).
-//
-//===----------------------------------------------------------------------===//
-
-#include "LegalizeTypes.h"
-#include "llvm/Constants.h"
-using namespace llvm;
-
-//===----------------------------------------------------------------------===//
-//  Result Expansion
-//===----------------------------------------------------------------------===//
-
-/// ExpandResult - This method is called when the specified result of the
-/// specified node is found to need expansion.  At this point, the node may also
-/// have invalid operands or may have other results that need promotion, we just
-/// know that (at least) one result needs expansion.
-void DAGTypeLegalizer::ExpandResult(SDNode *N, unsigned ResNo) {
-  DEBUG(cerr << "Expand node result: "; N->dump(&DAG); cerr << "\n");
-  SDOperand Lo, Hi;
-  Lo = Hi = SDOperand();
-
-  // See if the target wants to custom expand this node.
-  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == 
-          TargetLowering::Custom) {
-    // If the target wants to, allow it to lower this itself.
-    if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
-      // Everything that once used N now uses P.  We are guaranteed that the
-      // result value types of N and the result value types of P match.
-      ReplaceNodeWith(N, P);
-      return;
-    }
-  }
-
-  switch (N->getOpcode()) {
-  default:
-#ifndef NDEBUG
-    cerr << "ExpandResult #" << ResNo << ": ";
-    N->dump(&DAG); cerr << "\n";
-#endif
-    assert(0 && "Do not know how to expand the result of this operator!");
-    abort();
-      
-  case ISD::UNDEF:       ExpandResult_UNDEF(N, Lo, Hi); break;
-  case ISD::Constant:    ExpandResult_Constant(N, Lo, Hi); break;
-  case ISD::BUILD_PAIR:  ExpandResult_BUILD_PAIR(N, Lo, Hi); break;
-  case ISD::MERGE_VALUES: ExpandResult_MERGE_VALUES(N, Lo, Hi); break;
-  case ISD::ANY_EXTEND:  ExpandResult_ANY_EXTEND(N, Lo, Hi); break;
-  case ISD::ZERO_EXTEND: ExpandResult_ZERO_EXTEND(N, Lo, Hi); break;
-  case ISD::SIGN_EXTEND: ExpandResult_SIGN_EXTEND(N, Lo, Hi); break;
-  case ISD::AssertZext:  ExpandResult_AssertZext(N, Lo, Hi); break;
-  case ISD::TRUNCATE:    ExpandResult_TRUNCATE(N, Lo, Hi); break;
-  case ISD::BIT_CONVERT: ExpandResult_BIT_CONVERT(N, Lo, Hi); break;
-  case ISD::SIGN_EXTEND_INREG: ExpandResult_SIGN_EXTEND_INREG(N, Lo, Hi); break;
-  case ISD::FP_TO_SINT:  ExpandResult_FP_TO_SINT(N, Lo, Hi); break;
-  case ISD::FP_TO_UINT:  ExpandResult_FP_TO_UINT(N, Lo, Hi); break;
-  case ISD::LOAD:        ExpandResult_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
-    
-  case ISD::AND:
-  case ISD::OR:
-  case ISD::XOR:         ExpandResult_Logical(N, Lo, Hi); break;
-  case ISD::BSWAP:       ExpandResult_BSWAP(N, Lo, Hi); break;
-  case ISD::ADD:
-  case ISD::SUB:         ExpandResult_ADDSUB(N, Lo, Hi); break;
-  case ISD::ADDC:
-  case ISD::SUBC:        ExpandResult_ADDSUBC(N, Lo, Hi); break;
-  case ISD::ADDE:
-  case ISD::SUBE:        ExpandResult_ADDSUBE(N, Lo, Hi); break;
-  case ISD::SELECT:      ExpandResult_SELECT(N, Lo, Hi); break;
-  case ISD::SELECT_CC:   ExpandResult_SELECT_CC(N, Lo, Hi); break;
-  case ISD::MUL:         ExpandResult_MUL(N, Lo, Hi); break;
-  case ISD::SDIV:        ExpandResult_SDIV(N, Lo, Hi); break;
-  case ISD::SREM:        ExpandResult_SREM(N, Lo, Hi); break;
-  case ISD::UDIV:        ExpandResult_UDIV(N, Lo, Hi); break;
-  case ISD::UREM:        ExpandResult_UREM(N, Lo, Hi); break;
-  case ISD::SHL:
-  case ISD::SRA:
-  case ISD::SRL:         ExpandResult_Shift(N, Lo, Hi); break;
-
-  case ISD::CTLZ:        ExpandResult_CTLZ(N, Lo, Hi); break;
-  case ISD::CTPOP:       ExpandResult_CTPOP(N, Lo, Hi); break;
-  case ISD::CTTZ:        ExpandResult_CTTZ(N, Lo, Hi); break;
-
-  case ISD::EXTRACT_VECTOR_ELT:
-    ExpandResult_EXTRACT_VECTOR_ELT(N, Lo, Hi);
-    break;
-  }
-
-  // If Lo/Hi is null, the sub-method took care of registering results etc.
-  if (Lo.Val)
-    SetExpandedOp(SDOperand(N, ResNo), Lo, Hi);
-}
-
-void DAGTypeLegalizer::ExpandResult_UNDEF(SDNode *N,
-                                          SDOperand &Lo, SDOperand &Hi) {
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-  Lo = Hi = DAG.getNode(ISD::UNDEF, NVT);
-}
-
-void DAGTypeLegalizer::ExpandResult_Constant(SDNode *N,
-                                             SDOperand &Lo, SDOperand &Hi) {
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-  unsigned NBitWidth = NVT.getSizeInBits();
-  const APInt &Cst = cast<ConstantSDNode>(N)->getAPIntValue();
-  Lo = DAG.getConstant(APInt(Cst).trunc(NBitWidth), NVT);
-  Hi = DAG.getConstant(Cst.lshr(NBitWidth).trunc(NBitWidth), NVT);
-}
-
-void DAGTypeLegalizer::ExpandResult_BUILD_PAIR(SDNode *N,
-                                               SDOperand &Lo, SDOperand &Hi) {
-  // Return the operands.
-  Lo = N->getOperand(0);
-  Hi = N->getOperand(1);
-}
-
-void DAGTypeLegalizer::ExpandResult_MERGE_VALUES(SDNode *N,
-                                                 SDOperand &Lo, SDOperand &Hi) {
-  // A MERGE_VALUES node can produce any number of values.  We know that the
-  // first illegal one needs to be expanded into Lo/Hi.
-  unsigned i;
-  
-  // The string of legal results gets turns into the input operands, which have
-  // the same type.
-  for (i = 0; isTypeLegal(N->getValueType(i)); ++i)
-    ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i)));
-
-  // The first illegal result must be the one that needs to be expanded.
-  GetExpandedOp(N->getOperand(i), Lo, Hi);
-
-  // Legalize the rest of the results into the input operands whether they are
-  // legal or not.
-  unsigned e = N->getNumValues();
-  for (++i; i != e; ++i)
-    ReplaceValueWith(SDOperand(N, i), SDOperand(N->getOperand(i)));
-}
-
-void DAGTypeLegalizer::ExpandResult_ANY_EXTEND(SDNode *N,
-                                               SDOperand &Lo, SDOperand &Hi) {
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-  SDOperand Op = N->getOperand(0);
-  if (Op.getValueType().bitsLE(NVT)) {
-    // The low part is any extension of the input (which degenerates to a copy).
-    Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, Op);
-    Hi = DAG.getNode(ISD::UNDEF, NVT);   // The high part is undefined.
-  } else {
-    // For example, extension of an i48 to an i64.  The operand type necessarily
-    // promotes to the result type, so will end up being expanded too.
-    assert(getTypeAction(Op.getValueType()) == Promote &&
-           "Only know how to promote this result!");
-    SDOperand Res = GetPromotedOp(Op);
-    assert(Res.getValueType() == N->getValueType(0) &&
-           "Operand over promoted?");
-    // Split the promoted operand.  This will simplify when it is expanded.
-    SplitInteger(Res, Lo, Hi);
-  }
-}
-
-void DAGTypeLegalizer::ExpandResult_ZERO_EXTEND(SDNode *N,
-                                                SDOperand &Lo, SDOperand &Hi) {
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-  SDOperand Op = N->getOperand(0);
-  if (Op.getValueType().bitsLE(NVT)) {
-    // The low part is zero extension of the input (which degenerates to a copy).
-    Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, N->getOperand(0));
-    Hi = DAG.getConstant(0, NVT);   // The high part is just a zero.
-  } else {
-    // For example, extension of an i48 to an i64.  The operand type necessarily
-    // promotes to the result type, so will end up being expanded too.
-    assert(getTypeAction(Op.getValueType()) == Promote &&
-           "Only know how to promote this result!");
-    SDOperand Res = GetPromotedOp(Op);
-    assert(Res.getValueType() == N->getValueType(0) &&
-           "Operand over promoted?");
-    // Split the promoted operand.  This will simplify when it is expanded.
-    SplitInteger(Res, Lo, Hi);
-    unsigned ExcessBits =
-      Op.getValueType().getSizeInBits() - NVT.getSizeInBits();
-    Hi = DAG.getZeroExtendInReg(Hi, MVT::getIntegerVT(ExcessBits));
-  }
-}
-
-void DAGTypeLegalizer::ExpandResult_SIGN_EXTEND(SDNode *N,
-                                                SDOperand &Lo, SDOperand &Hi) {
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-  SDOperand Op = N->getOperand(0);
-  if (Op.getValueType().bitsLE(NVT)) {
-    // The low part is sign extension of the input (which degenerates to a copy).
-    Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, N->getOperand(0));
-    // The high part is obtained by SRA'ing all but one of the bits of low part.
-    unsigned LoSize = NVT.getSizeInBits();
-    Hi = DAG.getNode(ISD::SRA, NVT, Lo,
-                     DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
-  } else {
-    // For example, extension of an i48 to an i64.  The operand type necessarily
-    // promotes to the result type, so will end up being expanded too.
-    assert(getTypeAction(Op.getValueType()) == Promote &&
-           "Only know how to promote this result!");
-    SDOperand Res = GetPromotedOp(Op);
-    assert(Res.getValueType() == N->getValueType(0) &&
-           "Operand over promoted?");
-    // Split the promoted operand.  This will simplify when it is expanded.
-    SplitInteger(Res, Lo, Hi);
-    unsigned ExcessBits =
-      Op.getValueType().getSizeInBits() - NVT.getSizeInBits();
-    Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi,
-                     DAG.getValueType(MVT::getIntegerVT(ExcessBits)));
-  }
-}
-
-void DAGTypeLegalizer::ExpandResult_AssertZext(SDNode *N,
-                                               SDOperand &Lo, SDOperand &Hi) {
-  GetExpandedOp(N->getOperand(0), Lo, Hi);
-  MVT NVT = Lo.getValueType();
-  MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
-  unsigned NVTBits = NVT.getSizeInBits();
-  unsigned EVTBits = EVT.getSizeInBits();
-
-  if (NVTBits < EVTBits) {
-    Hi = DAG.getNode(ISD::AssertZext, NVT, Hi,
-                     DAG.getValueType(MVT::getIntegerVT(EVTBits - NVTBits)));
-  } else {
-    Lo = DAG.getNode(ISD::AssertZext, NVT, Lo, DAG.getValueType(EVT));
-    // The high part must be zero, make it explicit.
-    Hi = DAG.getConstant(0, NVT);
-  }
-}
-
-void DAGTypeLegalizer::ExpandResult_TRUNCATE(SDNode *N,
-                                             SDOperand &Lo, SDOperand &Hi) {
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-  Lo = DAG.getNode(ISD::TRUNCATE, NVT, N->getOperand(0));
-  Hi = DAG.getNode(ISD::SRL, N->getOperand(0).getValueType(), N->getOperand(0),
-                   DAG.getConstant(NVT.getSizeInBits(),
-                                   TLI.getShiftAmountTy()));
-  Hi = DAG.getNode(ISD::TRUNCATE, NVT, Hi);
-}
-
-void DAGTypeLegalizer::ExpandResult_BIT_CONVERT(SDNode *N,
-                                                SDOperand &Lo, SDOperand &Hi) {
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-  SDOperand InOp = N->getOperand(0);
-  MVT InVT = InOp.getValueType();
-
-  // Handle some special cases efficiently.
-  switch (getTypeAction(InVT)) {
-    default:
-      assert(false && "Unknown type action!");
-    case Legal:
-    case Promote:
-      break;
-    case Expand:
-      // Convert the expanded pieces of the input.
-      GetExpandedOp(InOp, Lo, Hi);
-      Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
-      Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
-      return;
-    case FloatToInt:
-      // Convert the integer operand instead.
-      SplitInteger(GetIntegerOp(InOp), Lo, Hi);
-      Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
-      Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
-      return;
-    case Split:
-      // Convert the split parts of the input if it was split in two.
-      GetSplitOp(InOp, Lo, Hi);
-      if (Lo.getValueType() == Hi.getValueType()) {
-        if (TLI.isBigEndian())
-          std::swap(Lo, Hi);
-        Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
-        Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
-        return;
-      }
-      break;
-    case Scalarize:
-      // Convert the element instead.
-      SplitInteger(BitConvertToInteger(GetScalarizedOp(InOp)), Lo, Hi);
-      Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Lo);
-      Hi = DAG.getNode(ISD::BIT_CONVERT, NVT, Hi);
-      return;
-  }
-
-  // Lower the bit-convert to a store/load from the stack, then expand the load.
-  SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
-  ExpandResult_LOAD(cast<LoadSDNode>(Op.Val), Lo, Hi);
-}
-
-void DAGTypeLegalizer::
-ExpandResult_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
-  GetExpandedOp(N->getOperand(0), Lo, Hi);
-  MVT EVT = cast<VTSDNode>(N->getOperand(1))->getVT();
-
-  if (EVT.bitsLE(Lo.getValueType())) {
-    // sext_inreg the low part if needed.
-    Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, Lo.getValueType(), Lo,
-                     N->getOperand(1));
-
-    // The high part gets the sign extension from the lo-part.  This handles
-    // things like sextinreg V:i64 from i8.
-    Hi = DAG.getNode(ISD::SRA, Hi.getValueType(), Lo,
-                     DAG.getConstant(Hi.getValueType().getSizeInBits()-1,
-                                     TLI.getShiftAmountTy()));
-  } else {
-    // For example, extension of an i48 to an i64.  Leave the low part alone,
-    // sext_inreg the high part.
-    unsigned ExcessBits =
-      EVT.getSizeInBits() - Lo.getValueType().getSizeInBits();
-    Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi,
-                     DAG.getValueType(MVT::getIntegerVT(ExcessBits)));
-  }
-}
-
-void DAGTypeLegalizer::ExpandResult_FP_TO_SINT(SDNode *N, SDOperand &Lo,
-                                               SDOperand &Hi) {
-  MVT VT = N->getValueType(0);
-  SDOperand Op = N->getOperand(0);
-  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
-  if (VT == MVT::i64) {
-    if (Op.getValueType() == MVT::f32)
-      LC = RTLIB::FPTOSINT_F32_I64;
-    else if (Op.getValueType() == MVT::f64)
-      LC = RTLIB::FPTOSINT_F64_I64;
-    else if (Op.getValueType() == MVT::f80)
-      LC = RTLIB::FPTOSINT_F80_I64;
-    else if (Op.getValueType() == MVT::ppcf128)
-      LC = RTLIB::FPTOSINT_PPCF128_I64;
-  } else if (VT == MVT::i128) {
-    if (Op.getValueType() == MVT::f32)
-      LC = RTLIB::FPTOSINT_F32_I128;
-    else if (Op.getValueType() == MVT::f64)
-      LC = RTLIB::FPTOSINT_F64_I128;
-    else if (Op.getValueType() == MVT::f80)
-      LC = RTLIB::FPTOSINT_F80_I128;
-    else if (Op.getValueType() == MVT::ppcf128)
-      LC = RTLIB::FPTOSINT_PPCF128_I128;
-  } else {
-    assert(0 && "Unexpected fp-to-sint conversion!");
-  }
-  SplitInteger(MakeLibCall(LC, VT, &Op, 1, true/*sign irrelevant*/), Lo, Hi);
-}
-
-void DAGTypeLegalizer::ExpandResult_FP_TO_UINT(SDNode *N, SDOperand &Lo,
-                                               SDOperand &Hi) {
-  MVT VT = N->getValueType(0);
-  SDOperand Op = N->getOperand(0);
-  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
-  if (VT == MVT::i64) {
-    if (Op.getValueType() == MVT::f32)
-      LC = RTLIB::FPTOUINT_F32_I64;
-    else if (Op.getValueType() == MVT::f64)
-      LC = RTLIB::FPTOUINT_F64_I64;
-    else if (Op.getValueType() == MVT::f80)
-      LC = RTLIB::FPTOUINT_F80_I64;
-    else if (Op.getValueType() == MVT::ppcf128)
-      LC = RTLIB::FPTOUINT_PPCF128_I64;
-  } else if (VT == MVT::i128) {
-    if (Op.getValueType() == MVT::f32)
-      LC = RTLIB::FPTOUINT_F32_I128;
-    else if (Op.getValueType() == MVT::f64)
-      LC = RTLIB::FPTOUINT_F64_I128;
-    else if (Op.getValueType() == MVT::f80)
-      LC = RTLIB::FPTOUINT_F80_I128;
-    else if (Op.getValueType() == MVT::ppcf128)
-      LC = RTLIB::FPTOUINT_PPCF128_I128;
-  } else {
-    assert(0 && "Unexpected fp-to-uint conversion!");
-  }
-  SplitInteger(MakeLibCall(LC, VT, &Op, 1, false/*sign irrelevant*/), Lo, Hi);
-}
-
-void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N,
-                                         SDOperand &Lo, SDOperand &Hi) {
-  // FIXME: Add support for indexed loads.
-  MVT VT = N->getValueType(0);
-  MVT NVT = TLI.getTypeToTransformTo(VT);
-  SDOperand Ch  = N->getChain();    // Legalize the chain.
-  SDOperand Ptr = N->getBasePtr();  // Legalize the pointer.
-  ISD::LoadExtType ExtType = N->getExtensionType();
-  int SVOffset = N->getSrcValueOffset();
-  unsigned Alignment = N->getAlignment();
-  bool isVolatile = N->isVolatile();
-
-  assert(!(NVT.getSizeInBits() & 7) && "Expanded type not byte sized!");
-
-  if (ExtType == ISD::NON_EXTLOAD) {
-    Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
-                     isVolatile, Alignment);
-    // Increment the pointer to the other half.
-    unsigned IncrementSize = NVT.getSizeInBits()/8;
-    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                      DAG.getIntPtrConstant(IncrementSize));
-    Hi = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
-                     isVolatile, MinAlign(Alignment, IncrementSize));
-
-    // Build a factor node to remember that this load is independent of the
-    // other one.
-    Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
-                     Hi.getValue(1));
-
-    // Handle endianness of the load.
-    if (TLI.isBigEndian())
-      std::swap(Lo, Hi);
-  } else if (N->getMemoryVT().bitsLE(NVT)) {
-    MVT EVT = N->getMemoryVT();
-
-    Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, EVT,
-                        isVolatile, Alignment);
-
-    // Remember the chain.
-    Ch = Lo.getValue(1);
-
-    if (ExtType == ISD::SEXTLOAD) {
-      // The high part is obtained by SRA'ing all but one of the bits of the
-      // lo part.
-      unsigned LoSize = Lo.getValueType().getSizeInBits();
-      Hi = DAG.getNode(ISD::SRA, NVT, Lo,
-                       DAG.getConstant(LoSize-1, TLI.getShiftAmountTy()));
-    } else if (ExtType == ISD::ZEXTLOAD) {
-      // The high part is just a zero.
-      Hi = DAG.getConstant(0, NVT);
-    } else {
-      assert(ExtType == ISD::EXTLOAD && "Unknown extload!");
-      // The high part is undefined.
-      Hi = DAG.getNode(ISD::UNDEF, NVT);
-    }
-  } else if (TLI.isLittleEndian()) {
-    // Little-endian - low bits are at low addresses.
-    Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
-                     isVolatile, Alignment);
-
-    unsigned ExcessBits =
-      N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
-    MVT NEVT = MVT::getIntegerVT(ExcessBits);
-
-    // Increment the pointer to the other half.
-    unsigned IncrementSize = NVT.getSizeInBits()/8;
-    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                      DAG.getIntPtrConstant(IncrementSize));
-    Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(),
-                        SVOffset+IncrementSize, NEVT,
-                        isVolatile, MinAlign(Alignment, IncrementSize));
-
-    // Build a factor node to remember that this load is independent of the
-    // other one.
-    Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
-                     Hi.getValue(1));
-  } else {
-    // Big-endian - high bits are at low addresses.  Favor aligned loads at
-    // the cost of some bit-fiddling.
-    MVT EVT = N->getMemoryVT();
-    unsigned EBytes = EVT.getStoreSizeInBits()/8;
-    unsigned IncrementSize = NVT.getSizeInBits()/8;
-    unsigned ExcessBits = (EBytes - IncrementSize)*8;
-
-    // Load both the high bits and maybe some of the low bits.
-    Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset,
-                        MVT::getIntegerVT(EVT.getSizeInBits() - ExcessBits),
-                        isVolatile, Alignment);
-
-    // Increment the pointer to the other half.
-    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                      DAG.getIntPtrConstant(IncrementSize));
-    // Load the rest of the low bits.
-    Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Ch, Ptr, N->getSrcValue(),
-                        SVOffset+IncrementSize,
-                        MVT::getIntegerVT(ExcessBits),
-                        isVolatile, MinAlign(Alignment, IncrementSize));
-
-    // Build a factor node to remember that this load is independent of the
-    // other one.
-    Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1),
-                     Hi.getValue(1));
-
-    if (ExcessBits < NVT.getSizeInBits()) {
-      // Transfer low bits from the bottom of Hi to the top of Lo.
-      Lo = DAG.getNode(ISD::OR, NVT, Lo,
-                       DAG.getNode(ISD::SHL, NVT, Hi,
-                                   DAG.getConstant(ExcessBits,
-                                                   TLI.getShiftAmountTy())));
-      // Move high bits to the right position in Hi.
-      Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, NVT, Hi,
-                       DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
-                                       TLI.getShiftAmountTy()));
-    }
-  }
-
-  // Legalized the chain result - switch anything that used the old chain to
-  // use the new one.
-  ReplaceValueWith(SDOperand(N, 1), Ch);
-}
-
-void DAGTypeLegalizer::ExpandResult_Logical(SDNode *N,
-                                            SDOperand &Lo, SDOperand &Hi) {
-  SDOperand LL, LH, RL, RH;
-  GetExpandedOp(N->getOperand(0), LL, LH);
-  GetExpandedOp(N->getOperand(1), RL, RH);
-  Lo = DAG.getNode(N->getOpcode(), LL.getValueType(), LL, RL);
-  Hi = DAG.getNode(N->getOpcode(), LL.getValueType(), LH, RH);
-}
-
-void DAGTypeLegalizer::ExpandResult_BSWAP(SDNode *N,
-                                          SDOperand &Lo, SDOperand &Hi) {
-  GetExpandedOp(N->getOperand(0), Hi, Lo);  // Note swapped operands.
-  Lo = DAG.getNode(ISD::BSWAP, Lo.getValueType(), Lo);
-  Hi = DAG.getNode(ISD::BSWAP, Hi.getValueType(), Hi);
-}
-
-void DAGTypeLegalizer::ExpandResult_SELECT(SDNode *N,
-                                           SDOperand &Lo, SDOperand &Hi) {
-  SDOperand LL, LH, RL, RH;
-  GetExpandedOp(N->getOperand(1), LL, LH);
-  GetExpandedOp(N->getOperand(2), RL, RH);
-  Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LL, RL);
-  Hi = DAG.getNode(ISD::SELECT, LL.getValueType(), N->getOperand(0), LH, RH);
-}
-
-void DAGTypeLegalizer::ExpandResult_SELECT_CC(SDNode *N,
-                                              SDOperand &Lo, SDOperand &Hi) {
-  SDOperand LL, LH, RL, RH;
-  GetExpandedOp(N->getOperand(2), LL, LH);
-  GetExpandedOp(N->getOperand(3), RL, RH);
-  Lo = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0), 
-                   N->getOperand(1), LL, RL, N->getOperand(4));
-  Hi = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0), 
-                   N->getOperand(1), LH, RH, N->getOperand(4));
-}
-
-void DAGTypeLegalizer::ExpandResult_ADDSUB(SDNode *N,
-                                           SDOperand &Lo, SDOperand &Hi) {
-  // Expand the subcomponents.
-  SDOperand LHSL, LHSH, RHSL, RHSH;
-  GetExpandedOp(N->getOperand(0), LHSL, LHSH);
-  GetExpandedOp(N->getOperand(1), RHSL, RHSH);
-  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
-  SDOperand LoOps[2] = { LHSL, RHSL };
-  SDOperand HiOps[3] = { LHSH, RHSH };
-
-  if (N->getOpcode() == ISD::ADD) {
-    Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
-    HiOps[2] = Lo.getValue(1);
-    Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3);
-  } else {
-    Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2);
-    HiOps[2] = Lo.getValue(1);
-    Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3);
-  }
-}
-
-void DAGTypeLegalizer::ExpandResult_ADDSUBC(SDNode *N,
-                                            SDOperand &Lo, SDOperand &Hi) {
-  // Expand the subcomponents.
-  SDOperand LHSL, LHSH, RHSL, RHSH;
-  GetExpandedOp(N->getOperand(0), LHSL, LHSH);
-  GetExpandedOp(N->getOperand(1), RHSL, RHSH);
-  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
-  SDOperand LoOps[2] = { LHSL, RHSL };
-  SDOperand HiOps[3] = { LHSH, RHSH };
-
-  if (N->getOpcode() == ISD::ADDC) {
-    Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
-    HiOps[2] = Lo.getValue(1);
-    Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3);
-  } else {
-    Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2);
-    HiOps[2] = Lo.getValue(1);
-    Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3);
-  }
-
-  // Legalized the flag result - switch anything that used the old flag to
-  // use the new one.
-  ReplaceValueWith(SDOperand(N, 1), Hi.getValue(1));
-}
-
-void DAGTypeLegalizer::ExpandResult_ADDSUBE(SDNode *N,
-                                            SDOperand &Lo, SDOperand &Hi) {
-  // Expand the subcomponents.
-  SDOperand LHSL, LHSH, RHSL, RHSH;
-  GetExpandedOp(N->getOperand(0), LHSL, LHSH);
-  GetExpandedOp(N->getOperand(1), RHSL, RHSH);
-  SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag);
-  SDOperand LoOps[3] = { LHSL, RHSL, N->getOperand(2) };
-  SDOperand HiOps[3] = { LHSH, RHSH };
-
-  Lo = DAG.getNode(N->getOpcode(), VTList, LoOps, 3);
-  HiOps[2] = Lo.getValue(1);
-  Hi = DAG.getNode(N->getOpcode(), VTList, HiOps, 3);
-
-  // Legalized the flag result - switch anything that used the old flag to
-  // use the new one.
-  ReplaceValueWith(SDOperand(N, 1), Hi.getValue(1));
-}
-
-void DAGTypeLegalizer::ExpandResult_MUL(SDNode *N,
-                                        SDOperand &Lo, SDOperand &Hi) {
-  MVT VT = N->getValueType(0);
-  MVT NVT = TLI.getTypeToTransformTo(VT);
-  
-  bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, NVT);
-  bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, NVT);
-  bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, NVT);
-  bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, NVT);
-  if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) {
-    SDOperand LL, LH, RL, RH;
-    GetExpandedOp(N->getOperand(0), LL, LH);
-    GetExpandedOp(N->getOperand(1), RL, RH);
-    unsigned OuterBitSize = VT.getSizeInBits();
-    unsigned BitSize = NVT.getSizeInBits();
-    unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
-    unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
-    
-    if (DAG.MaskedValueIsZero(N->getOperand(0),
-                              APInt::getHighBitsSet(OuterBitSize, LHSSB)) &&
-        DAG.MaskedValueIsZero(N->getOperand(1),
-                              APInt::getHighBitsSet(OuterBitSize, RHSSB))) {
-      // The inputs are both zero-extended.
-      if (HasUMUL_LOHI) {
-        // We can emit a umul_lohi.
-        Lo = DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL);
-        Hi = SDOperand(Lo.Val, 1);
-        return;
-      }
-      if (HasMULHU) {
-        // We can emit a mulhu+mul.
-        Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
-        Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL);
-        return;
-      }
-    }
-    if (LHSSB > BitSize && RHSSB > BitSize) {
-      // The input values are both sign-extended.
-      if (HasSMUL_LOHI) {
-        // We can emit a smul_lohi.
-        Lo = DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL);
-        Hi = SDOperand(Lo.Val, 1);
-        return;
-      }
-      if (HasMULHS) {
-        // We can emit a mulhs+mul.
-        Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
-        Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL);
-        return;
-      }
-    }
-    if (HasUMUL_LOHI) {
-      // Lo,Hi = umul LHS, RHS.
-      SDOperand UMulLOHI = DAG.getNode(ISD::UMUL_LOHI,
-                                       DAG.getVTList(NVT, NVT), LL, RL);
-      Lo = UMulLOHI;
-      Hi = UMulLOHI.getValue(1);
-      RH = DAG.getNode(ISD::MUL, NVT, LL, RH);
-      LH = DAG.getNode(ISD::MUL, NVT, LH, RL);
-      Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH);
-      Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
-      return;
-    }
-  }
-
-  // If nothing else, we can make a libcall.
-  SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
-  SplitInteger(MakeLibCall(RTLIB::MUL_I64, VT, Ops, 2, true/*sign irrelevant*/),
-               Lo, Hi);
-}
-
-void DAGTypeLegalizer::ExpandResult_SDIV(SDNode *N,
-                                         SDOperand &Lo, SDOperand &Hi) {
-  assert(N->getValueType(0) == MVT::i64 && "Unsupported sdiv!");
-  SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
-  SplitInteger(MakeLibCall(RTLIB::SDIV_I64, N->getValueType(0), Ops, 2, true),
-               Lo, Hi);
-}
-
-void DAGTypeLegalizer::ExpandResult_SREM(SDNode *N,
-                                         SDOperand &Lo, SDOperand &Hi) {
-  assert(N->getValueType(0) == MVT::i64 && "Unsupported srem!");
-  SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
-  SplitInteger(MakeLibCall(RTLIB::SREM_I64, N->getValueType(0), Ops, 2, true),
-               Lo, Hi);
-}
-
-void DAGTypeLegalizer::ExpandResult_UDIV(SDNode *N,
-                                         SDOperand &Lo, SDOperand &Hi) {
-  assert(N->getValueType(0) == MVT::i64 && "Unsupported udiv!");
-  SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
-  SplitInteger(MakeLibCall(RTLIB::UDIV_I64, N->getValueType(0), Ops, 2, false),
-               Lo, Hi);
-}
-
-void DAGTypeLegalizer::ExpandResult_UREM(SDNode *N,
-                                         SDOperand &Lo, SDOperand &Hi) {
-  assert(N->getValueType(0) == MVT::i64 && "Unsupported urem!");
-  SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
-  SplitInteger(MakeLibCall(RTLIB::UREM_I64, N->getValueType(0), Ops, 2, false),
-               Lo, Hi);
-}
-
-void DAGTypeLegalizer::ExpandResult_Shift(SDNode *N,
-                                          SDOperand &Lo, SDOperand &Hi) {
-  MVT VT = N->getValueType(0);
-  
-  // If we can emit an efficient shift operation, do so now.  Check to see if 
-  // the RHS is a constant.
-  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N->getOperand(1)))
-    return ExpandShiftByConstant(N, CN->getValue(), Lo, Hi);
-
-  // If we can determine that the high bit of the shift is zero or one, even if
-  // the low bits are variable, emit this shift in an optimized form.
-  if (ExpandShiftWithKnownAmountBit(N, Lo, Hi))
-    return;
-  
-  // If this target supports shift_PARTS, use it.  First, map to the _PARTS opc.
-  unsigned PartsOpc;
-  if (N->getOpcode() == ISD::SHL) {
-    PartsOpc = ISD::SHL_PARTS;
-  } else if (N->getOpcode() == ISD::SRL) {
-    PartsOpc = ISD::SRL_PARTS;
-  } else {
-    assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
-    PartsOpc = ISD::SRA_PARTS;
-  }
-  
-  // Next check to see if the target supports this SHL_PARTS operation or if it
-  // will custom expand it.
-  MVT NVT = TLI.getTypeToTransformTo(VT);
-  TargetLowering::LegalizeAction Action = TLI.getOperationAction(PartsOpc, NVT);
-  if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) ||
-      Action == TargetLowering::Custom) {
-    // Expand the subcomponents.
-    SDOperand LHSL, LHSH;
-    GetExpandedOp(N->getOperand(0), LHSL, LHSH);
-    
-    SDOperand Ops[] = { LHSL, LHSH, N->getOperand(1) };
-    MVT VT = LHSL.getValueType();
-    Lo = DAG.getNode(PartsOpc, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3);
-    Hi = Lo.getValue(1);
-    return;
-  }
-
-  // Otherwise, emit a libcall.
-  assert(VT == MVT::i64 && "Unsupported shift!");
-
-  RTLIB::Libcall LC;
-  bool isSigned;
-  if (N->getOpcode() == ISD::SHL) {
-    LC = RTLIB::SHL_I64;
-    isSigned = false; /*sign irrelevant*/
-  } else if (N->getOpcode() == ISD::SRL) {
-    LC = RTLIB::SRL_I64;
-    isSigned = false;
-  } else {
-    assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
-    LC = RTLIB::SRA_I64;
-    isSigned = true;
-  }
-
-  SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
-  SplitInteger(MakeLibCall(LC, VT, Ops, 2, isSigned), Lo, Hi);
-}
-
-void DAGTypeLegalizer::ExpandResult_CTLZ(SDNode *N,
-                                         SDOperand &Lo, SDOperand &Hi) {
-  // ctlz (HiLo) -> Hi != 0 ? ctlz(Hi) : (ctlz(Lo)+32)
-  GetExpandedOp(N->getOperand(0), Lo, Hi);
-  MVT NVT = Lo.getValueType();
-
-  SDOperand HiNotZero = DAG.getSetCC(TLI.getSetCCResultType(Hi), Hi,
-                                     DAG.getConstant(0, NVT), ISD::SETNE);
-
-  SDOperand LoLZ = DAG.getNode(ISD::CTLZ, NVT, Lo);
-  SDOperand HiLZ = DAG.getNode(ISD::CTLZ, NVT, Hi);
-
-  Lo = DAG.getNode(ISD::SELECT, NVT, HiNotZero, HiLZ,
-                   DAG.getNode(ISD::ADD, NVT, LoLZ,
-                               DAG.getConstant(NVT.getSizeInBits(), NVT)));
-  Hi = DAG.getConstant(0, NVT);
-}
-
-void DAGTypeLegalizer::ExpandResult_CTPOP(SDNode *N,
-                                          SDOperand &Lo, SDOperand &Hi) {
-  // ctpop(HiLo) -> ctpop(Hi)+ctpop(Lo)
-  GetExpandedOp(N->getOperand(0), Lo, Hi);
-  MVT NVT = Lo.getValueType();
-  Lo = DAG.getNode(ISD::ADD, NVT, DAG.getNode(ISD::CTPOP, NVT, Lo),
-                   DAG.getNode(ISD::CTPOP, NVT, Hi));
-  Hi = DAG.getConstant(0, NVT);
-}
-
-void DAGTypeLegalizer::ExpandResult_CTTZ(SDNode *N,
-                                         SDOperand &Lo, SDOperand &Hi) {
-  // cttz (HiLo) -> Lo != 0 ? cttz(Lo) : (cttz(Hi)+32)
-  GetExpandedOp(N->getOperand(0), Lo, Hi);
-  MVT NVT = Lo.getValueType();
-
-  SDOperand LoNotZero = DAG.getSetCC(TLI.getSetCCResultType(Lo), Lo,
-                                     DAG.getConstant(0, NVT), ISD::SETNE);
-
-  SDOperand LoLZ = DAG.getNode(ISD::CTTZ, NVT, Lo);
-  SDOperand HiLZ = DAG.getNode(ISD::CTTZ, NVT, Hi);
-
-  Lo = DAG.getNode(ISD::SELECT, NVT, LoNotZero, LoLZ,
-                   DAG.getNode(ISD::ADD, NVT, HiLZ,
-                               DAG.getConstant(NVT.getSizeInBits(), NVT)));
-  Hi = DAG.getConstant(0, NVT);
-}
-
-void DAGTypeLegalizer::ExpandResult_EXTRACT_VECTOR_ELT(SDNode *N,
-                                                       SDOperand &Lo,
-                                                       SDOperand &Hi) {
-  SDOperand OldVec = N->getOperand(0);
-  unsigned OldElts = OldVec.getValueType().getVectorNumElements();
-
-  // Convert to a vector of the expanded element type, for example
-  // <2 x i64> -> <4 x i32>.
-  MVT OldVT = N->getValueType(0);
-  MVT NewVT = TLI.getTypeToTransformTo(OldVT);
-  assert(OldVT.getSizeInBits() == 2 * NewVT.getSizeInBits() &&
-         "Do not know how to handle this expansion!");
-
-  SDOperand NewVec = DAG.getNode(ISD::BIT_CONVERT,
-                                 MVT::getVectorVT(NewVT, 2*OldElts),
-                                 OldVec);
-
-  // Extract the elements at 2 * Idx and 2 * Idx + 1 from the new vector.
-  SDOperand Idx = N->getOperand(1);
-
-  // Make sure the type of Idx is big enough to hold the new values.
-  if (Idx.getValueType().bitsLT(TLI.getPointerTy()))
-    Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx);
-
-  Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, Idx);
-  Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx);
-
-  Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx,
-                    DAG.getConstant(1, Idx.getValueType()));
-  Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx);
-
-  if (TLI.isBigEndian())
-    std::swap(Lo, Hi);
-}
-
-/// ExpandShiftByConstant - N is a shift by a value that needs to be expanded,
-/// and the shift amount is a constant 'Amt'.  Expand the operation.
-void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, 
-                                             SDOperand &Lo, SDOperand &Hi) {
-  // Expand the incoming operand to be shifted, so that we have its parts
-  SDOperand InL, InH;
-  GetExpandedOp(N->getOperand(0), InL, InH);
-  
-  MVT NVT = InL.getValueType();
-  unsigned VTBits = N->getValueType(0).getSizeInBits();
-  unsigned NVTBits = NVT.getSizeInBits();
-  MVT ShTy = N->getOperand(1).getValueType();
-
-  if (N->getOpcode() == ISD::SHL) {
-    if (Amt > VTBits) {
-      Lo = Hi = DAG.getConstant(0, NVT);
-    } else if (Amt > NVTBits) {
-      Lo = DAG.getConstant(0, NVT);
-      Hi = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt-NVTBits,ShTy));
-    } else if (Amt == NVTBits) {
-      Lo = DAG.getConstant(0, NVT);
-      Hi = InL;
-    } else {
-      Lo = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt, ShTy));
-      Hi = DAG.getNode(ISD::OR, NVT,
-                       DAG.getNode(ISD::SHL, NVT, InH,
-                                   DAG.getConstant(Amt, ShTy)),
-                       DAG.getNode(ISD::SRL, NVT, InL,
-                                   DAG.getConstant(NVTBits-Amt, ShTy)));
-    }
-    return;
-  }
-  
-  if (N->getOpcode() == ISD::SRL) {
-    if (Amt > VTBits) {
-      Lo = DAG.getConstant(0, NVT);
-      Hi = DAG.getConstant(0, NVT);
-    } else if (Amt > NVTBits) {
-      Lo = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy));
-      Hi = DAG.getConstant(0, NVT);
-    } else if (Amt == NVTBits) {
-      Lo = InH;
-      Hi = DAG.getConstant(0, NVT);
-    } else {
-      Lo = DAG.getNode(ISD::OR, NVT,
-                       DAG.getNode(ISD::SRL, NVT, InL,
-                                   DAG.getConstant(Amt, ShTy)),
-                       DAG.getNode(ISD::SHL, NVT, InH,
-                                   DAG.getConstant(NVTBits-Amt, ShTy)));
-      Hi = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt, ShTy));
-    }
-    return;
-  }
-  
-  assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
-  if (Amt > VTBits) {
-    Hi = Lo = DAG.getNode(ISD::SRA, NVT, InH,
-                          DAG.getConstant(NVTBits-1, ShTy));
-  } else if (Amt > NVTBits) {
-    Lo = DAG.getNode(ISD::SRA, NVT, InH,
-                     DAG.getConstant(Amt-NVTBits, ShTy));
-    Hi = DAG.getNode(ISD::SRA, NVT, InH,
-                     DAG.getConstant(NVTBits-1, ShTy));
-  } else if (Amt == NVTBits) {
-    Lo = InH;
-    Hi = DAG.getNode(ISD::SRA, NVT, InH,
-                     DAG.getConstant(NVTBits-1, ShTy));
-  } else {
-    Lo = DAG.getNode(ISD::OR, NVT,
-                     DAG.getNode(ISD::SRL, NVT, InL,
-                                 DAG.getConstant(Amt, ShTy)),
-                     DAG.getNode(ISD::SHL, NVT, InH,
-                                 DAG.getConstant(NVTBits-Amt, ShTy)));
-    Hi = DAG.getNode(ISD::SRA, NVT, InH, DAG.getConstant(Amt, ShTy));
-  }
-}
-
-/// ExpandShiftWithKnownAmountBit - Try to determine whether we can simplify
-/// this shift based on knowledge of the high bit of the shift amount.  If we
-/// can tell this, we know that it is >= 32 or < 32, without knowing the actual
-/// shift amount.
-bool DAGTypeLegalizer::
-ExpandShiftWithKnownAmountBit(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
-  SDOperand Amt = N->getOperand(1);
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-  MVT ShTy = Amt.getValueType();
-  unsigned ShBits = ShTy.getSizeInBits();
-  unsigned NVTBits = NVT.getSizeInBits();
-  assert(isPowerOf2_32(NVTBits) &&
-         "Expanded integer type size not a power of two!");
-
-  APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits));
-  APInt KnownZero, KnownOne;
-  DAG.ComputeMaskedBits(N->getOperand(1), HighBitMask, KnownZero, KnownOne);
-  
-  // If we don't know anything about the high bits, exit.
-  if (((KnownZero|KnownOne) & HighBitMask) == 0)
-    return false;
-
-  // Get the incoming operand to be shifted.
-  SDOperand InL, InH;
-  GetExpandedOp(N->getOperand(0), InL, InH);
-
-  // If we know that any of the high bits of the shift amount are one, then we
-  // can do this as a couple of simple shifts.
-  if (KnownOne.intersects(HighBitMask)) {
-    // Mask out the high bit, which we know is set.
-    Amt = DAG.getNode(ISD::AND, ShTy, Amt,
-                      DAG.getConstant(~HighBitMask, ShTy));
-    
-    switch (N->getOpcode()) {
-    default: assert(0 && "Unknown shift");
-    case ISD::SHL:
-      Lo = DAG.getConstant(0, NVT);              // Low part is zero.
-      Hi = DAG.getNode(ISD::SHL, NVT, InL, Amt); // High part from Lo part.
-      return true;
-    case ISD::SRL:
-      Hi = DAG.getConstant(0, NVT);              // Hi part is zero.
-      Lo = DAG.getNode(ISD::SRL, NVT, InH, Amt); // Lo part from Hi part.
-      return true;
-    case ISD::SRA:
-      Hi = DAG.getNode(ISD::SRA, NVT, InH,       // Sign extend high part.
-                       DAG.getConstant(NVTBits-1, ShTy));
-      Lo = DAG.getNode(ISD::SRA, NVT, InH, Amt); // Lo part from Hi part.
-      return true;
-    }
-  }
-  
-  // If we know that all of the high bits of the shift amount are zero, then we
-  // can do this as a couple of simple shifts.
-  if ((KnownZero & HighBitMask) == HighBitMask) {
-    // Compute 32-amt.
-    SDOperand Amt2 = DAG.getNode(ISD::SUB, ShTy,
-                                 DAG.getConstant(NVTBits, ShTy),
-                                 Amt);
-    unsigned Op1, Op2;
-    switch (N->getOpcode()) {
-    default: assert(0 && "Unknown shift");
-    case ISD::SHL:  Op1 = ISD::SHL; Op2 = ISD::SRL; break;
-    case ISD::SRL:
-    case ISD::SRA:  Op1 = ISD::SRL; Op2 = ISD::SHL; break;
-    }
-    
-    Lo = DAG.getNode(N->getOpcode(), NVT, InL, Amt);
-    Hi = DAG.getNode(ISD::OR, NVT,
-                     DAG.getNode(Op1, NVT, InH, Amt),
-                     DAG.getNode(Op2, NVT, InL, Amt2));
-    return true;
-  }
-
-  return false;
-}
-
-
-//===----------------------------------------------------------------------===//
-//  Operand Expansion
-//===----------------------------------------------------------------------===//
-
-/// ExpandOperand - This method is called when the specified operand of the
-/// specified node is found to need expansion.  At this point, all of the result
-/// types of the node are known to be legal, but other operands of the node may
-/// need promotion or expansion as well as the specified one.
-bool DAGTypeLegalizer::ExpandOperand(SDNode *N, unsigned OpNo) {
-  DEBUG(cerr << "Expand node operand: "; N->dump(&DAG); cerr << "\n");
-  SDOperand Res(0, 0);
-  
-  if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
-      == TargetLowering::Custom)
-    Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
-  
-  if (Res.Val == 0) {
-    switch (N->getOpcode()) {
-    default:
-  #ifndef NDEBUG
-      cerr << "ExpandOperand Op #" << OpNo << ": ";
-      N->dump(&DAG); cerr << "\n";
-  #endif
-      assert(0 && "Do not know how to expand this operator's operand!");
-      abort();
-      
-    case ISD::TRUNCATE:        Res = ExpandOperand_TRUNCATE(N); break;
-    case ISD::BIT_CONVERT:     Res = ExpandOperand_BIT_CONVERT(N); break;
-
-    case ISD::SINT_TO_FP:
-      Res = ExpandOperand_SINT_TO_FP(N->getOperand(0), N->getValueType(0));
-      break;
-    case ISD::UINT_TO_FP:
-      Res = ExpandOperand_UINT_TO_FP(N->getOperand(0), N->getValueType(0)); 
-      break;
-    case ISD::EXTRACT_ELEMENT: Res = ExpandOperand_EXTRACT_ELEMENT(N); break;
-
-    case ISD::BR_CC:           Res = ExpandOperand_BR_CC(N); break;
-    case ISD::SETCC:           Res = ExpandOperand_SETCC(N); break;
-
-    case ISD::STORE:
-      Res = ExpandOperand_STORE(cast<StoreSDNode>(N), OpNo);
-      break;
-
-    case ISD::BUILD_VECTOR: Res = ExpandOperand_BUILD_VECTOR(N); break;
-    }
-  }
-  
-  // If the result is null, the sub-method took care of registering results etc.
-  if (!Res.Val) return false;
-  // If the result is N, the sub-method updated N in place.  Check to see if any
-  // operands are new, and if so, mark them.
-  if (Res.Val == N) {
-    // Mark N as new and remark N and its operands.  This allows us to correctly
-    // revisit N if it needs another step of promotion and allows us to visit
-    // any new operands to N.
-    ReanalyzeNode(N);
-    return true;
-  }
-
-  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
-         "Invalid operand expansion");
-  
-  ReplaceValueWith(SDOperand(N, 0), Res);
-  return false;
-}
-
-SDOperand DAGTypeLegalizer::ExpandOperand_TRUNCATE(SDNode *N) {
-  SDOperand InL, InH;
-  GetExpandedOp(N->getOperand(0), InL, InH);
-  // Just truncate the low part of the source.
-  return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), InL);
-}
-
-SDOperand DAGTypeLegalizer::ExpandOperand_BIT_CONVERT(SDNode *N) {
-  if (N->getValueType(0).isVector()) {
-    // An illegal integer type is being converted to a legal vector type.
-    // Make a two element vector out of the expanded parts and convert that
-    // instead, but only if the new vector type is legal (otherwise there
-    // is no point, and it might create expansion loops).  For example, on
-    // x86 this turns v1i64 = BIT_CONVERT i64 into v1i64 = BIT_CONVERT v2i32.
-    MVT OVT = N->getOperand(0).getValueType();
-    MVT NVT = MVT::getVectorVT(TLI.getTypeToTransformTo(OVT), 2);
-
-    if (isTypeLegal(NVT)) {
-      SDOperand Parts[2];
-      GetExpandedOp(N->getOperand(0), Parts[0], Parts[1]);
-
-      if (TLI.isBigEndian())
-        std::swap(Parts[0], Parts[1]);
-
-      SDOperand Vec = DAG.getNode(ISD::BUILD_VECTOR, NVT, Parts, 2);
-      return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Vec);
-    }
-  }
-
-  // Otherwise, store to a temporary and load out again as the new type.
-  return CreateStackStoreLoad(N->getOperand(0), N->getValueType(0));
-}
-
-SDOperand DAGTypeLegalizer::ExpandOperand_SINT_TO_FP(SDOperand Source, 
-                                                     MVT DestTy) {
-  // We know the destination is legal, but that the input needs to be expanded.
-  MVT SourceVT = Source.getValueType();
-  
-  // Check to see if the target has a custom way to lower this.  If so, use it.
-  switch (TLI.getOperationAction(ISD::SINT_TO_FP, SourceVT)) {
-  default: assert(0 && "This action not implemented for this operation!");
-  case TargetLowering::Legal:
-  case TargetLowering::Expand:
-    break;   // This case is handled below.
-  case TargetLowering::Custom:
-    SDOperand NV = TLI.LowerOperation(DAG.getNode(ISD::SINT_TO_FP, DestTy,
-                                                  Source), DAG);
-    if (NV.Val) return NV;
-    break;   // The target lowered this.
-  }
-  
-  RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
-  if (SourceVT == MVT::i64) {
-    if (DestTy == MVT::f32)
-      LC = RTLIB::SINTTOFP_I64_F32;
-    else {
-      assert(DestTy == MVT::f64 && "Unknown fp value type!");
-      LC = RTLIB::SINTTOFP_I64_F64;
-    }
-  } else if (SourceVT == MVT::i128) {
-    if (DestTy == MVT::f32)
-      LC = RTLIB::SINTTOFP_I128_F32;
-    else if (DestTy == MVT::f64)
-      LC = RTLIB::SINTTOFP_I128_F64;
-    else if (DestTy == MVT::f80)
-      LC = RTLIB::SINTTOFP_I128_F80;
-    else {
-      assert(DestTy == MVT::ppcf128 && "Unknown fp value type!");
-      LC = RTLIB::SINTTOFP_I128_PPCF128;
-    }
-  } else {
-    assert(0 && "Unknown int value type!");
-  }
-
-  assert(LC != RTLIB::UNKNOWN_LIBCALL &&
-         "Don't know how to expand this SINT_TO_FP!");
-  return MakeLibCall(LC, DestTy, &Source, 1, true);
-}
-
-SDOperand DAGTypeLegalizer::ExpandOperand_UINT_TO_FP(SDOperand Source, 
-                                                     MVT DestTy) {
-  // We know the destination is legal, but that the input needs to be expanded.
-  assert(getTypeAction(Source.getValueType()) == Expand &&
-         "This is not an expansion!");
-  
-  // If this is unsigned, and not supported, first perform the conversion to
-  // signed, then adjust the result if the sign bit is set.
-  SDOperand SignedConv = ExpandOperand_SINT_TO_FP(Source, DestTy);
-
-  // The 64-bit value loaded will be incorrectly if the 'sign bit' of the
-  // incoming integer is set.  To handle this, we dynamically test to see if
-  // it is set, and, if so, add a fudge factor.
-  SDOperand Lo, Hi;
-  GetExpandedOp(Source, Lo, Hi);
-  
-  SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi), Hi,
-                                   DAG.getConstant(0, Hi.getValueType()),
-                                   ISD::SETLT);
-  SDOperand Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4);
-  SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(),
-                                    SignSet, Four, Zero);
-  uint64_t FF = 0x5f800000ULL;
-  if (TLI.isLittleEndian()) FF <<= 32;
-  Constant *FudgeFactor = ConstantInt::get((Type*)Type::Int64Ty, FF);
-  
-  SDOperand CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy());
-  CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset);
-  SDOperand FudgeInReg;
-  if (DestTy == MVT::f32)
-    FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, NULL, 0);
-  else if (DestTy.bitsGT(MVT::f32))
-    // FIXME: Avoid the extend by construction the right constantpool?
-    FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, DestTy, DAG.getEntryNode(),
-                                CPIdx, NULL, 0, MVT::f32);
-  else 
-    assert(0 && "Unexpected conversion");
-  
-  return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg);
-}
-
-SDOperand DAGTypeLegalizer::ExpandOperand_EXTRACT_ELEMENT(SDNode *N) {
-  SDOperand Lo, Hi;
-  GetExpandedOp(N->getOperand(0), Lo, Hi);
-  return cast<ConstantSDNode>(N->getOperand(1))->getValue() ? Hi : Lo;
-}
-
-SDOperand DAGTypeLegalizer::ExpandOperand_BR_CC(SDNode *N) {
-  SDOperand NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
-  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
-  ExpandSetCCOperands(NewLHS, NewRHS, CCCode);
-
-  // If ExpandSetCCOperands returned a scalar, we need to compare the result
-  // against zero to select between true and false values.
-  if (NewRHS.Val == 0) {
-    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
-    CCCode = ISD::SETNE;
-  }
-
-  // Update N to have the operands specified.
-  return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
-                                DAG.getCondCode(CCCode), NewLHS, NewRHS,
-                                N->getOperand(4));
-}
-
-SDOperand DAGTypeLegalizer::ExpandOperand_SETCC(SDNode *N) {
-  SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
-  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
-  ExpandSetCCOperands(NewLHS, NewRHS, CCCode);
-  
-  // If ExpandSetCCOperands returned a scalar, use it.
-  if (NewRHS.Val == 0) return NewLHS;
-
-  // Otherwise, update N to have the operands specified.
-  return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS,
-                                DAG.getCondCode(CCCode));
-}
-
-/// ExpandSetCCOperands - Expand the operands of a comparison.  This code is
-/// shared among BR_CC, SELECT_CC, and SETCC handlers.
-void DAGTypeLegalizer::ExpandSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS,
-                                           ISD::CondCode &CCCode) {
-  SDOperand LHSLo, LHSHi, RHSLo, RHSHi;
-  GetExpandedOp(NewLHS, LHSLo, LHSHi);
-  GetExpandedOp(NewRHS, RHSLo, RHSHi);
-
-  MVT VT = NewLHS.getValueType();
-  if (VT == MVT::ppcf128) {
-    // FIXME:  This generated code sucks.  We want to generate
-    //         FCMP crN, hi1, hi2
-    //         BNE crN, L:
-    //         FCMP crN, lo1, lo2
-    // The following can be improved, but not that much.
-    SDOperand Tmp1, Tmp2, Tmp3;
-    Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, ISD::SETEQ);
-    Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, CCCode);
-    Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
-    Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, ISD::SETNE);
-    Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, CCCode);
-    Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
-    NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3);
-    NewRHS = SDOperand();   // LHS is the result, not a compare.
-    return;
-  }
-
-  if (CCCode == ISD::SETEQ || CCCode == ISD::SETNE) {
-    if (RHSLo == RHSHi)
-      if (ConstantSDNode *RHSCST = dyn_cast<ConstantSDNode>(RHSLo))
-        if (RHSCST->isAllOnesValue()) {
-          // Equality comparison to -1.
-          NewLHS = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi);
-          NewRHS = RHSLo;
-          return;
-        }
-          
-    NewLHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo);
-    NewRHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi);
-    NewLHS = DAG.getNode(ISD::OR, NewLHS.getValueType(), NewLHS, NewRHS);
-    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
-    return;
-  }
-  
-  // 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>(NewRHS))
-    if ((CCCode == ISD::SETLT && CST->isNullValue()) ||     // X < 0
-        (CCCode == ISD::SETGT && CST->isAllOnesValue())) {  // X > -1
-      NewLHS = LHSHi;
-      NewRHS = RHSHi;
-      return;
-    }
-      
-  // FIXME: This generated code sucks.
-  ISD::CondCode LowCC;
-  switch (CCCode) {
-  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)
-  TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, NULL);
-  SDOperand Tmp1, Tmp2;
-  Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, LowCC,
-                           false, DagCombineInfo);
-  if (!Tmp1.Val)
-    Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, LowCC);
-  Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
-                           CCCode, false, DagCombineInfo);
-  if (!Tmp2.Val)
-    Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
-                       DAG.getCondCode(CCCode));
-  
-  ConstantSDNode *Tmp1C = dyn_cast<ConstantSDNode>(Tmp1.Val);
-  ConstantSDNode *Tmp2C = dyn_cast<ConstantSDNode>(Tmp2.Val);
-  if ((Tmp1C && Tmp1C->isNullValue()) ||
-      (Tmp2C && Tmp2C->isNullValue() &&
-       (CCCode == ISD::SETLE || CCCode == ISD::SETGE ||
-        CCCode == ISD::SETUGE || CCCode == ISD::SETULE)) ||
-      (Tmp2C && Tmp2C->getAPIntValue() == 1 &&
-       (CCCode == ISD::SETLT || CCCode == ISD::SETGT ||
-        CCCode == ISD::SETUGT || CCCode == ISD::SETULT))) {
-    // low part is known false, returns high part.
-    // For LE / GE, if high part is known false, ignore the low part.
-    // For LT / GT, if high part is known true, ignore the low part.
-    NewLHS = Tmp2;
-    NewRHS = SDOperand();
-    return;
-  }
-  
-  NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
-                             ISD::SETEQ, false, DagCombineInfo);
-  if (!NewLHS.Val)
-    NewLHS = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi,
-                          ISD::SETEQ);
-  NewLHS = DAG.getNode(ISD::SELECT, Tmp1.getValueType(),
-                       NewLHS, Tmp1, Tmp2);
-  NewRHS = SDOperand();
-}
-
-SDOperand DAGTypeLegalizer::ExpandOperand_STORE(StoreSDNode *N, unsigned OpNo) {
-  // FIXME: Add support for indexed stores.
-  assert(OpNo == 1 && "Can only expand the stored value so far");
-
-  MVT VT = N->getOperand(1).getValueType();
-  MVT NVT = TLI.getTypeToTransformTo(VT);
-  SDOperand Ch  = N->getChain();
-  SDOperand Ptr = N->getBasePtr();
-  int SVOffset = N->getSrcValueOffset();
-  unsigned Alignment = N->getAlignment();
-  bool isVolatile = N->isVolatile();
-  SDOperand Lo, Hi;
-
-  assert(!(NVT.getSizeInBits() & 7) && "Expanded type not byte sized!");
-
-  if (!N->isTruncatingStore()) {
-    unsigned IncrementSize = 0;
-    GetExpandedOp(N->getValue(), Lo, Hi);
-    IncrementSize = Hi.getValueType().getSizeInBits()/8;
-
-    if (TLI.isBigEndian())
-      std::swap(Lo, Hi);
-
-    Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(),
-                      SVOffset, isVolatile, Alignment);
-
-    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                      DAG.getIntPtrConstant(IncrementSize));
-    assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!");
-    Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
-                      isVolatile, MinAlign(Alignment, IncrementSize));
-    return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
-  } else if (N->getMemoryVT().bitsLE(NVT)) {
-    GetExpandedOp(N->getValue(), Lo, Hi);
-    return DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
-                             N->getMemoryVT(), isVolatile, Alignment);
-  } else if (TLI.isLittleEndian()) {
-    // Little-endian - low bits are at low addresses.
-    GetExpandedOp(N->getValue(), Lo, Hi);
-
-    Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset,
-                      isVolatile, Alignment);
-
-    unsigned ExcessBits =
-      N->getMemoryVT().getSizeInBits() - NVT.getSizeInBits();
-    MVT NEVT = MVT::getIntegerVT(ExcessBits);
-
-    // Increment the pointer to the other half.
-    unsigned IncrementSize = NVT.getSizeInBits()/8;
-    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                      DAG.getIntPtrConstant(IncrementSize));
-    Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(),
-                           SVOffset+IncrementSize, NEVT,
-                           isVolatile, MinAlign(Alignment, IncrementSize));
-    return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
-  } else {
-    // Big-endian - high bits are at low addresses.  Favor aligned stores at
-    // the cost of some bit-fiddling.
-    GetExpandedOp(N->getValue(), Lo, Hi);
-
-    MVT EVT = N->getMemoryVT();
-    unsigned EBytes = EVT.getStoreSizeInBits()/8;
-    unsigned IncrementSize = NVT.getSizeInBits()/8;
-    unsigned ExcessBits = (EBytes - IncrementSize)*8;
-    MVT HiVT = MVT::getIntegerVT(EVT.getSizeInBits() - ExcessBits);
-
-    if (ExcessBits < NVT.getSizeInBits()) {
-      // Transfer high bits from the top of Lo to the bottom of Hi.
-      Hi = DAG.getNode(ISD::SHL, NVT, Hi,
-                       DAG.getConstant(NVT.getSizeInBits() - ExcessBits,
-                                       TLI.getShiftAmountTy()));
-      Hi = DAG.getNode(ISD::OR, NVT, Hi,
-                       DAG.getNode(ISD::SRL, NVT, Lo,
-                                   DAG.getConstant(ExcessBits,
-                                                   TLI.getShiftAmountTy())));
-    }
-
-    // Store both the high bits and maybe some of the low bits.
-    Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(),
-                           SVOffset, HiVT, isVolatile, Alignment);
-
-    // Increment the pointer to the other half.
-    Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                      DAG.getIntPtrConstant(IncrementSize));
-    // Store the lowest ExcessBits bits in the second half.
-    Lo = DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(),
-                           SVOffset+IncrementSize,
-                           MVT::getIntegerVT(ExcessBits),
-                           isVolatile, MinAlign(Alignment, IncrementSize));
-    return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
-  }
-}
-
-SDOperand DAGTypeLegalizer::ExpandOperand_BUILD_VECTOR(SDNode *N) {
-  // The vector type is legal but the element type needs expansion.
-  MVT VecVT = N->getValueType(0);
-  unsigned NumElts = VecVT.getVectorNumElements();
-  MVT OldVT = N->getOperand(0).getValueType();
-  MVT NewVT = TLI.getTypeToTransformTo(OldVT);
-
-  assert(OldVT.getSizeInBits() == 2 * NewVT.getSizeInBits() &&
-         "Do not know how to expand this operand!");
-
-  // Build a vector of twice the length out of the expanded elements.
-  // For example <2 x i64> -> <4 x i32>.
-  std::vector<SDOperand> NewElts;
-  NewElts.reserve(NumElts*2);
-
-  for (unsigned i = 0; i < NumElts; ++i) {
-    SDOperand Lo, Hi;
-    GetExpandedOp(N->getOperand(i), Lo, Hi);
-    if (TLI.isBigEndian())
-      std::swap(Lo, Hi);
-    NewElts.push_back(Lo);
-    NewElts.push_back(Hi);
-  }
-
-  SDOperand NewVec = DAG.getNode(ISD::BUILD_VECTOR,
-                                 MVT::getVectorVT(NewVT, NewElts.size()),
-                                 &NewElts[0], NewElts.size());
-
-  // Convert the new vector to the old vector type.
-  return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
-}

Removed: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesFloatToInt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesFloatToInt.cpp?rev=52407&view=auto

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesFloatToInt.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesFloatToInt.cpp (removed)
@@ -1,357 +0,0 @@
-//===-- LegalizeTypesFloatToInt.cpp - LegalizeTypes float to int support --===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements float to integer conversion for LegalizeTypes.  This
-// is the act of turning a computation in an invalid floating point type into
-// a computation in an integer type of the same size.  For example, turning
-// f32 arithmetic into operations using i32.  Also known as "soft float".
-// The result is equivalent to bitcasting the float value to the integer type.
-//
-//===----------------------------------------------------------------------===//
-
-#include "llvm/CodeGen/PseudoSourceValue.h"
-#include "llvm/DerivedTypes.h"
-#include "LegalizeTypes.h"
-using namespace llvm;
-
-/// GetFPLibCall - Return the right libcall for the given floating point type.
-static RTLIB::Libcall GetFPLibCall(MVT VT,
-                                   RTLIB::Libcall Call_F32,
-                                   RTLIB::Libcall Call_F64,
-                                   RTLIB::Libcall Call_F80,
-                                   RTLIB::Libcall Call_PPCF128) {
-  return
-    VT == MVT::f32 ? Call_F32 :
-    VT == MVT::f64 ? Call_F64 :
-    VT == MVT::f80 ? Call_F80 :
-    VT == MVT::ppcf128 ? Call_PPCF128 :
-    RTLIB::UNKNOWN_LIBCALL;
-}
-
-//===----------------------------------------------------------------------===//
-//  Result Float to Integer Conversion.
-//===----------------------------------------------------------------------===//
-
-void DAGTypeLegalizer::FloatToIntResult(SDNode *N, unsigned ResNo) {
-  DEBUG(cerr << "FloatToInt node result " << ResNo << ": "; N->dump(&DAG);
-        cerr << "\n");
-  SDOperand R = SDOperand();
-
-  // FIXME: Custom lowering for float-to-int?
-#if 0
-  // See if the target wants to custom convert this node to an integer.
-  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
-      TargetLowering::Custom) {
-    // If the target wants to, allow it to lower this itself.
-    if (SDNode *P = TLI.FloatToIntOperationResult(N, DAG)) {
-      // Everything that once used N now uses P.  We are guaranteed that the
-      // result value types of N and the result value types of P match.
-      ReplaceNodeWith(N, P);
-      return;
-    }
-  }
-#endif
-
-  switch (N->getOpcode()) {
-  default:
-#ifndef NDEBUG
-    cerr << "FloatToIntResult #" << ResNo << ": ";
-    N->dump(&DAG); cerr << "\n";
-#endif
-    assert(0 && "Do not know how to convert the result of this operator!");
-    abort();
-
-    case ISD::BIT_CONVERT: R = FloatToIntRes_BIT_CONVERT(N); break;
-    case ISD::BUILD_PAIR:  R = FloatToIntRes_BUILD_PAIR(N); break;
-    case ISD::ConstantFP:
-      R = FloatToIntRes_ConstantFP(cast<ConstantFPSDNode>(N));
-      break;
-    case ISD::FCOPYSIGN:   R = FloatToIntRes_FCOPYSIGN(N); break;
-    case ISD::LOAD:        R = FloatToIntRes_LOAD(N); break;
-    case ISD::SINT_TO_FP:
-    case ISD::UINT_TO_FP:  R = FloatToIntRes_XINT_TO_FP(N); break;
-
-    case ISD::FADD: R = FloatToIntRes_FADD(N); break;
-    case ISD::FMUL: R = FloatToIntRes_FMUL(N); break;
-    case ISD::FSUB: R = FloatToIntRes_FSUB(N); break;
-  }
-
-  // If R is null, the sub-method took care of registering the result.
-  if (R.Val)
-    SetIntegerOp(SDOperand(N, ResNo), R);
-}
-
-SDOperand DAGTypeLegalizer::FloatToIntRes_BIT_CONVERT(SDNode *N) {
-  return BitConvertToInteger(N->getOperand(0));
-}
-
-SDOperand DAGTypeLegalizer::FloatToIntRes_BUILD_PAIR(SDNode *N) {
-  // Convert the inputs to integers, and build a new pair out of them.
-  return DAG.getNode(ISD::BUILD_PAIR,
-                     TLI.getTypeToTransformTo(N->getValueType(0)),
-                     BitConvertToInteger(N->getOperand(0)),
-                     BitConvertToInteger(N->getOperand(1)));
-}
-
-SDOperand DAGTypeLegalizer::FloatToIntRes_ConstantFP(ConstantFPSDNode *N) {
-  return DAG.getConstant(N->getValueAPF().convertToAPInt(),
-                         TLI.getTypeToTransformTo(N->getValueType(0)));
-}
-
-SDOperand DAGTypeLegalizer::FloatToIntRes_FADD(SDNode *N) {
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-  SDOperand Ops[2] = { GetIntegerOp(N->getOperand(0)),
-                       GetIntegerOp(N->getOperand(1)) };
-  return MakeLibCall(GetFPLibCall(N->getValueType(0),
-                                  RTLIB::ADD_F32,
-                                  RTLIB::ADD_F64,
-                                  RTLIB::ADD_F80,
-                                  RTLIB::ADD_PPCF128),
-                     NVT, Ops, 2, false/*sign irrelevant*/);
-}
-
-SDOperand DAGTypeLegalizer::FloatToIntRes_FCOPYSIGN(SDNode *N) {
-  SDOperand LHS = GetIntegerOp(N->getOperand(0));
-  SDOperand RHS = BitConvertToInteger(N->getOperand(1));
-
-  MVT LVT = LHS.getValueType();
-  MVT RVT = RHS.getValueType();
-
-  unsigned LSize = LVT.getSizeInBits();
-  unsigned RSize = RVT.getSizeInBits();
-
-  // First get the sign bit of second operand.
-  SDOperand SignBit = DAG.getNode(ISD::SHL, RVT, DAG.getConstant(1, RVT),
-                                  DAG.getConstant(RSize - 1,
-                                                  TLI.getShiftAmountTy()));
-  SignBit = DAG.getNode(ISD::AND, RVT, RHS, SignBit);
-
-  // Shift right or sign-extend it if the two operands have different types.
-  int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits();
-  if (SizeDiff > 0) {
-    SignBit = DAG.getNode(ISD::SRL, RVT, SignBit,
-                          DAG.getConstant(SizeDiff, TLI.getShiftAmountTy()));
-    SignBit = DAG.getNode(ISD::TRUNCATE, LVT, SignBit);
-  } else if (SizeDiff < 0) {
-    SignBit = DAG.getNode(ISD::ANY_EXTEND, LVT, SignBit);
-    SignBit = DAG.getNode(ISD::SHL, LVT, SignBit,
-                          DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy()));
-  }
-
-  // Clear the sign bit of the first operand.
-  SDOperand Mask = DAG.getNode(ISD::SHL, LVT, DAG.getConstant(1, LVT),
-                               DAG.getConstant(LSize - 1,
-                                               TLI.getShiftAmountTy()));
-  Mask = DAG.getNode(ISD::SUB, LVT, Mask, DAG.getConstant(1, LVT));
-  LHS = DAG.getNode(ISD::AND, LVT, LHS, Mask);
-
-  // Or the value with the sign bit.
-  return DAG.getNode(ISD::OR, LVT, LHS, SignBit);
-}
-
-SDOperand DAGTypeLegalizer::FloatToIntRes_FMUL(SDNode *N) {
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-  SDOperand Ops[2] = { GetIntegerOp(N->getOperand(0)),
-                       GetIntegerOp(N->getOperand(1)) };
-  return MakeLibCall(GetFPLibCall(N->getValueType(0),
-                                  RTLIB::MUL_F32,
-                                  RTLIB::MUL_F64,
-                                  RTLIB::MUL_F80,
-                                  RTLIB::MUL_PPCF128),
-                     NVT, Ops, 2, false/*sign irrelevant*/);
-}
-
-SDOperand DAGTypeLegalizer::FloatToIntRes_FSUB(SDNode *N) {
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-  SDOperand Ops[2] = { GetIntegerOp(N->getOperand(0)),
-                       GetIntegerOp(N->getOperand(1)) };
-  return MakeLibCall(GetFPLibCall(N->getValueType(0),
-                                  RTLIB::SUB_F32,
-                                  RTLIB::SUB_F64,
-                                  RTLIB::SUB_F80,
-                                  RTLIB::SUB_PPCF128),
-                     NVT, Ops, 2, false/*sign irrelevant*/);
-}
-
-SDOperand DAGTypeLegalizer::FloatToIntRes_LOAD(SDNode *N) {
-  LoadSDNode *L = cast<LoadSDNode>(N);
-  MVT VT = N->getValueType(0);
-  MVT NVT = TLI.getTypeToTransformTo(VT);
-
-  if (L->getExtensionType() == ISD::NON_EXTLOAD)
-     return DAG.getLoad(L->getAddressingMode(), L->getExtensionType(),
-                        NVT, L->getChain(), L->getBasePtr(), L->getOffset(),
-                        L->getSrcValue(), L->getSrcValueOffset(), NVT,
-                        L->isVolatile(), L->getAlignment());
-
-  // Do a non-extending load followed by FP_EXTEND.
-  SDOperand NL = DAG.getLoad(L->getAddressingMode(), ISD::NON_EXTLOAD,
-                             L->getMemoryVT(), L->getChain(),
-                             L->getBasePtr(), L->getOffset(),
-                             L->getSrcValue(), L->getSrcValueOffset(),
-                             L->getMemoryVT(),
-                             L->isVolatile(), L->getAlignment());
-  return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, VT, NL));
-}
-
-SDOperand DAGTypeLegalizer::FloatToIntRes_XINT_TO_FP(SDNode *N) {
-  bool isSigned = N->getOpcode() == ISD::SINT_TO_FP;
-  MVT DestVT = N->getValueType(0);
-  SDOperand Op = N->getOperand(0);
-
-  if (Op.getValueType() == MVT::i32) {
-    // simple 32-bit [signed|unsigned] integer to float/double expansion
-
-    // Get the stack frame index of a 8 byte buffer.
-    SDOperand StackSlot = DAG.CreateStackTemporary(MVT::f64);
-
-    // word offset constant for Hi/Lo address computation
-    SDOperand Offset =
-      DAG.getConstant(MVT(MVT::i32).getSizeInBits() / 8,
-                      TLI.getPointerTy());
-    // set up Hi and Lo (into buffer) address based on endian
-    SDOperand Hi = StackSlot;
-    SDOperand Lo = DAG.getNode(ISD::ADD, TLI.getPointerTy(), StackSlot, Offset);
-    if (TLI.isLittleEndian())
-      std::swap(Hi, Lo);
-
-    // if signed map to unsigned space
-    SDOperand OpMapped;
-    if (isSigned) {
-      // constant used to invert sign bit (signed to unsigned mapping)
-      SDOperand SignBit = DAG.getConstant(0x80000000u, MVT::i32);
-      OpMapped = DAG.getNode(ISD::XOR, MVT::i32, Op, SignBit);
-    } else {
-      OpMapped = Op;
-    }
-    // store the lo of the constructed double - based on integer input
-    SDOperand Store1 = DAG.getStore(DAG.getEntryNode(),
-                                    OpMapped, Lo, NULL, 0);
-    // 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.getStore(Store1, InitialHi, Hi, NULL, 0);
-    // load the constructed double
-    SDOperand Load = DAG.getLoad(MVT::f64, Store2, StackSlot, NULL, 0);
-    // 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 (DestVT.bitsLT(MVT::f64)) {
-      Result = DAG.getNode(ISD::FP_ROUND, DestVT, Sub,
-                           DAG.getIntPtrConstant(0));
-    } else if (DestVT.bitsGT(MVT::f64)) {
-      Result = DAG.getNode(ISD::FP_EXTEND, DestVT, Sub);
-    }
-    return BitConvertToInteger(Result);
-  }
-  assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet");
-  SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op);
-
-  SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultType(Op), Op,
-                                   DAG.getConstant(0, Op.getValueType()),
-                                   ISD::SETLT);
-  SDOperand Zero = DAG.getIntPtrConstant(0), Four = DAG.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 (Op.getValueType().getSimpleVT()) {
-  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 = ConstantInt::get(Type::Int64Ty, 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,
-                             PseudoSourceValue::getConstantPool(), 0);
-  else {
-    FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, DestVT,
-                                DAG.getEntryNode(), CPIdx,
-                                PseudoSourceValue::getConstantPool(), 0,
-                                MVT::f32);
-  }
-
-  return BitConvertToInteger(DAG.getNode(ISD::FADD, DestVT, Tmp1, FudgeInReg));
-}
-
-
-//===----------------------------------------------------------------------===//
-//  Operand Float to Integer Conversion..
-//===----------------------------------------------------------------------===//
-
-bool DAGTypeLegalizer::FloatToIntOperand(SDNode *N, unsigned OpNo) {
-  DEBUG(cerr << "FloatToInt node operand " << OpNo << ": "; N->dump(&DAG);
-        cerr << "\n");
-  SDOperand Res(0, 0);
-
-  // FIXME: Custom lowering for float-to-int?
-#if 0
-  if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
-      == TargetLowering::Custom)
-    Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
-#endif
-
-  if (Res.Val == 0) {
-    switch (N->getOpcode()) {
-    default:
-#ifndef NDEBUG
-      cerr << "FloatToIntOperand Op #" << OpNo << ": ";
-      N->dump(&DAG); cerr << "\n";
-#endif
-      assert(0 && "Do not know how to convert this operator's operand!");
-      abort();
-
-      case ISD::BIT_CONVERT: Res = FloatToIntOp_BIT_CONVERT(N); break;
-    }
-  }
-
-  // If the result is null, the sub-method took care of registering results etc.
-  if (!Res.Val) return false;
-
-  // If the result is N, the sub-method updated N in place.  Check to see if any
-  // operands are new, and if so, mark them.
-  if (Res.Val == N) {
-    // Mark N as new and remark N and its operands.  This allows us to correctly
-    // revisit N if it needs another step of promotion and allows us to visit
-    // any new operands to N.
-    ReanalyzeNode(N);
-    return true;
-  }
-
-  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
-         "Invalid operand expansion");
-
-  ReplaceValueWith(SDOperand(N, 0), Res);
-  return false;
-}
-
-SDOperand DAGTypeLegalizer::FloatToIntOp_BIT_CONVERT(SDNode *N) {
-  return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0),
-                     GetIntegerOp(N->getOperand(0)));
-}

Removed: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp?rev=52407&view=auto

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesPromote.cpp (removed)
@@ -1,748 +0,0 @@
-//===-- LegalizeTypesPromote.cpp - Promotion for LegalizeTypes ------------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements promotion support for LegalizeTypes.  Promotion is the
-// act of changing a computation in an invalid type to be a computation in a 
-// larger type.  For example, implementing i8 arithmetic in an i32 register (as
-// is often needed on powerpc for example).
-//
-//===----------------------------------------------------------------------===//
-
-#include "LegalizeTypes.h"
-using namespace llvm;
-
-//===----------------------------------------------------------------------===//
-//  Result Promotion
-//===----------------------------------------------------------------------===//
-
-/// PromoteResult - This method is called when a result of a node is found to be
-/// in need of promotion to a larger type.  At this point, the node may also
-/// have invalid operands or may have other results that need expansion, we just
-/// know that (at least) one result needs promotion.
-void DAGTypeLegalizer::PromoteResult(SDNode *N, unsigned ResNo) {
-  DEBUG(cerr << "Promote node result: "; N->dump(&DAG); cerr << "\n");
-  SDOperand Result = SDOperand();
-  
-  switch (N->getOpcode()) {
-  default:
-#ifndef NDEBUG
-    cerr << "PromoteResult #" << ResNo << ": ";
-    N->dump(&DAG); cerr << "\n";
-#endif
-    assert(0 && "Do not know how to promote this operator!");
-    abort();
-  case ISD::UNDEF:    Result = PromoteResult_UNDEF(N); break;
-  case ISD::Constant: Result = PromoteResult_Constant(N); break;
-
-  case ISD::TRUNCATE:    Result = PromoteResult_TRUNCATE(N); break;
-  case ISD::SIGN_EXTEND:
-  case ISD::ZERO_EXTEND:
-  case ISD::ANY_EXTEND:  Result = PromoteResult_INT_EXTEND(N); break;
-  case ISD::FP_ROUND:    Result = PromoteResult_FP_ROUND(N); break;
-  case ISD::FP_TO_SINT:
-  case ISD::FP_TO_UINT:  Result = PromoteResult_FP_TO_XINT(N); break;
-  case ISD::SETCC:    Result = PromoteResult_SETCC(N); break;
-  case ISD::LOAD:     Result = PromoteResult_LOAD(cast<LoadSDNode>(N)); break;
-  case ISD::BUILD_PAIR:  Result = PromoteResult_BUILD_PAIR(N); break;
-  case ISD::BIT_CONVERT: Result = PromoteResult_BIT_CONVERT(N); break;
-
-  case ISD::AND:
-  case ISD::OR:
-  case ISD::XOR:
-  case ISD::ADD:
-  case ISD::SUB:
-  case ISD::MUL:      Result = PromoteResult_SimpleIntBinOp(N); break;
-
-  case ISD::SDIV:
-  case ISD::SREM:     Result = PromoteResult_SDIV(N); break;
-
-  case ISD::UDIV:
-  case ISD::UREM:     Result = PromoteResult_UDIV(N); break;
-
-  case ISD::SHL:      Result = PromoteResult_SHL(N); break;
-  case ISD::SRA:      Result = PromoteResult_SRA(N); break;
-  case ISD::SRL:      Result = PromoteResult_SRL(N); break;
-
-  case ISD::SELECT:    Result = PromoteResult_SELECT(N); break;
-  case ISD::SELECT_CC: Result = PromoteResult_SELECT_CC(N); break;
-
-  case ISD::CTLZ:     Result = PromoteResult_CTLZ(N); break;
-  case ISD::CTPOP:    Result = PromoteResult_CTPOP(N); break;
-  case ISD::CTTZ:     Result = PromoteResult_CTTZ(N); break;
-
-  case ISD::EXTRACT_VECTOR_ELT:
-    Result = PromoteResult_EXTRACT_VECTOR_ELT(N);
-    break;
-  }      
-
-  // If Result is null, the sub-method took care of registering the result.
-  if (Result.Val)
-    SetPromotedOp(SDOperand(N, ResNo), Result);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_UNDEF(SDNode *N) {
-  return DAG.getNode(ISD::UNDEF, TLI.getTypeToTransformTo(N->getValueType(0)));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_Constant(SDNode *N) {
-  MVT VT = N->getValueType(0);
-  // Zero extend things like i1, sign extend everything else.  It shouldn't
-  // matter in theory which one we pick, but this tends to give better code?
-  unsigned Opc = VT.isByteSized() ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND;
-  SDOperand Result = DAG.getNode(Opc, TLI.getTypeToTransformTo(VT),
-                                 SDOperand(N, 0));
-  assert(isa<ConstantSDNode>(Result) && "Didn't constant fold ext?");
-  return Result;
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_TRUNCATE(SDNode *N) {
-  SDOperand Res;
-
-  switch (getTypeAction(N->getOperand(0).getValueType())) {
-  default: assert(0 && "Unknown type action!");
-  case Legal:
-  case Expand:
-    Res = N->getOperand(0);
-    break;
-  case Promote:
-    Res = GetPromotedOp(N->getOperand(0));
-    break;
-  }
-
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-  assert(Res.getValueType().getSizeInBits() >= NVT.getSizeInBits() &&
-         "Truncation doesn't make sense!");
-  if (Res.getValueType() == NVT)
-    return Res;
-
-  // Truncate to NVT instead of VT
-  return DAG.getNode(ISD::TRUNCATE, NVT, Res);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_INT_EXTEND(SDNode *N) {
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-
-  if (getTypeAction(N->getOperand(0).getValueType()) == Promote) {
-    SDOperand Res = GetPromotedOp(N->getOperand(0));
-    assert(Res.getValueType().getSizeInBits() <= NVT.getSizeInBits() &&
-           "Extension doesn't make sense!");
-
-    // If the result and operand types are the same after promotion, simplify
-    // to an in-register extension.
-    if (NVT == Res.getValueType()) {
-      // The high bits are not guaranteed to be anything.  Insert an extend.
-      if (N->getOpcode() == ISD::SIGN_EXTEND)
-        return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res,
-                           DAG.getValueType(N->getOperand(0).getValueType()));
-      if (N->getOpcode() == ISD::ZERO_EXTEND)
-        return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType());
-      assert(N->getOpcode() == ISD::ANY_EXTEND && "Unknown integer extension!");
-      return Res;
-    }
-  }
-
-  // Otherwise, just extend the original operand all the way to the larger type.
-  return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_FP_ROUND(SDNode *N) {
-  // NOTE: Assumes input is legal.
-  if (N->getConstantOperandVal(1) == 0) 
-    return DAG.getNode(ISD::FP_ROUND_INREG, N->getOperand(0).getValueType(),
-                       N->getOperand(0), DAG.getValueType(N->getValueType(0)));
-  // If the precision discard isn't needed, just return the operand unrounded.
-  return N->getOperand(0);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_FP_TO_XINT(SDNode *N) {
-  SDOperand Op = N->getOperand(0);
-  // If the operand needed to be promoted, do so now.
-  if (getTypeAction(Op.getValueType()) == Promote)
-    // The input result is prerounded, so we don't have to do anything special.
-    Op = GetPromotedOp(Op);
-  
-  unsigned NewOpc = N->getOpcode();
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-  
-  // If we're promoting a UINT to a larger size, check to see if the new node
-  // will be legal.  If it isn't, check to see if FP_TO_SINT is legal, since
-  // we can use that instead.  This allows us to generate better code for
-  // FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not
-  // legal, such as PowerPC.
-  if (N->getOpcode() == ISD::FP_TO_UINT) {
-    if (!TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) &&
-        (TLI.isOperationLegal(ISD::FP_TO_SINT, NVT) ||
-         TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom))
-      NewOpc = ISD::FP_TO_SINT;
-  }
-
-  return DAG.getNode(NewOpc, NVT, Op);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SETCC(SDNode *N) {
-  assert(isTypeLegal(TLI.getSetCCResultType(N->getOperand(0)))
-         && "SetCC type is not legal??");
-  return DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(N->getOperand(0)),
-                     N->getOperand(0), N->getOperand(1), N->getOperand(2));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_LOAD(LoadSDNode *N) {
-  // FIXME: Add support for indexed loads.
-  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
-  ISD::LoadExtType ExtType =
-    ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType();
-  SDOperand Res = DAG.getExtLoad(ExtType, NVT, N->getChain(), N->getBasePtr(),
-                                 N->getSrcValue(), N->getSrcValueOffset(),
-                                 N->getMemoryVT(), N->isVolatile(),
-                                 N->getAlignment());
-
-  // Legalized the chain result - switch anything that used the old chain to
-  // use the new one.
-  ReplaceValueWith(SDOperand(N, 1), Res.getValue(1));
-  return Res;
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_BUILD_PAIR(SDNode *N) {
-  // The pair element type may be legal, or may not promote to the same type as
-  // the result, for example i14 = BUILD_PAIR (i7, i7).  Handle all cases.
-  return DAG.getNode(ISD::ANY_EXTEND,
-                     TLI.getTypeToTransformTo(N->getValueType(0)),
-                     JoinIntegers(N->getOperand(0), N->getOperand(1)));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_BIT_CONVERT(SDNode *N) {
-  SDOperand InOp = N->getOperand(0);
-  MVT InVT = InOp.getValueType();
-  MVT NInVT = TLI.getTypeToTransformTo(InVT);
-  MVT OutVT = TLI.getTypeToTransformTo(N->getValueType(0));
-
-  switch (getTypeAction(InVT)) {
-  default:
-    assert(false && "Unknown type action!");
-    break;
-  case Legal:
-    break;
-  case Promote:
-    if (OutVT.getSizeInBits() == NInVT.getSizeInBits())
-      // The input promotes to the same size.  Convert the promoted value.
-      return DAG.getNode(ISD::BIT_CONVERT, OutVT, GetPromotedOp(InOp));
-    break;
-  case Expand:
-    break;
-  case FloatToInt:
-    // Promote the integer operand by hand.
-    return DAG.getNode(ISD::ANY_EXTEND, OutVT, GetIntegerOp(InOp));
-  case Scalarize:
-    // Convert the element to an integer and promote it by hand.
-    return DAG.getNode(ISD::ANY_EXTEND, OutVT,
-                       BitConvertToInteger(GetScalarizedOp(InOp)));
-  case Split:
-    // For example, i32 = BIT_CONVERT v2i16 on alpha.  Convert the split
-    // pieces of the input into integers and reassemble in the final type.
-    SDOperand Lo, Hi;
-    GetSplitOp(N->getOperand(0), Lo, Hi);
-    Lo = BitConvertToInteger(Lo);
-    Hi = BitConvertToInteger(Hi);
-
-    if (TLI.isBigEndian())
-      std::swap(Lo, Hi);
-
-    InOp = DAG.getNode(ISD::ANY_EXTEND,
-                       MVT::getIntegerVT(OutVT.getSizeInBits()),
-                       JoinIntegers(Lo, Hi));
-    return DAG.getNode(ISD::BIT_CONVERT, OutVT, InOp);
-  }
-
-  // Otherwise, lower the bit-convert to a store/load from the stack, then
-  // promote the load.
-  SDOperand Op = CreateStackStoreLoad(InOp, N->getValueType(0));
-  return PromoteResult_LOAD(cast<LoadSDNode>(Op.Val));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SimpleIntBinOp(SDNode *N) {
-  // The input may have strange things in the top bits of the registers, but
-  // these operations don't care.  They may have weird bits going out, but
-  // that too is okay if they are integer operations.
-  SDOperand LHS = GetPromotedOp(N->getOperand(0));
-  SDOperand RHS = GetPromotedOp(N->getOperand(1));
-  return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SDIV(SDNode *N) {
-  // Sign extend the input.
-  SDOperand LHS = GetPromotedOp(N->getOperand(0));
-  SDOperand RHS = GetPromotedOp(N->getOperand(1));
-  MVT VT = N->getValueType(0);
-  LHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, LHS.getValueType(), LHS,
-                    DAG.getValueType(VT));
-  RHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, RHS.getValueType(), RHS,
-                    DAG.getValueType(VT));
-
-  return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_UDIV(SDNode *N) {
-  // Zero extend the input.
-  SDOperand LHS = GetPromotedOp(N->getOperand(0));
-  SDOperand RHS = GetPromotedOp(N->getOperand(1));
-  MVT VT = N->getValueType(0);
-  LHS = DAG.getZeroExtendInReg(LHS, VT);
-  RHS = DAG.getZeroExtendInReg(RHS, VT);
-
-  return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SHL(SDNode *N) {
-  return DAG.getNode(ISD::SHL, TLI.getTypeToTransformTo(N->getValueType(0)),
-                     GetPromotedOp(N->getOperand(0)), N->getOperand(1));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SRA(SDNode *N) {
-  // The input value must be properly sign extended.
-  MVT VT = N->getValueType(0);
-  MVT NVT = TLI.getTypeToTransformTo(VT);
-  SDOperand Res = GetPromotedOp(N->getOperand(0));
-  Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, DAG.getValueType(VT));
-  return DAG.getNode(ISD::SRA, NVT, Res, N->getOperand(1));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SRL(SDNode *N) {
-  // The input value must be properly zero extended.
-  MVT VT = N->getValueType(0);
-  MVT NVT = TLI.getTypeToTransformTo(VT);
-  SDOperand Res = GetPromotedZExtOp(N->getOperand(0));
-  return DAG.getNode(ISD::SRL, NVT, Res, N->getOperand(1));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SELECT(SDNode *N) {
-  SDOperand LHS = GetPromotedOp(N->getOperand(1));
-  SDOperand RHS = GetPromotedOp(N->getOperand(2));
-  return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_SELECT_CC(SDNode *N) {
-  SDOperand LHS = GetPromotedOp(N->getOperand(2));
-  SDOperand RHS = GetPromotedOp(N->getOperand(3));
-  return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0),
-                     N->getOperand(1), LHS, RHS, N->getOperand(4));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_CTLZ(SDNode *N) {
-  SDOperand Op = GetPromotedOp(N->getOperand(0));
-  MVT OVT = N->getValueType(0);
-  MVT NVT = Op.getValueType();
-  // Zero extend to the promoted type and do the count there.
-  Op = DAG.getNode(ISD::CTLZ, NVT, DAG.getZeroExtendInReg(Op, OVT));
-  // Subtract off the extra leading bits in the bigger type.
-  return DAG.getNode(ISD::SUB, NVT, Op,
-                     DAG.getConstant(NVT.getSizeInBits() -
-                                     OVT.getSizeInBits(), NVT));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_CTPOP(SDNode *N) {
-  SDOperand Op = GetPromotedOp(N->getOperand(0));
-  MVT OVT = N->getValueType(0);
-  MVT NVT = Op.getValueType();
-  // Zero extend to the promoted type and do the count there.
-  return DAG.getNode(ISD::CTPOP, NVT, DAG.getZeroExtendInReg(Op, OVT));
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_CTTZ(SDNode *N) {
-  SDOperand Op = GetPromotedOp(N->getOperand(0));
-  MVT OVT = N->getValueType(0);
-  MVT NVT = Op.getValueType();
-  // The count is the same in the promoted type except if the original
-  // value was zero.  This can be handled by setting the bit just off
-  // the top of the original type.
-  Op = DAG.getNode(ISD::OR, NVT, Op,
-                   // FIXME: Do this using an APINT constant.
-                   DAG.getConstant(1UL << OVT.getSizeInBits(), NVT));
-  return DAG.getNode(ISD::CTTZ, NVT, Op);
-}
-
-SDOperand DAGTypeLegalizer::PromoteResult_EXTRACT_VECTOR_ELT(SDNode *N) {
-  MVT OldVT = N->getValueType(0);
-  SDOperand OldVec = N->getOperand(0);
-  unsigned OldElts = OldVec.getValueType().getVectorNumElements();
-
-  if (OldElts == 1) {
-    assert(!isTypeLegal(OldVec.getValueType()) &&
-           "Legal one-element vector of a type needing promotion!");
-    // It is tempting to follow GetScalarizedOp by a call to GetPromotedOp,
-    // but this would be wrong because the scalarized value may not yet have
-    // been processed.
-    return DAG.getNode(ISD::ANY_EXTEND, TLI.getTypeToTransformTo(OldVT),
-                       GetScalarizedOp(OldVec));
-  }
-
-  // Convert to a vector half as long with an element type of twice the width,
-  // for example <4 x i16> -> <2 x i32>.
-  assert(!(OldElts & 1) && "Odd length vectors not supported!");
-  MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits());
-  assert(OldVT.isSimple() && NewVT.isSimple());
-
-  SDOperand NewVec = DAG.getNode(ISD::BIT_CONVERT,
-                                 MVT::getVectorVT(NewVT, OldElts / 2),
-                                 OldVec);
-
-  // Extract the element at OldIdx / 2 from the new vector.
-  SDOperand OldIdx = N->getOperand(1);
-  SDOperand NewIdx = DAG.getNode(ISD::SRL, OldIdx.getValueType(), OldIdx,
-                                 DAG.getConstant(1, TLI.getShiftAmountTy()));
-  SDOperand Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, NewIdx);
-
-  // Select the appropriate half of the element: Lo if OldIdx was even,
-  // Hi if it was odd.
-  SDOperand Lo = Elt;
-  SDOperand Hi = DAG.getNode(ISD::SRL, NewVT, Elt,
-                             DAG.getConstant(OldVT.getSizeInBits(),
-                                             TLI.getShiftAmountTy()));
-  if (TLI.isBigEndian())
-    std::swap(Lo, Hi);
-
-  SDOperand Odd = DAG.getNode(ISD::AND, OldIdx.getValueType(), OldIdx,
-                              DAG.getConstant(1, TLI.getShiftAmountTy()));
-  return DAG.getNode(ISD::SELECT, NewVT, Odd, Hi, Lo);
-}
-
-//===----------------------------------------------------------------------===//
-//  Operand Promotion
-//===----------------------------------------------------------------------===//
-
-/// PromoteOperand - This method is called when the specified operand of the
-/// specified node is found to need promotion.  At this point, all of the result
-/// types of the node are known to be legal, but other operands of the node may
-/// need promotion or expansion as well as the specified one.
-bool DAGTypeLegalizer::PromoteOperand(SDNode *N, unsigned OpNo) {
-  DEBUG(cerr << "Promote node operand: "; N->dump(&DAG); cerr << "\n");
-  SDOperand Res;
-  switch (N->getOpcode()) {
-    default:
-#ifndef NDEBUG
-    cerr << "PromoteOperand Op #" << OpNo << ": ";
-    N->dump(&DAG); cerr << "\n";
-#endif
-    assert(0 && "Do not know how to promote this operator's operand!");
-    abort();
-    
-  case ISD::ANY_EXTEND:  Res = PromoteOperand_ANY_EXTEND(N); break;
-  case ISD::ZERO_EXTEND: Res = PromoteOperand_ZERO_EXTEND(N); break;
-  case ISD::SIGN_EXTEND: Res = PromoteOperand_SIGN_EXTEND(N); break;
-  case ISD::TRUNCATE:    Res = PromoteOperand_TRUNCATE(N); break;
-  case ISD::FP_EXTEND:   Res = PromoteOperand_FP_EXTEND(N); break;
-  case ISD::FP_ROUND:    Res = PromoteOperand_FP_ROUND(N); break;
-  case ISD::SINT_TO_FP:
-  case ISD::UINT_TO_FP:  Res = PromoteOperand_INT_TO_FP(N); break;
-  case ISD::BUILD_PAIR:  Res = PromoteOperand_BUILD_PAIR(N); break;
-
-  case ISD::SELECT:      Res = PromoteOperand_SELECT(N, OpNo); break;
-  case ISD::BRCOND:      Res = PromoteOperand_BRCOND(N, OpNo); break;
-  case ISD::BR_CC:       Res = PromoteOperand_BR_CC(N, OpNo); break;
-  case ISD::SETCC:       Res = PromoteOperand_SETCC(N, OpNo); break;
-
-  case ISD::STORE:       Res = PromoteOperand_STORE(cast<StoreSDNode>(N),
-                                                    OpNo); break;
-
-  case ISD::BUILD_VECTOR: Res = PromoteOperand_BUILD_VECTOR(N); break;
-  case ISD::INSERT_VECTOR_ELT:
-    Res = PromoteOperand_INSERT_VECTOR_ELT(N, OpNo);
-    break;
-
-  case ISD::RET:         Res = PromoteOperand_RET(N, OpNo); break;
-
-  case ISD::MEMBARRIER:  Res = PromoteOperand_MEMBARRIER(N); break;
-  }
-
-  // If the result is null, the sub-method took care of registering results etc.
-  if (!Res.Val) return false;
-  // If the result is N, the sub-method updated N in place.
-  if (Res.Val == N) {
-    // Mark N as new and remark N and its operands.  This allows us to correctly
-    // revisit N if it needs another step of promotion and allows us to visit
-    // any new operands to N.
-    ReanalyzeNode(N);
-    return true;
-  }
-
-  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
-         "Invalid operand expansion");
-  
-  ReplaceValueWith(SDOperand(N, 0), Res);
-  return false;
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_ANY_EXTEND(SDNode *N) {
-  SDOperand Op = GetPromotedOp(N->getOperand(0));
-  return DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_ZERO_EXTEND(SDNode *N) {
-  SDOperand Op = GetPromotedOp(N->getOperand(0));
-  Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
-  return DAG.getZeroExtendInReg(Op, N->getOperand(0).getValueType());
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_SIGN_EXTEND(SDNode *N) {
-  SDOperand Op = GetPromotedOp(N->getOperand(0));
-  Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op);
-  return DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(),
-                     Op, DAG.getValueType(N->getOperand(0).getValueType()));
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_TRUNCATE(SDNode *N) {
-  SDOperand Op = GetPromotedOp(N->getOperand(0));
-  return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), Op);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_FP_EXTEND(SDNode *N) {
-  SDOperand Op = GetPromotedOp(N->getOperand(0));
-  return DAG.getNode(ISD::FP_EXTEND, N->getValueType(0), Op);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_FP_ROUND(SDNode *N) {
-  SDOperand Op = GetPromotedOp(N->getOperand(0));
-  return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Op,
-                     DAG.getIntPtrConstant(0));
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_INT_TO_FP(SDNode *N) {
-  SDOperand In = GetPromotedOp(N->getOperand(0));
-  MVT OpVT = N->getOperand(0).getValueType();
-  if (N->getOpcode() == ISD::UINT_TO_FP)
-    In = DAG.getZeroExtendInReg(In, OpVT);
-  else
-    In = DAG.getNode(ISD::SIGN_EXTEND_INREG, In.getValueType(),
-                     In, DAG.getValueType(OpVT));
-  
-  return DAG.UpdateNodeOperands(SDOperand(N, 0), In);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_BUILD_PAIR(SDNode *N) {
-  // Since the result type is legal, the operands must promote to it.
-  MVT OVT = N->getOperand(0).getValueType();
-  SDOperand Lo = GetPromotedOp(N->getOperand(0));
-  SDOperand Hi = GetPromotedOp(N->getOperand(1));
-  assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?");
-
-  Lo = DAG.getZeroExtendInReg(Lo, OVT);
-  Hi = DAG.getNode(ISD::SHL, N->getValueType(0), Hi,
-                   DAG.getConstant(OVT.getSizeInBits(),
-                                   TLI.getShiftAmountTy()));
-  return DAG.getNode(ISD::OR, N->getValueType(0), Lo, Hi);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_SELECT(SDNode *N, unsigned OpNo) {
-  assert(OpNo == 0 && "Only know how to promote condition");
-  SDOperand Cond = GetPromotedOp(N->getOperand(0));  // Promote the condition.
-
-  // The top bits of the promoted condition are not necessarily zero, ensure
-  // that the value is properly zero extended.
-  unsigned BitWidth = Cond.getValueSizeInBits();
-  if (!DAG.MaskedValueIsZero(Cond, 
-                             APInt::getHighBitsSet(BitWidth, BitWidth-1)))
-    Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
-
-  // The chain (Op#0) and basic block destination (Op#2) are always legal types.
-  return DAG.UpdateNodeOperands(SDOperand(N, 0), Cond, N->getOperand(1),
-                                N->getOperand(2));
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_BRCOND(SDNode *N, unsigned OpNo) {
-  assert(OpNo == 1 && "only know how to promote condition");
-  SDOperand Cond = GetPromotedOp(N->getOperand(1));  // Promote the condition.
-  
-  // The top bits of the promoted condition are not necessarily zero, ensure
-  // that the value is properly zero extended.
-  unsigned BitWidth = Cond.getValueSizeInBits();
-  if (!DAG.MaskedValueIsZero(Cond, 
-                             APInt::getHighBitsSet(BitWidth, BitWidth-1)))
-    Cond = DAG.getZeroExtendInReg(Cond, MVT::i1);
-
-  // The chain (Op#0) and basic block destination (Op#2) are always legal types.
-  return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0), Cond,
-                                N->getOperand(2));
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_BR_CC(SDNode *N, unsigned OpNo) {
-  assert(OpNo == 2 && "Don't know how to promote this operand");
-  
-  SDOperand LHS = N->getOperand(2);
-  SDOperand RHS = N->getOperand(3);
-  PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(1))->get());
-  
-  // The chain (Op#0), CC (#1) and basic block destination (Op#4) are always
-  // legal types.
-  return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
-                                N->getOperand(1), LHS, RHS, N->getOperand(4));
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_SETCC(SDNode *N, unsigned OpNo) {
-  assert(OpNo == 0 && "Don't know how to promote this operand");
-
-  SDOperand LHS = N->getOperand(0);
-  SDOperand RHS = N->getOperand(1);
-  PromoteSetCCOperands(LHS, RHS, cast<CondCodeSDNode>(N->getOperand(2))->get());
-
-  // The CC (#2) is always legal.
-  return DAG.UpdateNodeOperands(SDOperand(N, 0), LHS, RHS, N->getOperand(2));
-}
-
-/// PromoteSetCCOperands - Promote the operands of a comparison.  This code is
-/// shared among BR_CC, SELECT_CC, and SETCC handlers.
-void DAGTypeLegalizer::PromoteSetCCOperands(SDOperand &NewLHS,SDOperand &NewRHS,
-                                            ISD::CondCode CCCode) {
-  MVT VT = NewLHS.getValueType();
-  
-  // Get the promoted values.
-  NewLHS = GetPromotedOp(NewLHS);
-  NewRHS = GetPromotedOp(NewRHS);
-  
-  // If this is an FP compare, the operands have already been extended.
-  if (!NewLHS.getValueType().isInteger())
-    return;
-  
-  // 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 (CCCode) {
-  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.
-    NewLHS = DAG.getZeroExtendInReg(NewLHS, VT);
-    NewRHS = DAG.getZeroExtendInReg(NewRHS, VT);
-    return;
-  case ISD::SETGE:
-  case ISD::SETGT:
-  case ISD::SETLT:
-  case ISD::SETLE:
-    NewLHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewLHS.getValueType(), NewLHS,
-                         DAG.getValueType(VT));
-    NewRHS = DAG.getNode(ISD::SIGN_EXTEND_INREG, NewRHS.getValueType(), NewRHS,
-                         DAG.getValueType(VT));
-    return;
-  }
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_STORE(StoreSDNode *N, unsigned OpNo){
-  // FIXME: Add support for indexed stores.
-  SDOperand Ch = N->getChain(), Ptr = N->getBasePtr();
-  int SVOffset = N->getSrcValueOffset();
-  unsigned Alignment = N->getAlignment();
-  bool isVolatile = N->isVolatile();
-  
-  SDOperand Val = GetPromotedOp(N->getValue());  // Get promoted value.
-
-  assert(!N->isTruncatingStore() && "Cannot promote this store operand!");
-  
-  // Truncate the value and store the result.
-  return DAG.getTruncStore(Ch, Val, Ptr, N->getSrcValue(),
-                           SVOffset, N->getMemoryVT(),
-                           isVolatile, Alignment);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_BUILD_VECTOR(SDNode *N) {
-  // The vector type is legal but the element type is not.  This implies
-  // that the vector is a power-of-two in length and that the element
-  // type does not have a strange size (eg: it is not i1).
-  MVT VecVT = N->getValueType(0);
-  unsigned NumElts = VecVT.getVectorNumElements();
-  assert(!(NumElts & 1) && "Legal vector of one illegal element?");
-
-  // Build a vector of half the length out of elements of twice the bitwidth.
-  // For example <4 x i16> -> <2 x i32>.
-  MVT OldVT = N->getOperand(0).getValueType();
-  MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits());
-  assert(OldVT.isSimple() && NewVT.isSimple());
-
-  std::vector<SDOperand> NewElts;
-  NewElts.reserve(NumElts/2);
-
-  for (unsigned i = 0; i < NumElts; i += 2) {
-    // Combine two successive elements into one promoted element.
-    SDOperand Lo = N->getOperand(i);
-    SDOperand Hi = N->getOperand(i+1);
-    if (TLI.isBigEndian())
-      std::swap(Lo, Hi);
-    NewElts.push_back(JoinIntegers(Lo, Hi));
-  }
-
-  SDOperand NewVec = DAG.getNode(ISD::BUILD_VECTOR,
-                                 MVT::getVectorVT(NewVT, NewElts.size()),
-                                 &NewElts[0], NewElts.size());
-
-  // Convert the new vector to the old vector type.
-  return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_INSERT_VECTOR_ELT(SDNode *N,
-                                                             unsigned OpNo) {
-  if (OpNo == 1) {
-    // Promote the inserted value.  This is valid because the type does not
-    // have to match the vector element type.
-
-    // Check that any extra bits introduced will be truncated away.
-    assert(N->getOperand(1).getValueType().getSizeInBits() >=
-           N->getValueType(0).getVectorElementType().getSizeInBits() &&
-           "Type of inserted value narrower than vector element type!");
-    return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
-                                  GetPromotedOp(N->getOperand(1)),
-                                  N->getOperand(2));
-  }
-
-  assert(OpNo == 2 && "Different operand and result vector types?");
-
-  // Promote the index.
-  SDOperand Idx = N->getOperand(2);
-  Idx = DAG.getZeroExtendInReg(GetPromotedOp(Idx), Idx.getValueType());
-  return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
-                                N->getOperand(1), Idx);
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_RET(SDNode *N, unsigned OpNo) {
-  assert(!(OpNo & 1) && "Return values should be legally typed!");
-  assert((N->getNumOperands() & 1) && "Wrong number of operands!");
-
-  // It's a flag.  Promote all the flags in one hit, as an optimization.
-  SmallVector<SDOperand, 8> NewValues(N->getNumOperands());
-  NewValues[0] = N->getOperand(0); // The chain
-  for (unsigned i = 1, e = N->getNumOperands(); i < e; i += 2) {
-    // The return value.
-    NewValues[i] = N->getOperand(i);
-
-    // The flag.
-    SDOperand Flag = N->getOperand(i + 1);
-    if (getTypeAction(Flag.getValueType()) == Promote)
-      // The promoted value may have rubbish in the new bits, but that
-      // doesn't matter because those bits aren't queried anyway.
-      Flag = GetPromotedOp(Flag);
-    NewValues[i + 1] = Flag;
-  }
-
-  return DAG.UpdateNodeOperands(SDOperand (N, 0),
-                                &NewValues[0], NewValues.size());
-}
-
-SDOperand DAGTypeLegalizer::PromoteOperand_MEMBARRIER(SDNode *N) {
-  SDOperand NewOps[6];
-  NewOps[0] = N->getOperand(0);
-  for (unsigned i = 1; i < array_lengthof(NewOps); ++i) {
-    SDOperand Flag = GetPromotedOp(N->getOperand(i));
-    NewOps[i] = DAG.getZeroExtendInReg(Flag, MVT::i1);
-  }
-  return DAG.UpdateNodeOperands(SDOperand (N, 0), NewOps,
-                                array_lengthof(NewOps));
-}

Removed: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp?rev=52407&view=auto

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesScalarize.cpp (removed)
@@ -1,233 +0,0 @@
-//===-- LegalizeTypesScalarize.cpp - Scalarization for LegalizeTypes ------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements scalarization support for LegalizeTypes.  Scalarization
-// is the act of changing a computation in an invalid single-element vector type
-// to be a computation in its scalar element type.  For example, implementing
-// <1 x f32> arithmetic in a scalar f32 register.  This is needed as a base case
-// when scalarizing vector arithmetic like <4 x f32>, which eventually
-// decomposes to scalars if the target doesn't support v4f32 or v2f32 types.
-//
-//===----------------------------------------------------------------------===//
-
-#include "LegalizeTypes.h"
-using namespace llvm;
-
-//===----------------------------------------------------------------------===//
-//  Result Vector Scalarization: <1 x ty> -> ty.
-//===----------------------------------------------------------------------===//
-
-void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) {
-  DEBUG(cerr << "Scalarize node result " << ResNo << ": "; N->dump(&DAG); 
-        cerr << "\n");
-  SDOperand R = SDOperand();
-  
-  // FIXME: Custom lowering for scalarization?
-#if 0
-  // See if the target wants to custom expand this node.
-  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == 
-      TargetLowering::Custom) {
-    // If the target wants to, allow it to lower this itself.
-    if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
-      // Everything that once used N now uses P.  We are guaranteed that the
-      // result value types of N and the result value types of P match.
-      ReplaceNodeWith(N, P);
-      return;
-    }
-  }
-#endif
-  
-  switch (N->getOpcode()) {
-  default:
-#ifndef NDEBUG
-    cerr << "ScalarizeResult #" << ResNo << ": ";
-    N->dump(&DAG); cerr << "\n";
-#endif
-    assert(0 && "Do not know how to scalarize the result of this operator!");
-    abort();
-    
-  case ISD::UNDEF:       R = ScalarizeRes_UNDEF(N); break;
-  case ISD::LOAD:        R = ScalarizeRes_LOAD(cast<LoadSDNode>(N)); break;
-  case ISD::ADD:
-  case ISD::FADD:
-  case ISD::SUB:
-  case ISD::FSUB:
-  case ISD::MUL:
-  case ISD::FMUL:
-  case ISD::SDIV:
-  case ISD::UDIV:
-  case ISD::FDIV:
-  case ISD::SREM:
-  case ISD::UREM:
-  case ISD::FREM:
-  case ISD::FPOW:
-  case ISD::AND:
-  case ISD::OR:
-  case ISD::XOR:         R = ScalarizeRes_BinOp(N); break;
-  case ISD::FNEG:
-  case ISD::FABS:
-  case ISD::FSQRT:
-  case ISD::FSIN:
-  case ISD::FCOS:              R = ScalarizeRes_UnaryOp(N); break;
-  case ISD::FPOWI:             R = ScalarizeRes_FPOWI(N); break;
-  case ISD::BUILD_VECTOR:      R = N->getOperand(0); break;
-  case ISD::INSERT_VECTOR_ELT: R = ScalarizeRes_INSERT_VECTOR_ELT(N); break;
-  case ISD::VECTOR_SHUFFLE:    R = ScalarizeRes_VECTOR_SHUFFLE(N); break;
-  case ISD::BIT_CONVERT:       R = ScalarizeRes_BIT_CONVERT(N); break;
-  case ISD::SELECT:            R = ScalarizeRes_SELECT(N); break;
-  }
-  
-  // If R is null, the sub-method took care of registering the result.
-  if (R.Val)
-    SetScalarizedOp(SDOperand(N, ResNo), R);
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_UNDEF(SDNode *N) {
-  return DAG.getNode(ISD::UNDEF, N->getValueType(0).getVectorElementType());
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_LOAD(LoadSDNode *N) {
-  // FIXME: Add support for indexed loads.
-  SDOperand Result = DAG.getLoad(N->getValueType(0).getVectorElementType(),
-                                 N->getChain(), N->getBasePtr(), 
-                                 N->getSrcValue(), N->getSrcValueOffset(),
-                                 N->isVolatile(), N->getAlignment());
-  
-  // Legalized the chain result - switch anything that used the old chain to
-  // use the new one.
-  ReplaceValueWith(SDOperand(N, 1), Result.getValue(1));
-  return Result;
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_BinOp(SDNode *N) {
-  SDOperand LHS = GetScalarizedOp(N->getOperand(0));
-  SDOperand RHS = GetScalarizedOp(N->getOperand(1));
-  return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_UnaryOp(SDNode *N) {
-  SDOperand Op = GetScalarizedOp(N->getOperand(0));
-  return DAG.getNode(N->getOpcode(), Op.getValueType(), Op);
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_FPOWI(SDNode *N) {
-  SDOperand Op = GetScalarizedOp(N->getOperand(0));
-  return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1));
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N) {
-  // The value to insert may have a wider type than the vector element type,
-  // so be sure to truncate it to the element type if necessary.
-  SDOperand Op = N->getOperand(1);
-  MVT EltVT = N->getValueType(0).getVectorElementType();
-  if (Op.getValueType().bitsGT(EltVT))
-    Op = DAG.getNode(ISD::TRUNCATE, EltVT, Op);
-  assert(Op.getValueType() == EltVT && "Invalid type for inserted value!");
-  return Op;
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_VECTOR_SHUFFLE(SDNode *N) {
-  // Figure out if the scalar is the LHS or RHS and return it.
-  SDOperand EltNum = N->getOperand(2).getOperand(0);
-  unsigned Op = cast<ConstantSDNode>(EltNum)->getValue() != 0;
-  return GetScalarizedOp(N->getOperand(Op));
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_BIT_CONVERT(SDNode *N) {
-  MVT NewVT = N->getValueType(0).getVectorElementType();
-  return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0));
-}
-
-SDOperand DAGTypeLegalizer::ScalarizeRes_SELECT(SDNode *N) {
-  SDOperand LHS = GetScalarizedOp(N->getOperand(1));
-  return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0), LHS,
-                     GetScalarizedOp(N->getOperand(2)));
-}
-
-
-//===----------------------------------------------------------------------===//
-//  Operand Vector Scalarization <1 x ty> -> ty.
-//===----------------------------------------------------------------------===//
-
-bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) {
-  DEBUG(cerr << "Scalarize node operand " << OpNo << ": "; N->dump(&DAG); 
-        cerr << "\n");
-  SDOperand Res(0, 0);
-  
-  // FIXME: Should we support custom lowering for scalarization?
-#if 0
-  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == 
-      TargetLowering::Custom)
-    Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
-#endif
-  
-  if (Res.Val == 0) {
-    switch (N->getOpcode()) {
-    default:
-#ifndef NDEBUG
-      cerr << "ScalarizeOperand Op #" << OpNo << ": ";
-      N->dump(&DAG); cerr << "\n";
-#endif
-      assert(0 && "Do not know how to scalarize this operator's operand!");
-      abort();
-      
-    case ISD::BIT_CONVERT:
-      Res = ScalarizeOp_BIT_CONVERT(N); break;
-
-    case ISD::EXTRACT_VECTOR_ELT:
-      Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N); break;
-
-    case ISD::STORE:
-      Res = ScalarizeOp_STORE(cast<StoreSDNode>(N), OpNo); break;
-    }
-  }
-  
-  // If the result is null, the sub-method took care of registering results etc.
-  if (!Res.Val) return false;
-  
-  // If the result is N, the sub-method updated N in place.  Check to see if any
-  // operands are new, and if so, mark them.
-  if (Res.Val == N) {
-    // Mark N as new and remark N and its operands.  This allows us to correctly
-    // revisit N if it needs another step of promotion and allows us to visit
-    // any new operands to N.
-    ReanalyzeNode(N);
-    return true;
-  }
-
-  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
-         "Invalid operand expansion");
-  
-  ReplaceValueWith(SDOperand(N, 0), Res);
-  return false;
-}
-
-/// ScalarizeOp_BIT_CONVERT - If the value to convert is a vector that needs
-/// to be scalarized, it must be <1 x ty>.  Convert the element instead.
-SDOperand DAGTypeLegalizer::ScalarizeOp_BIT_CONVERT(SDNode *N) {
-  SDOperand Elt = GetScalarizedOp(N->getOperand(0));
-  return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Elt);
-}
-
-/// ScalarizeOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to be
-/// scalarized, it must be <1 x ty>, so just return the element, ignoring the
-/// index.
-SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N) {
-  return GetScalarizedOp(N->getOperand(0));
-}
-
-/// ScalarizeOp_STORE - If the value to store is a vector that needs to be
-/// scalarized, it must be <1 x ty>.  Just store the element.
-SDOperand DAGTypeLegalizer::ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo) {
-  // FIXME: Add support for indexed stores.
-  assert(OpNo == 1 && "Do not know how to scalarize this operand!");
-  return DAG.getStore(N->getChain(), GetScalarizedOp(N->getOperand(1)),
-                      N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(),
-                      N->isVolatile(), N->getAlignment());
-}

Removed: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp?rev=52407&view=auto

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypesSplit.cpp (removed)
@@ -1,582 +0,0 @@
-//===-- LegalizeTypesSplit.cpp - Vector Splitting for LegalizeTypes -------===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements vector splitting support for LegalizeTypes.  Vector
-// splitting is the act of changing a computation in an invalid vector type to
-// be a computation in multiple vectors of a smaller type.  For example,
-// implementing <128 x f32> operations in terms of two <64 x f32> operations.
-//
-//===----------------------------------------------------------------------===//
-
-#include "LegalizeTypes.h"
-using namespace llvm;
-
-/// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a vector
-/// type that needs to be split.  This handles non-power of two vectors.
-static void GetSplitDestVTs(MVT InVT, MVT &Lo, MVT &Hi) {
-  MVT NewEltVT = InVT.getVectorElementType();
-  unsigned NumElements = InVT.getVectorNumElements();
-  if ((NumElements & (NumElements-1)) == 0) {  // Simple power of two vector.
-    NumElements >>= 1;
-    Lo = Hi =  MVT::getVectorVT(NewEltVT, NumElements);
-  } else {                                     // Non-power-of-two vectors.
-    unsigned NewNumElts_Lo = 1 << Log2_32(NumElements);
-    unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo;
-    Lo = MVT::getVectorVT(NewEltVT, NewNumElts_Lo);
-    Hi = MVT::getVectorVT(NewEltVT, NewNumElts_Hi);
-  }
-}
-
-
-//===----------------------------------------------------------------------===//
-//  Result Vector Splitting
-//===----------------------------------------------------------------------===//
-
-/// SplitResult - This method is called when the specified result of the
-/// specified node is found to need vector splitting.  At this point, the node
-/// may also have invalid operands or may have other results that need
-/// legalization, we just know that (at least) one result needs vector
-/// splitting.
-void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) {
-  DEBUG(cerr << "Split node result: "; N->dump(&DAG); cerr << "\n");
-  SDOperand Lo, Hi;
-  
-#if 0
-  // See if the target wants to custom expand this node.
-  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == 
-      TargetLowering::Custom) {
-    // If the target wants to, allow it to lower this itself.
-    if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
-      // Everything that once used N now uses P.  We are guaranteed that the
-      // result value types of N and the result value types of P match.
-      ReplaceNodeWith(N, P);
-      return;
-    }
-  }
-#endif
-  
-  switch (N->getOpcode()) {
-  default:
-#ifndef NDEBUG
-    cerr << "SplitResult #" << ResNo << ": ";
-    N->dump(&DAG); cerr << "\n";
-#endif
-    assert(0 && "Do not know how to split the result of this operator!");
-    abort();
-    
-  case ISD::UNDEF:            SplitRes_UNDEF(N, Lo, Hi); break;
-  case ISD::LOAD:             SplitRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
-  case ISD::BUILD_PAIR:       SplitRes_BUILD_PAIR(N, Lo, Hi); break;
-  case ISD::INSERT_VECTOR_ELT:SplitRes_INSERT_VECTOR_ELT(N, Lo, Hi); break;
-  case ISD::VECTOR_SHUFFLE:   SplitRes_VECTOR_SHUFFLE(N, Lo, Hi); break;
-  case ISD::BUILD_VECTOR:     SplitRes_BUILD_VECTOR(N, Lo, Hi); break;
-  case ISD::CONCAT_VECTORS:   SplitRes_CONCAT_VECTORS(N, Lo, Hi); break;
-  case ISD::BIT_CONVERT:      SplitRes_BIT_CONVERT(N, Lo, Hi); break;
-  case ISD::CTTZ:
-  case ISD::CTLZ:
-  case ISD::CTPOP:
-  case ISD::FNEG:
-  case ISD::FABS:
-  case ISD::FSQRT:
-  case ISD::FSIN:
-  case ISD::FCOS:
-  case ISD::FP_TO_SINT:
-  case ISD::FP_TO_UINT:
-  case ISD::SINT_TO_FP:
-  case ISD::UINT_TO_FP:       SplitRes_UnOp(N, Lo, Hi); break;
-  case ISD::ADD:
-  case ISD::SUB:
-  case ISD::MUL:
-  case ISD::FADD:
-  case ISD::FSUB:
-  case ISD::FMUL:
-  case ISD::SDIV:
-  case ISD::UDIV:
-  case ISD::FDIV:
-  case ISD::FPOW:
-  case ISD::AND:
-  case ISD::OR:
-  case ISD::XOR:
-  case ISD::UREM:
-  case ISD::SREM:
-  case ISD::FREM:             SplitRes_BinOp(N, Lo, Hi); break;
-  case ISD::FPOWI:            SplitRes_FPOWI(N, Lo, Hi); break;
-  case ISD::SELECT:           SplitRes_SELECT(N, Lo, Hi); break;
-  }
-  
-  // If Lo/Hi is null, the sub-method took care of registering results etc.
-  if (Lo.Val)
-    SetSplitOp(SDOperand(N, ResNo), Lo, Hi);
-}
-
-void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
-  MVT LoVT, HiVT;
-  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
-
-  Lo = DAG.getNode(ISD::UNDEF, LoVT);
-  Hi = DAG.getNode(ISD::UNDEF, HiVT);
-}
-
-void DAGTypeLegalizer::SplitRes_LOAD(LoadSDNode *LD, 
-                                     SDOperand &Lo, SDOperand &Hi) {
-  // FIXME: Add support for indexed loads.
-  MVT LoVT, HiVT;
-  GetSplitDestVTs(LD->getValueType(0), LoVT, HiVT);
-  
-  SDOperand Ch = LD->getChain();
-  SDOperand Ptr = LD->getBasePtr();
-  const Value *SV = LD->getSrcValue();
-  int SVOffset = LD->getSrcValueOffset();
-  unsigned Alignment = LD->getAlignment();
-  bool isVolatile = LD->isVolatile();
-  
-  Lo = DAG.getLoad(LoVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
-  unsigned IncrementSize = LoVT.getSizeInBits()/8;
-  Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                    DAG.getIntPtrConstant(IncrementSize));
-  SVOffset += IncrementSize;
-  Alignment = MinAlign(Alignment, IncrementSize);
-  Hi = DAG.getLoad(HiVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
-  
-  // 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));
-  
-  // Legalized the chain result - switch anything that used the old chain to
-  // use the new one.
-  ReplaceValueWith(SDOperand(LD, 1), TF);
-}
-
-void DAGTypeLegalizer::SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo,
-                                           SDOperand &Hi) {
-  Lo = N->getOperand(0);
-  Hi = N->getOperand(1);
-}
-
-void DAGTypeLegalizer::SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo,
-                                                  SDOperand &Hi) {
-  SDOperand Vec = N->getOperand(0);
-  SDOperand Elt = N->getOperand(1);
-  SDOperand Idx = N->getOperand(2);
-  GetSplitOp(Vec, Lo, Hi);
-
-  if (ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx)) {
-    unsigned IdxVal = CIdx->getValue();
-    unsigned LoNumElts = Lo.getValueType().getVectorNumElements();
-    if (IdxVal < LoNumElts)
-      Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, Lo.getValueType(), Lo, Elt, Idx);
-    else
-      Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, Hi.getValueType(), Hi, Elt,
-                       DAG.getIntPtrConstant(IdxVal - LoNumElts));
-    return;
-  }
-
-  // Spill the vector to the stack.
-  MVT VecVT = Vec.getValueType();
-  SDOperand StackPtr = DAG.CreateStackTemporary(VecVT);
-  SDOperand Store = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0);
-
-  // Store the new element.
-  SDOperand EltPtr = GetVectorElementPointer(StackPtr,
-                                             VecVT.getVectorElementType(), Idx);
-  Store = DAG.getStore(Store, Elt, EltPtr, NULL, 0);
-
-  // Reload the vector from the stack.
-  SDOperand Load = DAG.getLoad(VecVT, Store, StackPtr, NULL, 0);
-
-  // Split it.
-  SplitRes_LOAD(cast<LoadSDNode>(Load.Val), Lo, Hi);
-}
-
-void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N, 
-                                               SDOperand &Lo, SDOperand &Hi) {
-  // Build the low part.
-  SDOperand Mask = N->getOperand(2);
-  SmallVector<SDOperand, 16> Ops;
-  MVT LoVT, HiVT;
-  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
-  MVT EltVT = LoVT.getVectorElementType();
-  unsigned LoNumElts = LoVT.getVectorNumElements();
-  unsigned NumElements = Mask.getNumOperands();
-
-  // Insert all of the elements from the input that are needed.  We use 
-  // buildvector of extractelement here because the input vectors will have
-  // to be legalized, so this makes the code simpler.
-  for (unsigned i = 0; i != LoNumElts; ++i) {
-    unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
-    SDOperand InVec = N->getOperand(0);
-    if (Idx >= NumElements) {
-      InVec = N->getOperand(1);
-      Idx -= NumElements;
-    }
-    Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InVec,
-                              DAG.getIntPtrConstant(Idx)));
-  }
-  Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &Ops[0], Ops.size());
-  Ops.clear();
-  
-  for (unsigned i = LoNumElts; i != NumElements; ++i) {
-    unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
-    SDOperand InVec = N->getOperand(0);
-    if (Idx >= NumElements) {
-      InVec = N->getOperand(1);
-      Idx -= NumElements;
-    }
-    Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InVec,
-                              DAG.getIntPtrConstant(Idx)));
-  }
-  Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &Ops[0], Ops.size());
-}
-
-void DAGTypeLegalizer::SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo, 
-                                             SDOperand &Hi) {
-  MVT LoVT, HiVT;
-  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
-  unsigned LoNumElts = LoVT.getVectorNumElements();
-  SmallVector<SDOperand, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts);
-  Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &LoOps[0], LoOps.size());
-  
-  SmallVector<SDOperand, 8> HiOps(N->op_begin()+LoNumElts, N->op_end());
-  Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &HiOps[0], HiOps.size());
-}
-
-void DAGTypeLegalizer::SplitRes_CONCAT_VECTORS(SDNode *N, 
-                                               SDOperand &Lo, SDOperand &Hi) {
-  // FIXME: Handle non-power-of-two vectors?
-  unsigned NumSubvectors = N->getNumOperands() / 2;
-  if (NumSubvectors == 1) {
-    Lo = N->getOperand(0);
-    Hi = N->getOperand(1);
-    return;
-  }
-
-  MVT LoVT, HiVT;
-  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
-
-  SmallVector<SDOperand, 8> LoOps(N->op_begin(), N->op_begin()+NumSubvectors);
-  Lo = DAG.getNode(ISD::CONCAT_VECTORS, LoVT, &LoOps[0], LoOps.size());
-    
-  SmallVector<SDOperand, 8> HiOps(N->op_begin()+NumSubvectors, N->op_end());
-  Hi = DAG.getNode(ISD::CONCAT_VECTORS, HiVT, &HiOps[0], HiOps.size());
-}
-
-void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N, 
-                                            SDOperand &Lo, SDOperand &Hi) {
-  // We know the result is a vector.  The input may be either a vector or a
-  // scalar value.
-  MVT LoVT, HiVT;
-  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
-
-  SDOperand InOp = N->getOperand(0);
-  MVT InVT = InOp.getValueType();
-
-  // Handle some special cases efficiently.
-  switch (getTypeAction(InVT)) {
-  default:
-    assert(false && "Unknown type action!");
-  case Legal:
-  case FloatToInt:
-  case Promote:
-  case Scalarize:
-    break;
-  case Expand:
-    // A scalar to vector conversion, where the scalar needs expansion.
-    // If the vector is being split in two then we can just convert the
-    // expanded pieces.
-    if (LoVT == HiVT) {
-      GetExpandedOp(InOp, Lo, Hi);
-      if (TLI.isBigEndian())
-        std::swap(Lo, Hi);
-      Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
-      Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
-      return;
-    }
-    break;
-  case Split:
-    // If the input is a vector that needs to be split, convert each split
-    // piece of the input now.
-    GetSplitOp(InOp, Lo, Hi);
-    Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
-    Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
-    return;
-  }
-
-  // In the general case, convert the input to an integer and split it by hand.
-  MVT LoIntVT = MVT::getIntegerVT(LoVT.getSizeInBits());
-  MVT HiIntVT = MVT::getIntegerVT(HiVT.getSizeInBits());
-  if (TLI.isBigEndian())
-    std::swap(LoIntVT, HiIntVT);
-
-  SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT, Lo, Hi);
-
-  if (TLI.isBigEndian())
-    std::swap(Lo, Hi);
-  Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
-  Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
-}
-
-void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
-  SDOperand LHSLo, LHSHi;
-  GetSplitOp(N->getOperand(0), LHSLo, LHSHi);
-  SDOperand RHSLo, RHSHi;
-  GetSplitOp(N->getOperand(1), RHSLo, RHSHi);
-  
-  Lo = DAG.getNode(N->getOpcode(), LHSLo.getValueType(), LHSLo, RHSLo);
-  Hi = DAG.getNode(N->getOpcode(), LHSHi.getValueType(), LHSHi, RHSHi);
-}
-
-void DAGTypeLegalizer::SplitRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
-  // Get the dest types.  This doesn't always match input types, e.g. int_to_fp.
-  MVT LoVT, HiVT;
-  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
-
-  GetSplitOp(N->getOperand(0), Lo, Hi);
-  Lo = DAG.getNode(N->getOpcode(), LoVT, Lo);
-  Hi = DAG.getNode(N->getOpcode(), HiVT, Hi);
-}
-
-void DAGTypeLegalizer::SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
-  GetSplitOp(N->getOperand(0), Lo, Hi);
-  Lo = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Lo, N->getOperand(1));
-  Hi = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Hi, N->getOperand(1));
-}
-
-
-void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi){
-  SDOperand LL, LH, RL, RH;
-  GetSplitOp(N->getOperand(1), LL, LH);
-  GetSplitOp(N->getOperand(2), RL, RH);
-  
-  SDOperand Cond = N->getOperand(0);
-  Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), Cond, LL, RL);
-  Hi = DAG.getNode(ISD::SELECT, LH.getValueType(), Cond, LH, RH);
-}
-
-
-//===----------------------------------------------------------------------===//
-//  Operand Vector Splitting
-//===----------------------------------------------------------------------===//
-
-/// SplitOperand - This method is called when the specified operand of the
-/// specified node is found to need vector splitting.  At this point, all of the
-/// result types of the node are known to be legal, but other operands of the
-/// node may need legalization as well as the specified one.
-bool DAGTypeLegalizer::SplitOperand(SDNode *N, unsigned OpNo) {
-  DEBUG(cerr << "Split node operand: "; N->dump(&DAG); cerr << "\n");
-  SDOperand Res(0, 0);
-  
-#if 0
-  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == 
-      TargetLowering::Custom)
-    Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
-#endif
-  
-  if (Res.Val == 0) {
-    switch (N->getOpcode()) {
-    default:
-#ifndef NDEBUG
-      cerr << "SplitOperand Op #" << OpNo << ": ";
-      N->dump(&DAG); cerr << "\n";
-#endif
-      assert(0 && "Do not know how to split this operator's operand!");
-      abort();
-    case ISD::STORE: Res = SplitOp_STORE(cast<StoreSDNode>(N), OpNo); break;
-    case ISD::RET:   Res = SplitOp_RET(N, OpNo); break;
-
-    case ISD::BIT_CONVERT: Res = SplitOp_BIT_CONVERT(N); break;
-
-    case ISD::EXTRACT_VECTOR_ELT: Res = SplitOp_EXTRACT_VECTOR_ELT(N); break;
-    case ISD::EXTRACT_SUBVECTOR:  Res = SplitOp_EXTRACT_SUBVECTOR(N); break;
-    case ISD::VECTOR_SHUFFLE:     Res = SplitOp_VECTOR_SHUFFLE(N, OpNo); break;
-    }
-  }
-  
-  // If the result is null, the sub-method took care of registering results etc.
-  if (!Res.Val) return false;
-  
-  // If the result is N, the sub-method updated N in place.  Check to see if any
-  // operands are new, and if so, mark them.
-  if (Res.Val == N) {
-    // Mark N as new and remark N and its operands.  This allows us to correctly
-    // revisit N if it needs another step of promotion and allows us to visit
-    // any new operands to N.
-    ReanalyzeNode(N);
-    return true;
-  }
-
-  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
-         "Invalid operand expansion");
-  
-  ReplaceValueWith(SDOperand(N, 0), Res);
-  return false;
-}
-
-SDOperand DAGTypeLegalizer::SplitOp_STORE(StoreSDNode *N, unsigned OpNo) {
-  // FIXME: Add support for indexed stores.
-  assert(OpNo == 1 && "Can only split the stored value");
-  
-  SDOperand Ch  = N->getChain();
-  SDOperand Ptr = N->getBasePtr();
-  int SVOffset = N->getSrcValueOffset();
-  unsigned Alignment = N->getAlignment();
-  bool isVol = N->isVolatile();
-  SDOperand Lo, Hi;
-  GetSplitOp(N->getOperand(1), Lo, Hi);
-
-  unsigned IncrementSize = Lo.getValueType().getSizeInBits()/8;
-
-  Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, isVol, Alignment);
-  
-  // Increment the pointer to the other half.
-  Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
-                    DAG.getIntPtrConstant(IncrementSize));
-  
-  Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
-                    isVol, MinAlign(Alignment, IncrementSize));
-  return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
-}
-
-SDOperand DAGTypeLegalizer::SplitOp_RET(SDNode *N, unsigned OpNo) {
-  assert(N->getNumOperands() == 3 &&"Can only handle ret of one vector so far");
-  // FIXME: Returns of gcc generic vectors larger than a legal vector
-  // type should be returned by reference!
-  SDOperand Lo, Hi;
-  GetSplitOp(N->getOperand(1), Lo, Hi);
-
-  SDOperand Chain = N->getOperand(0);  // The chain.
-  SDOperand Sign = N->getOperand(2);  // Signness
-  
-  return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Sign, Hi, Sign);
-}
-
-SDOperand DAGTypeLegalizer::SplitOp_BIT_CONVERT(SDNode *N) {
-  // For example, i64 = BIT_CONVERT v4i16 on alpha.  Typically the vector will
-  // end up being split all the way down to individual components.  Convert the
-  // split pieces into integers and reassemble.
-  SDOperand Lo, Hi;
-  GetSplitOp(N->getOperand(0), Lo, Hi);
-  Lo = BitConvertToInteger(Lo);
-  Hi = BitConvertToInteger(Hi);
-
-  if (TLI.isBigEndian())
-    std::swap(Lo, Hi);
-
-  return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0),
-                     JoinIntegers(Lo, Hi));
-}
-
-SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_VECTOR_ELT(SDNode *N) {
-  SDOperand Vec = N->getOperand(0);
-  SDOperand Idx = N->getOperand(1);
-  MVT VecVT = Vec.getValueType();
-
-  if (isa<ConstantSDNode>(Idx)) {
-    uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getValue();
-    assert(IdxVal < VecVT.getVectorNumElements() && "Invalid vector index!");
-
-    SDOperand Lo, Hi;
-    GetSplitOp(Vec, Lo, Hi);
-
-    uint64_t LoElts = Lo.getValueType().getVectorNumElements();
-
-    if (IdxVal < LoElts)
-      return DAG.UpdateNodeOperands(SDOperand(N, 0), Lo, Idx);
-    else
-      return DAG.UpdateNodeOperands(SDOperand(N, 0), Hi,
-                                    DAG.getConstant(IdxVal - LoElts,
-                                                    Idx.getValueType()));
-  }
-
-  // Store the vector to the stack.
-  MVT EltVT = VecVT.getVectorElementType();
-  SDOperand StackPtr = DAG.CreateStackTemporary(VecVT);
-  SDOperand Store = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0);
-
-  // Load back the required element.
-  StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx);
-  return DAG.getLoad(EltVT, Store, StackPtr, NULL, 0);
-}
-
-SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_SUBVECTOR(SDNode *N) {
-  // We know that the extracted result type is legal.  For now, assume the index
-  // is a constant.
-  MVT SubVT = N->getValueType(0);
-  SDOperand Idx = N->getOperand(1);
-  SDOperand Lo, Hi;
-  GetSplitOp(N->getOperand(0), Lo, Hi);
-
-  uint64_t LoElts = Lo.getValueType().getVectorNumElements();
-  uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getValue();
-
-  if (IdxVal < LoElts) {
-    assert(IdxVal + SubVT.getVectorNumElements() <= LoElts &&
-           "Extracted subvector crosses vector split!");
-    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SubVT, Lo, Idx);
-  } else {
-    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SubVT, Hi,
-                       DAG.getConstant(IdxVal - LoElts, Idx.getValueType()));
-  }
-}
-
-SDOperand DAGTypeLegalizer::SplitOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo) {
-  assert(OpNo == 2 && "Shuffle source type differs from result type?");
-  SDOperand Mask = N->getOperand(2);
-  unsigned MaskLength = Mask.getValueType().getVectorNumElements();
-  unsigned LargestMaskEntryPlusOne = 2 * MaskLength;
-  unsigned MinimumBitWidth = Log2_32_Ceil(LargestMaskEntryPlusOne);
-
-  // Look for a legal vector type to place the mask values in.
-  // Note that there may not be *any* legal vector-of-integer
-  // type for which the element type is legal!
-  for (MVT::SimpleValueType EltVT = MVT::FIRST_INTEGER_VALUETYPE;
-       EltVT <= MVT::LAST_INTEGER_VALUETYPE;
-       // Integer values types are consecutively numbered.  Exploit this.
-       EltVT = MVT::SimpleValueType(EltVT + 1)) {
-
-    // Is the element type big enough to hold the values?
-    if (MVT(EltVT).getSizeInBits() < MinimumBitWidth)
-      // Nope.
-      continue;
-
-    // Is the vector type legal?
-    MVT VecVT = MVT::getVectorVT(EltVT, MaskLength);
-    if (!isTypeLegal(VecVT))
-      // Nope.
-      continue;
-
-    // If the element type is not legal, find a larger legal type to use for
-    // the BUILD_VECTOR operands.  This is an ugly hack, but seems to work!
-    // FIXME: The real solution is to change VECTOR_SHUFFLE into a variadic
-    // node where the shuffle mask is a list of integer operands, #2 .. #2+n.
-    for (MVT::SimpleValueType OpVT = EltVT; OpVT <= MVT::LAST_INTEGER_VALUETYPE;
-         // Integer values types are consecutively numbered.  Exploit this.
-         OpVT = MVT::SimpleValueType(OpVT + 1)) {
-      if (!isTypeLegal(OpVT))
-        continue;
-
-      // Success!  Rebuild the vector using the legal types.
-      SmallVector<SDOperand, 16> Ops(MaskLength);
-      for (unsigned i = 0; i < MaskLength; ++i) {
-        uint64_t Idx =
-          cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
-        Ops[i] = DAG.getConstant(Idx, OpVT);
-      }
-      return DAG.UpdateNodeOperands(SDOperand(N,0),
-                                    N->getOperand(0), N->getOperand(1),
-                                    DAG.getNode(ISD::BUILD_VECTOR,
-                                                VecVT, &Ops[0], Ops.size()));
-    }
-
-    // Continuing is pointless - failure is certain.
-    break;
-  }
-  assert(false && "Failed to find an appropriate mask type!");
-  return SDOperand(N, 0);
-}

Added: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp?rev=52408&view=auto

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp (added)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp Tue Jun 17 09:27:01 2008
@@ -0,0 +1,806 @@
+//===------- LegalizeVectorTypes.cpp - Legalization of vector types -------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file performs vector type splitting and scalarization for LegalizeTypes.
+// Scalarization is the act of changing a computation in an illegal one-element
+// vector type to be a computation in its scalar element type.  For example,
+// implementing <1 x f32> arithmetic in a scalar f32 register.  This is needed
+// as a base case when scalarizing vector arithmetic like <4 x f32>, which
+// eventually decomposes to scalars if the target doesn't support v4f32 or v2f32
+// types.
+// Splitting is the act of changing a computation in an invalid vector type to
+// be a computation in multiple vectors of a smaller type.  For example,
+// implementing <128 x f32> operations in terms of two <64 x f32> operations.
+//
+//===----------------------------------------------------------------------===//
+
+#include "LegalizeTypes.h"
+using namespace llvm;
+
+//===----------------------------------------------------------------------===//
+//  Result Vector Scalarization: <1 x ty> -> ty.
+//===----------------------------------------------------------------------===//
+
+void DAGTypeLegalizer::ScalarizeResult(SDNode *N, unsigned ResNo) {
+  DEBUG(cerr << "Scalarize node result " << ResNo << ": "; N->dump(&DAG);
+        cerr << "\n");
+  SDOperand R = SDOperand();
+
+  // FIXME: Custom lowering for scalarization?
+#if 0
+  // See if the target wants to custom expand this node.
+  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
+      TargetLowering::Custom) {
+    // If the target wants to, allow it to lower this itself.
+    if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
+      // Everything that once used N now uses P.  We are guaranteed that the
+      // result value types of N and the result value types of P match.
+      ReplaceNodeWith(N, P);
+      return;
+    }
+  }
+#endif
+
+  switch (N->getOpcode()) {
+  default:
+#ifndef NDEBUG
+    cerr << "ScalarizeResult #" << ResNo << ": ";
+    N->dump(&DAG); cerr << "\n";
+#endif
+    assert(0 && "Do not know how to scalarize the result of this operator!");
+    abort();
+
+  case ISD::UNDEF:       R = ScalarizeRes_UNDEF(N); break;
+  case ISD::LOAD:        R = ScalarizeRes_LOAD(cast<LoadSDNode>(N)); break;
+  case ISD::ADD:
+  case ISD::FADD:
+  case ISD::SUB:
+  case ISD::FSUB:
+  case ISD::MUL:
+  case ISD::FMUL:
+  case ISD::SDIV:
+  case ISD::UDIV:
+  case ISD::FDIV:
+  case ISD::SREM:
+  case ISD::UREM:
+  case ISD::FREM:
+  case ISD::FPOW:
+  case ISD::AND:
+  case ISD::OR:
+  case ISD::XOR:         R = ScalarizeRes_BinOp(N); break;
+  case ISD::FNEG:
+  case ISD::FABS:
+  case ISD::FSQRT:
+  case ISD::FSIN:
+  case ISD::FCOS:              R = ScalarizeRes_UnaryOp(N); break;
+  case ISD::FPOWI:             R = ScalarizeRes_FPOWI(N); break;
+  case ISD::BUILD_VECTOR:      R = N->getOperand(0); break;
+  case ISD::INSERT_VECTOR_ELT: R = ScalarizeRes_INSERT_VECTOR_ELT(N); break;
+  case ISD::VECTOR_SHUFFLE:    R = ScalarizeRes_VECTOR_SHUFFLE(N); break;
+  case ISD::BIT_CONVERT:       R = ScalarizeRes_BIT_CONVERT(N); break;
+  case ISD::SELECT:            R = ScalarizeRes_SELECT(N); break;
+  }
+
+  // If R is null, the sub-method took care of registering the result.
+  if (R.Val)
+    SetScalarizedVector(SDOperand(N, ResNo), R);
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_UNDEF(SDNode *N) {
+  return DAG.getNode(ISD::UNDEF, N->getValueType(0).getVectorElementType());
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_LOAD(LoadSDNode *N) {
+  // FIXME: Add support for indexed loads.
+  SDOperand Result = DAG.getLoad(N->getValueType(0).getVectorElementType(),
+                                 N->getChain(), N->getBasePtr(),
+                                 N->getSrcValue(), N->getSrcValueOffset(),
+                                 N->isVolatile(), N->getAlignment());
+
+  // Legalized the chain result - switch anything that used the old chain to
+  // use the new one.
+  ReplaceValueWith(SDOperand(N, 1), Result.getValue(1));
+  return Result;
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_BinOp(SDNode *N) {
+  SDOperand LHS = GetScalarizedVector(N->getOperand(0));
+  SDOperand RHS = GetScalarizedVector(N->getOperand(1));
+  return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS);
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_UnaryOp(SDNode *N) {
+  SDOperand Op = GetScalarizedVector(N->getOperand(0));
+  return DAG.getNode(N->getOpcode(), Op.getValueType(), Op);
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_FPOWI(SDNode *N) {
+  SDOperand Op = GetScalarizedVector(N->getOperand(0));
+  return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1));
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_INSERT_VECTOR_ELT(SDNode *N) {
+  // The value to insert may have a wider type than the vector element type,
+  // so be sure to truncate it to the element type if necessary.
+  SDOperand Op = N->getOperand(1);
+  MVT EltVT = N->getValueType(0).getVectorElementType();
+  if (Op.getValueType().bitsGT(EltVT))
+    Op = DAG.getNode(ISD::TRUNCATE, EltVT, Op);
+  assert(Op.getValueType() == EltVT && "Invalid type for inserted value!");
+  return Op;
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_VECTOR_SHUFFLE(SDNode *N) {
+  // Figure out if the scalar is the LHS or RHS and return it.
+  SDOperand EltNum = N->getOperand(2).getOperand(0);
+  unsigned Op = cast<ConstantSDNode>(EltNum)->getValue() != 0;
+  return GetScalarizedVector(N->getOperand(Op));
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_BIT_CONVERT(SDNode *N) {
+  MVT NewVT = N->getValueType(0).getVectorElementType();
+  return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0));
+}
+
+SDOperand DAGTypeLegalizer::ScalarizeRes_SELECT(SDNode *N) {
+  SDOperand LHS = GetScalarizedVector(N->getOperand(1));
+  return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0), LHS,
+                     GetScalarizedVector(N->getOperand(2)));
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Operand Vector Scalarization <1 x ty> -> ty.
+//===----------------------------------------------------------------------===//
+
+bool DAGTypeLegalizer::ScalarizeOperand(SDNode *N, unsigned OpNo) {
+  DEBUG(cerr << "Scalarize node operand " << OpNo << ": "; N->dump(&DAG);
+        cerr << "\n");
+  SDOperand Res(0, 0);
+
+  // FIXME: Should we support custom lowering for scalarization?
+#if 0
+  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
+      TargetLowering::Custom)
+    Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
+#endif
+
+  if (Res.Val == 0) {
+    switch (N->getOpcode()) {
+    default:
+#ifndef NDEBUG
+      cerr << "ScalarizeOperand Op #" << OpNo << ": ";
+      N->dump(&DAG); cerr << "\n";
+#endif
+      assert(0 && "Do not know how to scalarize this operator's operand!");
+      abort();
+
+    case ISD::BIT_CONVERT:
+      Res = ScalarizeOp_BIT_CONVERT(N); break;
+
+    case ISD::EXTRACT_VECTOR_ELT:
+      Res = ScalarizeOp_EXTRACT_VECTOR_ELT(N); break;
+
+    case ISD::STORE:
+      Res = ScalarizeOp_STORE(cast<StoreSDNode>(N), OpNo); break;
+    }
+  }
+
+  // If the result is null, the sub-method took care of registering results etc.
+  if (!Res.Val) return false;
+
+  // If the result is N, the sub-method updated N in place.  Check to see if any
+  // operands are new, and if so, mark them.
+  if (Res.Val == N) {
+    // Mark N as new and remark N and its operands.  This allows us to correctly
+    // revisit N if it needs another step of promotion and allows us to visit
+    // any new operands to N.
+    ReanalyzeNode(N);
+    return true;
+  }
+
+  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
+         "Invalid operand expansion");
+
+  ReplaceValueWith(SDOperand(N, 0), Res);
+  return false;
+}
+
+/// ScalarizeOp_BIT_CONVERT - If the value to convert is a vector that needs
+/// to be scalarized, it must be <1 x ty>.  Convert the element instead.
+SDOperand DAGTypeLegalizer::ScalarizeOp_BIT_CONVERT(SDNode *N) {
+  SDOperand Elt = GetScalarizedVector(N->getOperand(0));
+  return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Elt);
+}
+
+/// ScalarizeOp_EXTRACT_VECTOR_ELT - If the input is a vector that needs to be
+/// scalarized, it must be <1 x ty>, so just return the element, ignoring the
+/// index.
+SDOperand DAGTypeLegalizer::ScalarizeOp_EXTRACT_VECTOR_ELT(SDNode *N) {
+  return GetScalarizedVector(N->getOperand(0));
+}
+
+/// ScalarizeOp_STORE - If the value to store is a vector that needs to be
+/// scalarized, it must be <1 x ty>.  Just store the element.
+SDOperand DAGTypeLegalizer::ScalarizeOp_STORE(StoreSDNode *N, unsigned OpNo) {
+  // FIXME: Add support for indexed stores.
+  assert(OpNo == 1 && "Do not know how to scalarize this operand!");
+  return DAG.getStore(N->getChain(), GetScalarizedVector(N->getOperand(1)),
+                      N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(),
+                      N->isVolatile(), N->getAlignment());
+}
+
+
+/// GetSplitDestVTs - Compute the VTs needed for the low/hi parts of a vector
+/// type that needs to be split.  This handles non-power of two vectors.
+static void GetSplitDestVTs(MVT InVT, MVT &Lo, MVT &Hi) {
+  MVT NewEltVT = InVT.getVectorElementType();
+  unsigned NumElements = InVT.getVectorNumElements();
+  if ((NumElements & (NumElements-1)) == 0) {  // Simple power of two vector.
+    NumElements >>= 1;
+    Lo = Hi =  MVT::getVectorVT(NewEltVT, NumElements);
+  } else {                                     // Non-power-of-two vectors.
+    unsigned NewNumElts_Lo = 1 << Log2_32(NumElements);
+    unsigned NewNumElts_Hi = NumElements - NewNumElts_Lo;
+    Lo = MVT::getVectorVT(NewEltVT, NewNumElts_Lo);
+    Hi = MVT::getVectorVT(NewEltVT, NewNumElts_Hi);
+  }
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Result Vector Splitting
+//===----------------------------------------------------------------------===//
+
+/// SplitResult - This method is called when the specified result of the
+/// specified node is found to need vector splitting.  At this point, the node
+/// may also have invalid operands or may have other results that need
+/// legalization, we just know that (at least) one result needs vector
+/// splitting.
+void DAGTypeLegalizer::SplitResult(SDNode *N, unsigned ResNo) {
+  DEBUG(cerr << "Split node result: "; N->dump(&DAG); cerr << "\n");
+  SDOperand Lo, Hi;
+
+#if 0
+  // See if the target wants to custom expand this node.
+  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
+      TargetLowering::Custom) {
+    // If the target wants to, allow it to lower this itself.
+    if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) {
+      // Everything that once used N now uses P.  We are guaranteed that the
+      // result value types of N and the result value types of P match.
+      ReplaceNodeWith(N, P);
+      return;
+    }
+  }
+#endif
+
+  switch (N->getOpcode()) {
+  default:
+#ifndef NDEBUG
+    cerr << "SplitResult #" << ResNo << ": ";
+    N->dump(&DAG); cerr << "\n";
+#endif
+    assert(0 && "Do not know how to split the result of this operator!");
+    abort();
+
+  case ISD::UNDEF:            SplitRes_UNDEF(N, Lo, Hi); break;
+  case ISD::LOAD:             SplitRes_LOAD(cast<LoadSDNode>(N), Lo, Hi); break;
+  case ISD::BUILD_PAIR:       SplitRes_BUILD_PAIR(N, Lo, Hi); break;
+  case ISD::INSERT_VECTOR_ELT:SplitRes_INSERT_VECTOR_ELT(N, Lo, Hi); break;
+  case ISD::VECTOR_SHUFFLE:   SplitRes_VECTOR_SHUFFLE(N, Lo, Hi); break;
+  case ISD::BUILD_VECTOR:     SplitRes_BUILD_VECTOR(N, Lo, Hi); break;
+  case ISD::CONCAT_VECTORS:   SplitRes_CONCAT_VECTORS(N, Lo, Hi); break;
+  case ISD::BIT_CONVERT:      SplitRes_BIT_CONVERT(N, Lo, Hi); break;
+  case ISD::CTTZ:
+  case ISD::CTLZ:
+  case ISD::CTPOP:
+  case ISD::FNEG:
+  case ISD::FABS:
+  case ISD::FSQRT:
+  case ISD::FSIN:
+  case ISD::FCOS:
+  case ISD::FP_TO_SINT:
+  case ISD::FP_TO_UINT:
+  case ISD::SINT_TO_FP:
+  case ISD::UINT_TO_FP:       SplitRes_UnOp(N, Lo, Hi); break;
+  case ISD::ADD:
+  case ISD::SUB:
+  case ISD::MUL:
+  case ISD::FADD:
+  case ISD::FSUB:
+  case ISD::FMUL:
+  case ISD::SDIV:
+  case ISD::UDIV:
+  case ISD::FDIV:
+  case ISD::FPOW:
+  case ISD::AND:
+  case ISD::OR:
+  case ISD::XOR:
+  case ISD::UREM:
+  case ISD::SREM:
+  case ISD::FREM:             SplitRes_BinOp(N, Lo, Hi); break;
+  case ISD::FPOWI:            SplitRes_FPOWI(N, Lo, Hi); break;
+  case ISD::SELECT:           SplitRes_SELECT(N, Lo, Hi); break;
+  }
+
+  // If Lo/Hi is null, the sub-method took care of registering results etc.
+  if (Lo.Val)
+    SetSplitVector(SDOperand(N, ResNo), Lo, Hi);
+}
+
+void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+  MVT LoVT, HiVT;
+  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+
+  Lo = DAG.getNode(ISD::UNDEF, LoVT);
+  Hi = DAG.getNode(ISD::UNDEF, HiVT);
+}
+
+void DAGTypeLegalizer::SplitRes_LOAD(LoadSDNode *LD,
+                                     SDOperand &Lo, SDOperand &Hi) {
+  // FIXME: Add support for indexed loads.
+  MVT LoVT, HiVT;
+  GetSplitDestVTs(LD->getValueType(0), LoVT, HiVT);
+
+  SDOperand Ch = LD->getChain();
+  SDOperand Ptr = LD->getBasePtr();
+  const Value *SV = LD->getSrcValue();
+  int SVOffset = LD->getSrcValueOffset();
+  unsigned Alignment = LD->getAlignment();
+  bool isVolatile = LD->isVolatile();
+
+  Lo = DAG.getLoad(LoVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
+  unsigned IncrementSize = LoVT.getSizeInBits()/8;
+  Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                    DAG.getIntPtrConstant(IncrementSize));
+  SVOffset += IncrementSize;
+  Alignment = MinAlign(Alignment, IncrementSize);
+  Hi = DAG.getLoad(HiVT, Ch, Ptr, SV, SVOffset, isVolatile, Alignment);
+
+  // 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));
+
+  // Legalized the chain result - switch anything that used the old chain to
+  // use the new one.
+  ReplaceValueWith(SDOperand(LD, 1), TF);
+}
+
+void DAGTypeLegalizer::SplitRes_BUILD_PAIR(SDNode *N, SDOperand &Lo,
+                                           SDOperand &Hi) {
+  Lo = N->getOperand(0);
+  Hi = N->getOperand(1);
+}
+
+void DAGTypeLegalizer::SplitRes_INSERT_VECTOR_ELT(SDNode *N, SDOperand &Lo,
+                                                  SDOperand &Hi) {
+  SDOperand Vec = N->getOperand(0);
+  SDOperand Elt = N->getOperand(1);
+  SDOperand Idx = N->getOperand(2);
+  GetSplitVector(Vec, Lo, Hi);
+
+  if (ConstantSDNode *CIdx = dyn_cast<ConstantSDNode>(Idx)) {
+    unsigned IdxVal = CIdx->getValue();
+    unsigned LoNumElts = Lo.getValueType().getVectorNumElements();
+    if (IdxVal < LoNumElts)
+      Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, Lo.getValueType(), Lo, Elt, Idx);
+    else
+      Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, Hi.getValueType(), Hi, Elt,
+                       DAG.getIntPtrConstant(IdxVal - LoNumElts));
+    return;
+  }
+
+  // Spill the vector to the stack.
+  MVT VecVT = Vec.getValueType();
+  SDOperand StackPtr = DAG.CreateStackTemporary(VecVT);
+  SDOperand Store = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0);
+
+  // Store the new element.
+  SDOperand EltPtr = GetVectorElementPointer(StackPtr,
+                                             VecVT.getVectorElementType(), Idx);
+  Store = DAG.getStore(Store, Elt, EltPtr, NULL, 0);
+
+  // Reload the vector from the stack.
+  SDOperand Load = DAG.getLoad(VecVT, Store, StackPtr, NULL, 0);
+
+  // Split it.
+  SplitRes_LOAD(cast<LoadSDNode>(Load.Val), Lo, Hi);
+}
+
+void DAGTypeLegalizer::SplitRes_VECTOR_SHUFFLE(SDNode *N,
+                                               SDOperand &Lo, SDOperand &Hi) {
+  // Build the low part.
+  SDOperand Mask = N->getOperand(2);
+  SmallVector<SDOperand, 16> Ops;
+  MVT LoVT, HiVT;
+  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+  MVT EltVT = LoVT.getVectorElementType();
+  unsigned LoNumElts = LoVT.getVectorNumElements();
+  unsigned NumElements = Mask.getNumOperands();
+
+  // Insert all of the elements from the input that are needed.  We use
+  // buildvector of extractelement here because the input vectors will have
+  // to be legalized, so this makes the code simpler.
+  for (unsigned i = 0; i != LoNumElts; ++i) {
+    unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
+    SDOperand InVec = N->getOperand(0);
+    if (Idx >= NumElements) {
+      InVec = N->getOperand(1);
+      Idx -= NumElements;
+    }
+    Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InVec,
+                              DAG.getIntPtrConstant(Idx)));
+  }
+  Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &Ops[0], Ops.size());
+  Ops.clear();
+
+  for (unsigned i = LoNumElts; i != NumElements; ++i) {
+    unsigned Idx = cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
+    SDOperand InVec = N->getOperand(0);
+    if (Idx >= NumElements) {
+      InVec = N->getOperand(1);
+      Idx -= NumElements;
+    }
+    Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InVec,
+                              DAG.getIntPtrConstant(Idx)));
+  }
+  Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &Ops[0], Ops.size());
+}
+
+void DAGTypeLegalizer::SplitRes_BUILD_VECTOR(SDNode *N, SDOperand &Lo,
+                                             SDOperand &Hi) {
+  MVT LoVT, HiVT;
+  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+  unsigned LoNumElts = LoVT.getVectorNumElements();
+  SmallVector<SDOperand, 8> LoOps(N->op_begin(), N->op_begin()+LoNumElts);
+  Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &LoOps[0], LoOps.size());
+
+  SmallVector<SDOperand, 8> HiOps(N->op_begin()+LoNumElts, N->op_end());
+  Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &HiOps[0], HiOps.size());
+}
+
+void DAGTypeLegalizer::SplitRes_CONCAT_VECTORS(SDNode *N,
+                                               SDOperand &Lo, SDOperand &Hi) {
+  // FIXME: Handle non-power-of-two vectors?
+  unsigned NumSubvectors = N->getNumOperands() / 2;
+  if (NumSubvectors == 1) {
+    Lo = N->getOperand(0);
+    Hi = N->getOperand(1);
+    return;
+  }
+
+  MVT LoVT, HiVT;
+  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+
+  SmallVector<SDOperand, 8> LoOps(N->op_begin(), N->op_begin()+NumSubvectors);
+  Lo = DAG.getNode(ISD::CONCAT_VECTORS, LoVT, &LoOps[0], LoOps.size());
+
+  SmallVector<SDOperand, 8> HiOps(N->op_begin()+NumSubvectors, N->op_end());
+  Hi = DAG.getNode(ISD::CONCAT_VECTORS, HiVT, &HiOps[0], HiOps.size());
+}
+
+void DAGTypeLegalizer::SplitRes_BIT_CONVERT(SDNode *N,
+                                            SDOperand &Lo, SDOperand &Hi) {
+  // We know the result is a vector.  The input may be either a vector or a
+  // scalar value.
+  MVT LoVT, HiVT;
+  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+
+  SDOperand InOp = N->getOperand(0);
+  MVT InVT = InOp.getValueType();
+
+  // Handle some special cases efficiently.
+  switch (getTypeAction(InVT)) {
+  default:
+    assert(false && "Unknown type action!");
+  case Legal:
+  case PromoteInteger:
+  case PromoteFloat:
+  case Scalarize:
+    break;
+  case ExpandInteger:
+  case ExpandFloat:
+    // A scalar to vector conversion, where the scalar needs expansion.
+    // If the vector is being split in two then we can just convert the
+    // expanded pieces.
+    if (LoVT == HiVT) {
+      if (InVT.isInteger())
+        GetExpandedInteger(InOp, Lo, Hi);
+      else
+        GetExpandedFloat(InOp, Lo, Hi);
+      if (TLI.isBigEndian())
+        std::swap(Lo, Hi);
+      Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
+      Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
+      return;
+    }
+    break;
+  case Split:
+    // If the input is a vector that needs to be split, convert each split
+    // piece of the input now.
+    GetSplitVector(InOp, Lo, Hi);
+    Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
+    Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
+    return;
+  }
+
+  // In the general case, convert the input to an integer and split it by hand.
+  MVT LoIntVT = MVT::getIntegerVT(LoVT.getSizeInBits());
+  MVT HiIntVT = MVT::getIntegerVT(HiVT.getSizeInBits());
+  if (TLI.isBigEndian())
+    std::swap(LoIntVT, HiIntVT);
+
+  SplitInteger(BitConvertToInteger(InOp), LoIntVT, HiIntVT, Lo, Hi);
+
+  if (TLI.isBigEndian())
+    std::swap(Lo, Hi);
+  Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo);
+  Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi);
+}
+
+void DAGTypeLegalizer::SplitRes_BinOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+  SDOperand LHSLo, LHSHi;
+  GetSplitVector(N->getOperand(0), LHSLo, LHSHi);
+  SDOperand RHSLo, RHSHi;
+  GetSplitVector(N->getOperand(1), RHSLo, RHSHi);
+
+  Lo = DAG.getNode(N->getOpcode(), LHSLo.getValueType(), LHSLo, RHSLo);
+  Hi = DAG.getNode(N->getOpcode(), LHSHi.getValueType(), LHSHi, RHSHi);
+}
+
+void DAGTypeLegalizer::SplitRes_UnOp(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+  // Get the dest types.  This doesn't always match input types, e.g. int_to_fp.
+  MVT LoVT, HiVT;
+  GetSplitDestVTs(N->getValueType(0), LoVT, HiVT);
+
+  GetSplitVector(N->getOperand(0), Lo, Hi);
+  Lo = DAG.getNode(N->getOpcode(), LoVT, Lo);
+  Hi = DAG.getNode(N->getOpcode(), HiVT, Hi);
+}
+
+void DAGTypeLegalizer::SplitRes_FPOWI(SDNode *N, SDOperand &Lo, SDOperand &Hi) {
+  GetSplitVector(N->getOperand(0), Lo, Hi);
+  Lo = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Lo, N->getOperand(1));
+  Hi = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Hi, N->getOperand(1));
+}
+
+
+void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDOperand &Lo, SDOperand &Hi){
+  SDOperand LL, LH, RL, RH;
+  GetSplitVector(N->getOperand(1), LL, LH);
+  GetSplitVector(N->getOperand(2), RL, RH);
+
+  SDOperand Cond = N->getOperand(0);
+  Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), Cond, LL, RL);
+  Hi = DAG.getNode(ISD::SELECT, LH.getValueType(), Cond, LH, RH);
+}
+
+
+//===----------------------------------------------------------------------===//
+//  Operand Vector Splitting
+//===----------------------------------------------------------------------===//
+
+/// SplitOperand - This method is called when the specified operand of the
+/// specified node is found to need vector splitting.  At this point, all of the
+/// result types of the node are known to be legal, but other operands of the
+/// node may need legalization as well as the specified one.
+bool DAGTypeLegalizer::SplitOperand(SDNode *N, unsigned OpNo) {
+  DEBUG(cerr << "Split node operand: "; N->dump(&DAG); cerr << "\n");
+  SDOperand Res(0, 0);
+
+#if 0
+  if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) ==
+      TargetLowering::Custom)
+    Res = TLI.LowerOperation(SDOperand(N, 0), DAG);
+#endif
+
+  if (Res.Val == 0) {
+    switch (N->getOpcode()) {
+    default:
+#ifndef NDEBUG
+      cerr << "SplitOperand Op #" << OpNo << ": ";
+      N->dump(&DAG); cerr << "\n";
+#endif
+      assert(0 && "Do not know how to split this operator's operand!");
+      abort();
+    case ISD::STORE: Res = SplitOp_STORE(cast<StoreSDNode>(N), OpNo); break;
+    case ISD::RET:   Res = SplitOp_RET(N, OpNo); break;
+
+    case ISD::BIT_CONVERT: Res = SplitOp_BIT_CONVERT(N); break;
+
+    case ISD::EXTRACT_VECTOR_ELT: Res = SplitOp_EXTRACT_VECTOR_ELT(N); break;
+    case ISD::EXTRACT_SUBVECTOR:  Res = SplitOp_EXTRACT_SUBVECTOR(N); break;
+    case ISD::VECTOR_SHUFFLE:     Res = SplitOp_VECTOR_SHUFFLE(N, OpNo); break;
+    }
+  }
+
+  // If the result is null, the sub-method took care of registering results etc.
+  if (!Res.Val) return false;
+
+  // If the result is N, the sub-method updated N in place.  Check to see if any
+  // operands are new, and if so, mark them.
+  if (Res.Val == N) {
+    // Mark N as new and remark N and its operands.  This allows us to correctly
+    // revisit N if it needs another step of promotion and allows us to visit
+    // any new operands to N.
+    ReanalyzeNode(N);
+    return true;
+  }
+
+  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
+         "Invalid operand expansion");
+
+  ReplaceValueWith(SDOperand(N, 0), Res);
+  return false;
+}
+
+SDOperand DAGTypeLegalizer::SplitOp_STORE(StoreSDNode *N, unsigned OpNo) {
+  // FIXME: Add support for indexed stores.
+  assert(OpNo == 1 && "Can only split the stored value");
+
+  SDOperand Ch  = N->getChain();
+  SDOperand Ptr = N->getBasePtr();
+  int SVOffset = N->getSrcValueOffset();
+  unsigned Alignment = N->getAlignment();
+  bool isVol = N->isVolatile();
+  SDOperand Lo, Hi;
+  GetSplitVector(N->getOperand(1), Lo, Hi);
+
+  unsigned IncrementSize = Lo.getValueType().getSizeInBits()/8;
+
+  Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, isVol, Alignment);
+
+  // Increment the pointer to the other half.
+  Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr,
+                    DAG.getIntPtrConstant(IncrementSize));
+
+  Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize,
+                    isVol, MinAlign(Alignment, IncrementSize));
+  return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi);
+}
+
+SDOperand DAGTypeLegalizer::SplitOp_RET(SDNode *N, unsigned OpNo) {
+  assert(N->getNumOperands() == 3 &&"Can only handle ret of one vector so far");
+  // FIXME: Returns of gcc generic vectors larger than a legal vector
+  // type should be returned by reference!
+  SDOperand Lo, Hi;
+  GetSplitVector(N->getOperand(1), Lo, Hi);
+
+  SDOperand Chain = N->getOperand(0);  // The chain.
+  SDOperand Sign = N->getOperand(2);  // Signness
+
+  return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Sign, Hi, Sign);
+}
+
+SDOperand DAGTypeLegalizer::SplitOp_BIT_CONVERT(SDNode *N) {
+  // For example, i64 = BIT_CONVERT v4i16 on alpha.  Typically the vector will
+  // end up being split all the way down to individual components.  Convert the
+  // split pieces into integers and reassemble.
+  SDOperand Lo, Hi;
+  GetSplitVector(N->getOperand(0), Lo, Hi);
+  Lo = BitConvertToInteger(Lo);
+  Hi = BitConvertToInteger(Hi);
+
+  if (TLI.isBigEndian())
+    std::swap(Lo, Hi);
+
+  return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0),
+                     JoinIntegers(Lo, Hi));
+}
+
+SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_VECTOR_ELT(SDNode *N) {
+  SDOperand Vec = N->getOperand(0);
+  SDOperand Idx = N->getOperand(1);
+  MVT VecVT = Vec.getValueType();
+
+  if (isa<ConstantSDNode>(Idx)) {
+    uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getValue();
+    assert(IdxVal < VecVT.getVectorNumElements() && "Invalid vector index!");
+
+    SDOperand Lo, Hi;
+    GetSplitVector(Vec, Lo, Hi);
+
+    uint64_t LoElts = Lo.getValueType().getVectorNumElements();
+
+    if (IdxVal < LoElts)
+      return DAG.UpdateNodeOperands(SDOperand(N, 0), Lo, Idx);
+    else
+      return DAG.UpdateNodeOperands(SDOperand(N, 0), Hi,
+                                    DAG.getConstant(IdxVal - LoElts,
+                                                    Idx.getValueType()));
+  }
+
+  // Store the vector to the stack.
+  MVT EltVT = VecVT.getVectorElementType();
+  SDOperand StackPtr = DAG.CreateStackTemporary(VecVT);
+  SDOperand Store = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0);
+
+  // Load back the required element.
+  StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx);
+  return DAG.getLoad(EltVT, Store, StackPtr, NULL, 0);
+}
+
+SDOperand DAGTypeLegalizer::SplitOp_EXTRACT_SUBVECTOR(SDNode *N) {
+  // We know that the extracted result type is legal.  For now, assume the index
+  // is a constant.
+  MVT SubVT = N->getValueType(0);
+  SDOperand Idx = N->getOperand(1);
+  SDOperand Lo, Hi;
+  GetSplitVector(N->getOperand(0), Lo, Hi);
+
+  uint64_t LoElts = Lo.getValueType().getVectorNumElements();
+  uint64_t IdxVal = cast<ConstantSDNode>(Idx)->getValue();
+
+  if (IdxVal < LoElts) {
+    assert(IdxVal + SubVT.getVectorNumElements() <= LoElts &&
+           "Extracted subvector crosses vector split!");
+    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SubVT, Lo, Idx);
+  } else {
+    return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SubVT, Hi,
+                       DAG.getConstant(IdxVal - LoElts, Idx.getValueType()));
+  }
+}
+
+SDOperand DAGTypeLegalizer::SplitOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo) {
+  assert(OpNo == 2 && "Shuffle source type differs from result type?");
+  SDOperand Mask = N->getOperand(2);
+  unsigned MaskLength = Mask.getValueType().getVectorNumElements();
+  unsigned LargestMaskEntryPlusOne = 2 * MaskLength;
+  unsigned MinimumBitWidth = Log2_32_Ceil(LargestMaskEntryPlusOne);
+
+  // Look for a legal vector type to place the mask values in.
+  // Note that there may not be *any* legal vector-of-integer
+  // type for which the element type is legal!
+  for (MVT::SimpleValueType EltVT = MVT::FIRST_INTEGER_VALUETYPE;
+       EltVT <= MVT::LAST_INTEGER_VALUETYPE;
+       // Integer values types are consecutively numbered.  Exploit this.
+       EltVT = MVT::SimpleValueType(EltVT + 1)) {
+
+    // Is the element type big enough to hold the values?
+    if (MVT(EltVT).getSizeInBits() < MinimumBitWidth)
+      // Nope.
+      continue;
+
+    // Is the vector type legal?
+    MVT VecVT = MVT::getVectorVT(EltVT, MaskLength);
+    if (!isTypeLegal(VecVT))
+      // Nope.
+      continue;
+
+    // If the element type is not legal, find a larger legal type to use for
+    // the BUILD_VECTOR operands.  This is an ugly hack, but seems to work!
+    // FIXME: The real solution is to change VECTOR_SHUFFLE into a variadic
+    // node where the shuffle mask is a list of integer operands, #2 .. #2+n.
+    for (MVT::SimpleValueType OpVT = EltVT; OpVT <= MVT::LAST_INTEGER_VALUETYPE;
+         // Integer values types are consecutively numbered.  Exploit this.
+         OpVT = MVT::SimpleValueType(OpVT + 1)) {
+      if (!isTypeLegal(OpVT))
+        continue;
+
+      // Success!  Rebuild the vector using the legal types.
+      SmallVector<SDOperand, 16> Ops(MaskLength);
+      for (unsigned i = 0; i < MaskLength; ++i) {
+        uint64_t Idx =
+          cast<ConstantSDNode>(Mask.getOperand(i))->getValue();
+        Ops[i] = DAG.getConstant(Idx, OpVT);
+      }
+      return DAG.UpdateNodeOperands(SDOperand(N,0),
+                                    N->getOperand(0), N->getOperand(1),
+                                    DAG.getNode(ISD::BUILD_VECTOR,
+                                                VecVT, &Ops[0], Ops.size()));
+    }
+
+    // Continuing is pointless - failure is certain.
+    break;
+  }
+  assert(false && "Failed to find an appropriate mask type!");
+  return SDOperand(N, 0);
+}





More information about the llvm-commits mailing list