[llvm-commits] [llvm] r72447 - /llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

Eli Friedman eli.friedman at gmail.com
Tue May 26 18:25:57 PDT 2009


Author: efriedma
Date: Tue May 26 20:25:56 2009
New Revision: 72447

URL: http://llvm.org/viewvc/llvm-project?rev=72447&view=rev
Log:
Start of refactoring LegalizeDAG so that we don't need specialized 
handling for every single opcode.


Modified:
    llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp

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

==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Tue May 26 20:25:56 2009
@@ -157,8 +157,6 @@
   SDValue EmitStackConvert(SDValue SrcOp, MVT SlotVT, MVT DestVT, DebugLoc dl);
   SDValue ExpandBUILD_VECTOR(SDNode *Node);
   SDValue ExpandSCALAR_TO_VECTOR(SDNode *Node);
-  SDValue LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy,
-                            SDValue Op, DebugLoc dl);
   SDValue ExpandLegalINT_TO_FP(bool isSigned, SDValue LegalOp, MVT DestVT,
                                DebugLoc dl);
   SDValue PromoteLegalINT_TO_FP(SDValue LegalOp, MVT DestVT, bool isSigned,
@@ -169,8 +167,10 @@
   SDValue ExpandBSWAP(SDValue Op, DebugLoc dl);
   SDValue ExpandBitCount(unsigned Opc, SDValue Op, DebugLoc dl);
 
-  SDValue ExpandEXTRACT_VECTOR_ELT(SDValue Op);
   SDValue ExpandExtractFromVectorThroughStack(SDValue Op);
+
+  void ExpandNode(SDNode *Node, SmallVectorImpl<SDValue> &Results);
+  void PromoteNode(SDNode *Node, SmallVectorImpl<SDValue> &Results);
 };
 }
 
@@ -712,43 +712,150 @@
   SDValue Result = Op;
   bool isCustom = false;
 
+  // Figure out the correct action; the way to query this varies by opcode
+  TargetLowering::LegalizeAction Action;
+  bool SimpleFinishLegalizing = true;
   switch (Node->getOpcode()) {
-  case ISD::FrameIndex:
-  case ISD::EntryToken:
-  case ISD::Register:
-  case ISD::BasicBlock:
-  case ISD::TargetFrameIndex:
-  case ISD::TargetJumpTable:
-  case ISD::TargetConstant:
-  case ISD::TargetConstantFP:
-  case ISD::TargetConstantPool:
-  case ISD::TargetGlobalAddress:
-  case ISD::TargetGlobalTLSAddress:
-  case ISD::TargetExternalSymbol:
-  case ISD::VALUETYPE:
-  case ISD::SRCVALUE:
-  case ISD::MEMOPERAND:
-  case ISD::CONDCODE:
-  case ISD::ARG_FLAGS:
-    // Primitives must all be legal.
-    assert(TLI.isOperationLegal(Node->getOpcode(), Node->getValueType(0)) &&
-           "This must be legal!");
+  case ISD::INTRINSIC_W_CHAIN:
+  case ISD::INTRINSIC_WO_CHAIN:
+  case ISD::INTRINSIC_VOID:
+  case ISD::VAARG:
+  case ISD::STACKSAVE:
+    Action = TLI.getOperationAction(Node->getOpcode(), MVT::Other);
+    break;
+  case ISD::SINT_TO_FP:
+  case ISD::UINT_TO_FP:
+  case ISD::EXTRACT_VECTOR_ELT:
+    Action = TLI.getOperationAction(Node->getOpcode(),
+                                    Node->getOperand(0).getValueType());
+    break;
+  case ISD::FP_ROUND_INREG:
+  case ISD::SIGN_EXTEND_INREG: {
+    MVT InnerType = cast<VTSDNode>(Node->getOperand(1))->getVT();
+    Action = TLI.getOperationAction(Node->getOpcode(), InnerType);
+    break;
+  }
+  case ISD::LOAD:
+  case ISD::STORE:
+  case ISD::BR_CC:
+  case ISD::FORMAL_ARGUMENTS:
+  case ISD::CALL:
+  case ISD::CALLSEQ_START:
+  case ISD::CALLSEQ_END:
+  case ISD::SELECT_CC:
+  case ISD::SETCC:
+  case ISD::EXCEPTIONADDR:
+  case ISD::EHSELECTION:
+    // These instructions have properties that aren't modeled in the
+    // generic codepath
+    SimpleFinishLegalizing = false;
+    break;
+  case ISD::EXTRACT_ELEMENT:
+  case ISD::FLT_ROUNDS_:
+  case ISD::SADDO:
+  case ISD::SSUBO:
+  case ISD::UADDO:
+  case ISD::USUBO:
+  case ISD::SMULO:
+  case ISD::UMULO:
+  case ISD::FPOWI:
+  case ISD::MERGE_VALUES:
+  case ISD::EH_RETURN:
+  case ISD::FRAME_TO_ARGS_OFFSET:
+    Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
+    if (Action == TargetLowering::Legal)
+      Action = TargetLowering::Expand;
+    break;
+  case ISD::TRAMPOLINE:
+  case ISD::FRAMEADDR:
+  case ISD::RETURNADDR:
+    Action = TargetLowering::Custom;
+    break;
+  case ISD::BUILD_VECTOR:
+    // A weird case: when a BUILD_VECTOR is custom-lowered, it doesn't legalize
+    // its operands first!
+    SimpleFinishLegalizing = false;
     break;
   default:
     if (Node->getOpcode() >= ISD::BUILTIN_OP_END) {
-      // If this is a target node, legalize it by legalizing the operands then
-      // passing it through.
-      SmallVector<SDValue, 8> Ops;
-      for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
-        Ops.push_back(LegalizeOp(Node->getOperand(i)));
+      Action = TargetLowering::Legal;
+    } else {
+      Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0));
+    }
+    break;
+  }
 
-      Result = DAG.UpdateNodeOperands(Result.getValue(0), Ops.data(), Ops.size());
+  if (SimpleFinishLegalizing) {
+    SmallVector<SDValue, 8> Ops, ResultVals;
+    for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
+      Ops.push_back(LegalizeOp(Node->getOperand(i)));
+    switch (Node->getOpcode()) {
+    default: break;
+    case ISD::BR:
+    case ISD::BRIND:
+    case ISD::BR_JT:
+    case ISD::BR_CC:
+    case ISD::BRCOND:
+    case ISD::RET:
+      // Branches tweak the chain to include LastCALLSEQ_END
+      Ops[0] = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Ops[0],
+                            LastCALLSEQ_END);
+      Ops[0] = LegalizeOp(Ops[0]);
+      LastCALLSEQ_END = DAG.getEntryNode();
+      break;
+    case ISD::SHL:
+    case ISD::SRL:
+    case ISD::SRA:
+    case ISD::ROTL:
+    case ISD::ROTR:
+      // Legalizing shifts/rotates requires adjusting the shift amount
+      // to the appropriate width.
+      if (!Ops[1].getValueType().isVector())
+        Ops[1] = LegalizeOp(DAG.getShiftAmountOperand(Ops[1]));
+      break;
+    }
 
+    Result = DAG.UpdateNodeOperands(Result.getValue(0), Ops.data(),
+                                    Ops.size());
+    switch (Action) {
+    case TargetLowering::Legal:
       for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
-        AddLegalizedOperand(Op.getValue(i), Result.getValue(i));
-      return Result.getValue(Op.getResNo());
+        ResultVals.push_back(Result.getValue(i));
+      break;
+    case TargetLowering::Custom:
+      // FIXME: The handling for custom lowering with multiple results is
+      // a complete mess.
+      Tmp1 = TLI.LowerOperation(Result, DAG);
+      if (Tmp1.getNode()) {
+        for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) {
+          if (e == 1)
+            ResultVals.push_back(Tmp1);
+          else
+            ResultVals.push_back(Tmp1.getValue(i));
+        }
+        break;
+      }
+
+      // FALL THROUGH
+    case TargetLowering::Expand:
+      ExpandNode(Result.getNode(), ResultVals);
+      break;
+    case TargetLowering::Promote:
+      PromoteNode(Result.getNode(), ResultVals);
+      break;
     }
-    // Otherwise this is an unhandled builtin node.  splat.
+    if (!ResultVals.empty()) {
+      for (unsigned i = 0, e = ResultVals.size(); i != e; ++i) {
+        if (ResultVals[i] != SDValue(Node, i))
+          ResultVals[i] = LegalizeOp(ResultVals[i]);
+        AddLegalizedOperand(SDValue(Node, i), ResultVals[i]);
+      }
+      return ResultVals[Op.getResNo()];
+    }
+  }
+
+  switch (Node->getOpcode()) {
+  default:
 #ifndef NDEBUG
     cerr << "NODE: "; Node->dump(&DAG); cerr << "\n";
 #endif
@@ -770,30 +877,6 @@
       break;
     }
     break;
-  case ISD::FRAMEADDR:
-  case ISD::RETURNADDR:
-    // The only option for these nodes is to custom lower them.  If the target
-    // does not custom lower them, then return zero.
-    Tmp1 = TLI.LowerOperation(Op, DAG);
-    if (Tmp1.getNode())
-      Result = Tmp1;
-    else
-      Result = DAG.getConstant(0, TLI.getPointerTy());
-    break;
-  case ISD::FRAME_TO_ARGS_OFFSET: {
-    MVT VT = Node->getValueType(0);
-    switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Custom:
-      Result = TLI.LowerOperation(Op, DAG);
-      if (Result.getNode()) break;
-      // Fall Thru
-    case TargetLowering::Legal:
-      Result = DAG.getConstant(0, VT);
-      break;
-    }
-    }
-    break;
   case ISD::EXCEPTIONADDR: {
     Tmp1 = LegalizeOp(Node->getOperand(0));
     MVT VT = Node->getValueType(0);
@@ -861,70 +944,6 @@
     AddLegalizedOperand(Op.getValue(0), Tmp1);
     AddLegalizedOperand(Op.getValue(1), Tmp2);
     return Op.getResNo() ? Tmp2 : Tmp1;
-  case ISD::EH_RETURN: {
-    MVT VT = Node->getValueType(0);
-    // The only "good" option for this node is to custom lower it.
-    switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
-    default: assert(0 && "This action is not supported at all!");
-    case TargetLowering::Custom:
-      Result = TLI.LowerOperation(Op, DAG);
-      if (Result.getNode()) break;
-      // Fall Thru
-    case TargetLowering::Legal:
-      // Target does not know, how to lower this, lower to noop
-      Result = LegalizeOp(Node->getOperand(0));
-      break;
-    }
-    }
-    break;
-  case ISD::AssertSext:
-  case ISD::AssertZext:
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1));
-    break;
-  case ISD::MERGE_VALUES:
-    // Legalize eliminates MERGE_VALUES nodes.
-    Result = Node->getOperand(Op.getResNo());
-    break;
-  case ISD::CopyFromReg:
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    Result = Op.getValue(0);
-    if (Node->getNumValues() == 2) {
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1));
-    } else {
-      assert(Node->getNumValues() == 3 && "Invalid copyfromreg!");
-      if (Node->getNumOperands() == 3) {
-        Tmp2 = LegalizeOp(Node->getOperand(2));
-        Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1),Tmp2);
-      } else {
-        Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1));
-      }
-      AddLegalizedOperand(Op.getValue(2), Result.getValue(2));
-    }
-    // Since CopyFromReg produces two values, make sure to remember that we
-    // legalized both of them.
-    AddLegalizedOperand(Op.getValue(0), Result);
-    AddLegalizedOperand(Op.getValue(1), Result.getValue(1));
-    return Result.getValue(Op.getResNo());
-  case ISD::UNDEF: {
-    MVT VT = Op.getValueType();
-    switch (TLI.getOperationAction(ISD::UNDEF, VT)) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Expand:
-      if (VT.isInteger())
-        Result = DAG.getConstant(0, VT);
-      else if (VT.isFloatingPoint())
-        Result = DAG.getConstantFP(APFloat(APInt(VT.getSizeInBits(), 0)),
-                                   VT);
-      else
-        assert(0 && "Unknown value type!");
-      break;
-    case TargetLowering::Legal:
-      break;
-    }
-    break;
-  }
-
   case ISD::INTRINSIC_W_CHAIN:
   case ISD::INTRINSIC_WO_CHAIN:
   case ISD::INTRINSIC_VOID: {
@@ -1013,159 +1032,6 @@
     }
     }
     break;
-
-  case ISD::DECLARE:
-    assert(Node->getNumOperands() == 3 && "Invalid DECLARE node!");
-    switch (TLI.getOperationAction(ISD::DECLARE, MVT::Other)) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal:
-      Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-      Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the address.
-      Tmp3 = LegalizeOp(Node->getOperand(2));  // Legalize the variable.
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
-      break;
-    case TargetLowering::Expand:
-      Result = LegalizeOp(Node->getOperand(0));
-      break;
-    }
-    break;
-
-  case ISD::DEBUG_LOC:
-    assert(Node->getNumOperands() == 4 && "Invalid DEBUG_LOC node!");
-    switch (TLI.getOperationAction(ISD::DEBUG_LOC, MVT::Other)) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal: {
-      Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-      if (Tmp1 == Node->getOperand(0))
-        break;
-      Tmp2 = Node->getOperand(1);
-      Tmp3 = Node->getOperand(2);
-      Tmp4 = Node->getOperand(3);
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3, Tmp4);
-      break;
-    }
-    }
-    break;
-
-  case ISD::DBG_LABEL:
-  case ISD::EH_LABEL:
-    assert(Node->getNumOperands() == 1 && "Invalid LABEL node!");
-    switch (TLI.getOperationAction(Node->getOpcode(), MVT::Other)) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal:
-      Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-      Result = DAG.UpdateNodeOperands(Result, Tmp1);
-      break;
-    case TargetLowering::Expand:
-      Result = LegalizeOp(Node->getOperand(0));
-      break;
-    }
-    break;
-
-  case ISD::PREFETCH:
-    assert(Node->getNumOperands() == 4 && "Invalid Prefetch node!");
-    switch (TLI.getOperationAction(ISD::PREFETCH, MVT::Other)) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal:
-      Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-      Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the address.
-      Tmp3 = LegalizeOp(Node->getOperand(2));  // Legalize the rw specifier.
-      Tmp4 = LegalizeOp(Node->getOperand(3));  // Legalize locality specifier.
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3, Tmp4);
-      break;
-    case TargetLowering::Expand:
-      // It's a noop.
-      Result = LegalizeOp(Node->getOperand(0));
-      break;
-    }
-    break;
-
-  case ISD::MEMBARRIER: {
-    assert(Node->getNumOperands() == 6 && "Invalid MemBarrier node!");
-    switch (TLI.getOperationAction(ISD::MEMBARRIER, MVT::Other)) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal: {
-      SDValue Ops[6];
-      Ops[0] = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-      for (int x = 1; x < 6; ++x) {
-        Ops[x] = Node->getOperand(x);
-      }
-      Result = DAG.UpdateNodeOperands(Result, &Ops[0], 6);
-      break;
-    }
-    case TargetLowering::Expand:
-      //There is no libgcc call for this op
-      Result = Node->getOperand(0);  // Noop
-    break;
-    }
-    break;
-  }
-
-  case ISD::ATOMIC_CMP_SWAP: {
-    unsigned int num_operands = 4;
-    assert(Node->getNumOperands() == num_operands && "Invalid Atomic node!");
-    SDValue Ops[4];
-    for (unsigned int x = 0; x < num_operands; ++x)
-      Ops[x] = LegalizeOp(Node->getOperand(x));
-    Result = DAG.UpdateNodeOperands(Result, &Ops[0], num_operands);
-
-    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
-      default: assert(0 && "This action is not supported yet!");
-      case TargetLowering::Custom:
-        Result = TLI.LowerOperation(Result, DAG);
-        break;
-      case TargetLowering::Legal:
-        break;
-    }
-    AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0));
-    AddLegalizedOperand(SDValue(Node, 1), Result.getValue(1));
-    return Result.getValue(Op.getResNo());
-  }
-  case ISD::ATOMIC_LOAD_ADD:
-  case ISD::ATOMIC_LOAD_SUB:
-  case ISD::ATOMIC_LOAD_AND:
-  case ISD::ATOMIC_LOAD_OR:
-  case ISD::ATOMIC_LOAD_XOR:
-  case ISD::ATOMIC_LOAD_NAND:
-  case ISD::ATOMIC_LOAD_MIN:
-  case ISD::ATOMIC_LOAD_MAX:
-  case ISD::ATOMIC_LOAD_UMIN:
-  case ISD::ATOMIC_LOAD_UMAX:
-  case ISD::ATOMIC_SWAP: {
-    unsigned int num_operands = 3;
-    assert(Node->getNumOperands() == num_operands && "Invalid Atomic node!");
-    SDValue Ops[3];
-    for (unsigned int x = 0; x < num_operands; ++x)
-      Ops[x] = LegalizeOp(Node->getOperand(x));
-    Result = DAG.UpdateNodeOperands(Result, &Ops[0], num_operands);
-
-    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Custom:
-      Result = TLI.LowerOperation(Result, DAG);
-      break;
-    case TargetLowering::Legal:
-      break;
-    }
-    AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0));
-    AddLegalizedOperand(SDValue(Node, 1), Result.getValue(1));
-    return Result.getValue(Op.getResNo());
-  }
-  case ISD::Constant: {
-    ConstantSDNode *CN = cast<ConstantSDNode>(Node);
-    unsigned opAction =
-      TLI.getOperationAction(ISD::Constant, CN->getValueType(0));
-
-    // We know we don't need to expand constants here, constants only have one
-    // value and we check that it is fine above.
-
-    if (opAction == TargetLowering::Custom) {
-      Tmp1 = TLI.LowerOperation(Result, DAG);
-      if (Tmp1.getNode())
-        Result = Tmp1;
-    }
-    break;
-  }
   case ISD::ConstantFP: {
     // Spill FP immediates to the constant pool if the target cannot directly
     // codegen them.  Targets often have some immediate values that can be
@@ -1202,25 +1068,6 @@
     }
     break;
   }
-  case ISD::TokenFactor:
-    if (Node->getNumOperands() == 2) {
-      Tmp1 = LegalizeOp(Node->getOperand(0));
-      Tmp2 = LegalizeOp(Node->getOperand(1));
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
-    } else if (Node->getNumOperands() == 3) {
-      Tmp1 = LegalizeOp(Node->getOperand(0));
-      Tmp2 = LegalizeOp(Node->getOperand(1));
-      Tmp3 = LegalizeOp(Node->getOperand(2));
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
-    } else {
-      SmallVector<SDValue, 8> Ops;
-      // Legalize the operands.
-      for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i)
-        Ops.push_back(LegalizeOp(Node->getOperand(i)));
-      Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size());
-    }
-    break;
-
   case ISD::FORMAL_ARGUMENTS:
   case ISD::CALL:
     // The only option for this is to custom lower it.
@@ -1324,26 +1171,6 @@
     }
     }
     break;
-  case ISD::SCALAR_TO_VECTOR:
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // InVal
-    Result = DAG.UpdateNodeOperands(Result, Tmp1);
-    switch (TLI.getOperationAction(ISD::SCALAR_TO_VECTOR,
-                                   Node->getValueType(0))) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal:
-      break;
-    case TargetLowering::Custom:
-      Tmp3 = TLI.LowerOperation(Result, DAG);
-      if (Tmp3.getNode()) {
-        Result = Tmp3;
-        break;
-      }
-      // FALLTHROUGH
-    case TargetLowering::Expand:
-      Result = LegalizeOp(ExpandSCALAR_TO_VECTOR(Node));
-      break;
-    }
-    break;
   case ISD::VECTOR_SHUFFLE: {
     Tmp1 = LegalizeOp(Node->getOperand(0));   // Legalize the input vectors,
     Tmp2 = LegalizeOp(Node->getOperand(1));   // but not the shuffle mask.
@@ -1405,37 +1232,6 @@
     }
     break;
   }
-  case ISD::EXTRACT_VECTOR_ELT:
-    Tmp1 = Node->getOperand(0);
-    Tmp2 = LegalizeOp(Node->getOperand(1));
-    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
-    Result = ExpandEXTRACT_VECTOR_ELT(Result);
-    break;
-
-  case ISD::EXTRACT_SUBVECTOR:
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    Tmp2 = LegalizeOp(Node->getOperand(1));
-    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
-
-    switch (TLI.getOperationAction(ISD::EXTRACT_SUBVECTOR,
-                                   Node->getValueType(0))) {
-    default: assert(0 && "Unknown operation action!");
-    case TargetLowering::Legal:
-      break;
-    case TargetLowering::Custom:
-      Tmp3 = TLI.LowerOperation(Result, DAG);
-      if (Tmp3.getNode()) {
-        Result = Tmp3;
-        break;
-      }
-      // FALLTHROUGH
-    case TargetLowering::Expand: {
-      Result = ExpandExtractFromVectorThroughStack(Result);
-      break;
-    }
-    }
-    break;
-
   case ISD::CONCAT_VECTORS: {
     // Legalize the operands.
     SmallVector<SDValue, 8> Ops;
@@ -1626,68 +1422,12 @@
     AddLegalizedOperand(SDValue(Node, 1), Tmp2);
     return Op.getResNo() ? Tmp2 : Tmp1;
   }
-  case ISD::INLINEASM: {
-    SmallVector<SDValue, 8> Ops(Node->op_begin(), Node->op_end());
-    bool Changed = false;
-    // Legalize all of the operands of the inline asm, in case they are nodes
-    // that need to be expanded or something.  Note we skip the asm string and
-    // all of the TargetConstant flags.
-    SDValue Op = LegalizeOp(Ops[0]);
-    Changed = Op != Ops[0];
-    Ops[0] = Op;
-
-    bool HasInFlag = Ops.back().getValueType() == MVT::Flag;
-    for (unsigned i = 2, e = Ops.size()-HasInFlag; i < e; ) {
-      unsigned NumVals = InlineAsm::
-        getNumOperandRegisters(cast<ConstantSDNode>(Ops[i])->getZExtValue());
-      for (++i; NumVals; ++i, --NumVals) {
-        SDValue Op = LegalizeOp(Ops[i]);
-        if (Op != Ops[i]) {
-          Changed = true;
-          Ops[i] = Op;
-        }
-      }
-    }
-
-    if (HasInFlag) {
-      Op = LegalizeOp(Ops.back());
-      Changed |= Op != Ops.back();
-      Ops.back() = Op;
-    }
-
-    if (Changed)
-      Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size());
-
-    // INLINE asm returns a chain and flag, make sure to add both to the map.
-    AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0));
-    AddLegalizedOperand(SDValue(Node, 1), Result.getValue(1));
-    return Result.getValue(Op.getResNo());
-  }
-  case ISD::BR:
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    // Ensure that libcalls are emitted before a branch.
-    Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END);
-    Tmp1 = LegalizeOp(Tmp1);
-    LastCALLSEQ_END = DAG.getEntryNode();
-
-    Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1));
-    break;
-  case ISD::BRIND:
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    // Ensure that libcalls are emitted before a branch.
-    Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END);
-    Tmp1 = LegalizeOp(Tmp1);
-    LastCALLSEQ_END = DAG.getEntryNode();
-
-    Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the condition.
-    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
-    break;
-  case ISD::BR_JT:
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    // Ensure that libcalls are emitted before a branch.
-    Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END);
-    Tmp1 = LegalizeOp(Tmp1);
-    LastCALLSEQ_END = DAG.getEntryNode();
+  case ISD::BR_JT:
+    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
+    // Ensure that libcalls are emitted before a branch.
+    Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END);
+    Tmp1 = LegalizeOp(Tmp1);
+    LastCALLSEQ_END = DAG.getEntryNode();
 
     Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the jumptable node.
     Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
@@ -2048,85 +1788,6 @@
       return Op.getResNo() ? Tmp2 : Tmp1;
     }
   }
-  case ISD::EXTRACT_ELEMENT: {
-    MVT OpTy = Node->getOperand(0).getValueType();
-    if (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) {
-      // 1 -> Hi
-      Result = DAG.getNode(ISD::SRL, dl, OpTy, Node->getOperand(0),
-                           DAG.getConstant(OpTy.getSizeInBits()/2,
-                                           TLI.getShiftAmountTy()));
-      Result = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Result);
-    } else {
-      // 0 -> Lo
-      Result = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0),
-                           Node->getOperand(0));
-    }
-    break;
-  }
-
-  case ISD::CopyToReg:
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-
-    // Legalize the incoming value (must be a legal type).
-    Tmp2 = LegalizeOp(Node->getOperand(2));
-    if (Node->getNumValues() == 1) {
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1), Tmp2);
-    } else {
-      assert(Node->getNumValues() == 2 && "Unknown CopyToReg");
-      if (Node->getNumOperands() == 4) {
-        Tmp3 = LegalizeOp(Node->getOperand(3));
-        Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1), Tmp2,
-                                        Tmp3);
-      } else {
-        Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1),Tmp2);
-      }
-
-      // Since this produces two values, make sure to remember that we legalized
-      // both of them.
-      AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0));
-      AddLegalizedOperand(SDValue(Node, 1), Result.getValue(1));
-      return Result;
-    }
-    break;
-
-  case ISD::RET:
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-
-    // Ensure that libcalls are emitted before a return.
-    Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END);
-    Tmp1 = LegalizeOp(Tmp1);
-    LastCALLSEQ_END = DAG.getEntryNode();
-
-    switch (Node->getNumOperands()) {
-    case 3:  // ret val
-      Tmp2 = Node->getOperand(1);
-      Tmp3 = Node->getOperand(2);  // Signness
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, LegalizeOp(Tmp2), Tmp3);
-      break;
-    case 1:  // ret void
-      Result = DAG.UpdateNodeOperands(Result, Tmp1);
-      break;
-    default: { // ret <values>
-      SmallVector<SDValue, 8> NewValues;
-      NewValues.push_back(Tmp1);
-      for (unsigned i = 1, e = Node->getNumOperands(); i < e; i += 2) {
-        NewValues.push_back(LegalizeOp(Node->getOperand(i)));
-        NewValues.push_back(Node->getOperand(i+1));
-      }
-      Result = DAG.UpdateNodeOperands(Result, &NewValues[0],NewValues.size());
-      break;
-    }
-    }
-
-    switch (TLI.getOperationAction(Result.getOpcode(), MVT::Other)) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal: break;
-    case TargetLowering::Custom:
-      Tmp1 = TLI.LowerOperation(Result, DAG);
-      if (Tmp1.getNode()) Result = Tmp1;
-      break;
-    }
-    break;
   case ISD::STORE: {
     StoreSDNode *ST = cast<StoreSDNode>(Node);
     Tmp1 = LegalizeOp(ST->getChain());    // Legalize the chain.
@@ -2315,10 +1976,6 @@
     }
     break;
   }
-  case ISD::PCMARKER:
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1));
-    break;
   case ISD::STACKSAVE:
     Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
     Result = DAG.UpdateNodeOperands(Result, Tmp1);
@@ -2378,30 +2035,6 @@
       break;
     }
     break;
-
-  case ISD::READCYCLECOUNTER:
-    Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain
-    Result = DAG.UpdateNodeOperands(Result, Tmp1);
-    switch (TLI.getOperationAction(ISD::READCYCLECOUNTER,
-                                   Node->getValueType(0))) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal:
-      Tmp1 = Result.getValue(0);
-      Tmp2 = Result.getValue(1);
-      break;
-    case TargetLowering::Custom:
-      Result = TLI.LowerOperation(Result, DAG);
-      Tmp1 = LegalizeOp(Result.getValue(0));
-      Tmp2 = LegalizeOp(Result.getValue(1));
-      break;
-    }
-
-    // Since rdcc produce two values, make sure to remember that we legalized
-    // both of them.
-    AddLegalizedOperand(SDValue(Node, 0), Tmp1);
-    AddLegalizedOperand(SDValue(Node, 1), Tmp2);
-    return Result;
-
   case ISD::SELECT:
     Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the condition.
     Tmp2 = LegalizeOp(Node->getOperand(1));   // TrueVal
@@ -2554,89 +2187,6 @@
       break;
     }
     break;
-  case ISD::VSETCC: {
-    Tmp1 = LegalizeOp(Node->getOperand(0));   // LHS
-    Tmp2 = LegalizeOp(Node->getOperand(1));   // RHS
-    SDValue CC = Node->getOperand(2);
-
-    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, CC);
-
-    // Everything is legal, see if we should expand this op or something.
-    switch (TLI.getOperationAction(ISD::VSETCC, Tmp1.getValueType())) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal: break;
-    case TargetLowering::Custom:
-      Tmp1 = TLI.LowerOperation(Result, DAG);
-      if (Tmp1.getNode()) Result = Tmp1;
-      break;
-    case TargetLowering::Expand: {
-      // Unroll into a nasty set of scalar code for now.
-      MVT VT = Node->getValueType(0);
-      unsigned NumElems = VT.getVectorNumElements();
-      MVT EltVT = VT.getVectorElementType();
-      MVT TmpEltVT = Tmp1.getValueType().getVectorElementType();
-      SmallVector<SDValue, 8> Ops(NumElems);
-      for (unsigned i = 0; i < NumElems; ++i) {
-        SDValue In1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT,
-                                  Tmp1, DAG.getIntPtrConstant(i));
-        Ops[i] = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(TmpEltVT),
-                             In1, DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl,
-                                              TmpEltVT, Tmp2,
-                                              DAG.getIntPtrConstant(i)),
-                             CC);
-        Ops[i] = DAG.getNode(ISD::SELECT, dl, EltVT, Ops[i],
-                             DAG.getConstant(APInt::getAllOnesValue
-                                             (EltVT.getSizeInBits()), EltVT),
-                             DAG.getConstant(0, EltVT));
-      }
-      Result = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElems);
-      break;
-    }
-    }
-    break;
-  }
-
-  case ISD::SHL_PARTS:
-  case ISD::SRA_PARTS:
-  case ISD::SRL_PARTS: {
-    SmallVector<SDValue, 8> Ops;
-    bool Changed = false;
-    unsigned N = Node->getNumOperands();
-    for (unsigned i = 0; i + 1 < N; ++i) {
-      Ops.push_back(LegalizeOp(Node->getOperand(i)));
-      Changed |= Ops.back() != Node->getOperand(i);
-    }
-    Ops.push_back(LegalizeOp(DAG.getShiftAmountOperand(Node->getOperand(N-1))));
-    Changed |= Ops.back() != Node->getOperand(N-1);
-    if (Changed)
-      Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size());
-
-    switch (TLI.getOperationAction(Node->getOpcode(),
-                                   Node->getValueType(0))) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal: break;
-    case TargetLowering::Custom:
-      Tmp1 = TLI.LowerOperation(Result, DAG);
-      if (Tmp1.getNode()) {
-        SDValue Tmp2, RetVal(0, 0);
-        for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) {
-          Tmp2 = LegalizeOp(Tmp1.getValue(i));
-          AddLegalizedOperand(SDValue(Node, i), Tmp2);
-          if (i == Op.getResNo())
-            RetVal = Tmp2;
-        }
-        assert(RetVal.getNode() && "Illegal result number");
-        return RetVal;
-      }
-      break;
-    }
-
-    // Since these produce multiple values, make sure to remember that we
-    // legalized all of them.
-    for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i)
-      AddLegalizedOperand(SDValue(Node, i), Result.getValue(i));
-    return Result.getValue(Op.getResNo());
-  }
 
     // Binary operators
   case ISD::ADD:
@@ -2809,21 +2359,6 @@
     }
     }
     break;
-
-  case ISD::SMUL_LOHI:
-  case ISD::UMUL_LOHI:
-  case ISD::SDIVREM:
-  case ISD::UDIVREM:
-    // These nodes will only be produced by target-specific lowering, so
-    // they shouldn't be here if they aren't legal.
-    assert(TLI.isOperationLegal(Node->getOpcode(), Node->getValueType(0)) &&
-           "This must be legal!");
-
-    Tmp1 = LegalizeOp(Node->getOperand(0));   // LHS
-    Tmp2 = LegalizeOp(Node->getOperand(1));   // RHS
-    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
-    break;
-
   case ISD::FCOPYSIGN:  // FCOPYSIGN does not require LHS/RHS to match type!
     Tmp1 = LegalizeOp(Node->getOperand(0));   // LHS
     Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the RHS.
@@ -2878,60 +2413,6 @@
     }
     }
     break;
-
-  case ISD::ADDC:
-  case ISD::SUBC:
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    Tmp2 = LegalizeOp(Node->getOperand(1));
-    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
-    Tmp3 = Result.getValue(0);
-    Tmp4 = Result.getValue(1);
-
-    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal:
-      break;
-    case TargetLowering::Custom:
-      Tmp1 = TLI.LowerOperation(Tmp3, DAG);
-      if (Tmp1.getNode() != NULL) {
-        Tmp3 = LegalizeOp(Tmp1);
-        Tmp4 = LegalizeOp(Tmp1.getValue(1));
-      }
-      break;
-    }
-    // Since this produces two values, make sure to remember that we legalized
-    // both of them.
-    AddLegalizedOperand(SDValue(Node, 0), Tmp3);
-    AddLegalizedOperand(SDValue(Node, 1), Tmp4);
-    return Op.getResNo() ? Tmp4 : Tmp3;
-
-  case ISD::ADDE:
-  case ISD::SUBE:
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    Tmp2 = LegalizeOp(Node->getOperand(1));
-    Tmp3 = LegalizeOp(Node->getOperand(2));
-    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3);
-    Tmp3 = Result.getValue(0);
-    Tmp4 = Result.getValue(1);
-
-    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal:
-      break;
-    case TargetLowering::Custom:
-      Tmp1 = TLI.LowerOperation(Tmp3, DAG);
-      if (Tmp1.getNode() != NULL) {
-        Tmp3 = LegalizeOp(Tmp1);
-        Tmp4 = LegalizeOp(Tmp1.getValue(1));
-      }
-      break;
-    }
-    // Since this produces two values, make sure to remember that we legalized
-    // both of them.
-    AddLegalizedOperand(SDValue(Node, 0), Tmp3);
-    AddLegalizedOperand(SDValue(Node, 1), Tmp4);
-    return Op.getResNo() ? Tmp4 : Tmp3;
-
   case ISD::BUILD_PAIR: {
     MVT PairTy = Node->getValueType(0);
     // TODO: handle the case where the Lo and Hi operands are not of legal type
@@ -3083,237 +2564,69 @@
     AddLegalizedOperand(SDValue(Node, 1), Tmp1);
     return Op.getResNo() ? Tmp1 : Result;
   }
-
-  case ISD::VACOPY:
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the dest pointer.
-    Tmp3 = LegalizeOp(Node->getOperand(2));  // Legalize the source pointer.
-
-    switch (TLI.getOperationAction(ISD::VACOPY, MVT::Other)) {
-    default: assert(0 && "This action is not supported yet!");
+    // Unary operators
+  case ISD::FABS:
+  case ISD::FNEG:
+  case ISD::FSQRT:
+  case ISD::FSIN:
+  case ISD::FCOS:
+  case ISD::FLOG:
+  case ISD::FLOG2:
+  case ISD::FLOG10:
+  case ISD::FEXP:
+  case ISD::FEXP2:
+  case ISD::FTRUNC:
+  case ISD::FFLOOR:
+  case ISD::FCEIL:
+  case ISD::FRINT:
+  case ISD::FNEARBYINT:
+    Tmp1 = LegalizeOp(Node->getOperand(0));
+    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
+    case TargetLowering::Promote:
     case TargetLowering::Custom:
-      isCustom = true;
-      // FALLTHROUGH
+     isCustom = true;
+     // FALLTHROUGH
     case TargetLowering::Legal:
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3,
-                                      Node->getOperand(3), Node->getOperand(4));
+      Result = DAG.UpdateNodeOperands(Result, Tmp1);
       if (isCustom) {
         Tmp1 = TLI.LowerOperation(Result, DAG);
         if (Tmp1.getNode()) Result = Tmp1;
       }
       break;
     case TargetLowering::Expand:
-      // This defaults to loading a pointer from the input and storing it to the
-      // output, returning the chain.
-      const Value *VD = cast<SrcValueSDNode>(Node->getOperand(3))->getValue();
-      const Value *VS = cast<SrcValueSDNode>(Node->getOperand(4))->getValue();
-      Tmp4 = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp3, VS, 0);
-      Result = DAG.getStore(Tmp4.getValue(1), dl, Tmp4, Tmp2, VD, 0);
-      break;
-    }
-    break;
-
-  case ISD::VAEND:
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the pointer.
-
-    switch (TLI.getOperationAction(ISD::VAEND, MVT::Other)) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Custom:
-      isCustom = true;
-      // FALLTHROUGH
-    case TargetLowering::Legal:
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
-      if (isCustom) {
-        Tmp1 = TLI.LowerOperation(Tmp1, DAG);
-        if (Tmp1.getNode()) Result = Tmp1;
+      switch (Node->getOpcode()) {
+      default: assert(0 && "Unreachable!");
+      case ISD::FNEG:
+        // Expand Y = FNEG(X) ->  Y = SUB -0.0, X
+        Tmp2 = DAG.getConstantFP(-0.0, Node->getValueType(0));
+        Result = DAG.getNode(ISD::FSUB, dl, Node->getValueType(0), Tmp2, Tmp1);
+        break;
+      case ISD::FABS: {
+        // Expand Y = FABS(X) -> Y = (X >u 0.0) ? X : fneg(X).
+        MVT VT = Node->getValueType(0);
+        Tmp2 = DAG.getConstantFP(0.0, VT);
+        Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()),
+                            Tmp1, Tmp2, ISD::SETUGT);
+        Tmp3 = DAG.getNode(ISD::FNEG, dl, VT, Tmp1);
+        Result = DAG.getNode(ISD::SELECT, dl, VT, Tmp2, Tmp1, Tmp3);
+        break;
       }
-      break;
-    case TargetLowering::Expand:
-      Result = Tmp1; // Default to a no-op, return the chain
-      break;
-    }
-    break;
-
-  case ISD::VASTART:
-    Tmp1 = LegalizeOp(Node->getOperand(0));  // Legalize the chain.
-    Tmp2 = LegalizeOp(Node->getOperand(1));  // Legalize the pointer.
+      case ISD::FSQRT:
+      case ISD::FSIN:
+      case ISD::FCOS:
+      case ISD::FLOG:
+      case ISD::FLOG2:
+      case ISD::FLOG10:
+      case ISD::FEXP:
+      case ISD::FEXP2:
+      case ISD::FTRUNC:
+      case ISD::FFLOOR:
+      case ISD::FCEIL:
+      case ISD::FRINT:
+      case ISD::FNEARBYINT: {
+        MVT VT = Node->getValueType(0);
 
-    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2));
-
-    switch (TLI.getOperationAction(ISD::VASTART, MVT::Other)) {
-    default: assert(0 && "This action is not supported yet!");
-    case TargetLowering::Legal: break;
-    case TargetLowering::Custom:
-      Tmp1 = TLI.LowerOperation(Result, DAG);
-      if (Tmp1.getNode()) Result = Tmp1;
-      break;
-    }
-    break;
-
-  case ISD::ROTL:
-  case ISD::ROTR:
-    Tmp1 = LegalizeOp(Node->getOperand(0));   // LHS
-    Tmp2 = LegalizeOp(DAG.getShiftAmountOperand(Node->getOperand(1)));   // RHS
-    Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
-    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
-    default:
-      assert(0 && "ROTL/ROTR legalize operation not supported");
-      break;
-    case TargetLowering::Legal:
-      break;
-    case TargetLowering::Custom:
-      Tmp1 = TLI.LowerOperation(Result, DAG);
-      if (Tmp1.getNode()) Result = Tmp1;
-      break;
-    case TargetLowering::Promote:
-      assert(0 && "Do not know how to promote ROTL/ROTR");
-      break;
-    case TargetLowering::Expand:
-      assert(0 && "Do not know how to expand ROTL/ROTR");
-      break;
-    }
-    break;
-
-  case ISD::BSWAP:
-    Tmp1 = LegalizeOp(Node->getOperand(0));   // Op
-    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
-    case TargetLowering::Custom:
-      assert(0 && "Cannot custom legalize this yet!");
-    case TargetLowering::Legal:
-      Result = DAG.UpdateNodeOperands(Result, Tmp1);
-      break;
-    case TargetLowering::Promote: {
-      MVT OVT = Tmp1.getValueType();
-      MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT);
-      unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits();
-
-      Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Tmp1);
-      Tmp1 = DAG.getNode(ISD::BSWAP, dl, NVT, Tmp1);
-      Result = DAG.getNode(ISD::SRL, dl, NVT, Tmp1,
-                           DAG.getConstant(DiffBits, TLI.getShiftAmountTy()));
-      break;
-    }
-    case TargetLowering::Expand:
-      Result = ExpandBSWAP(Tmp1, dl);
-      break;
-    }
-    break;
-
-  case ISD::CTPOP:
-  case ISD::CTTZ:
-  case ISD::CTLZ:
-    Tmp1 = LegalizeOp(Node->getOperand(0));   // Op
-    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
-    case TargetLowering::Custom:
-    case TargetLowering::Legal:
-      Result = DAG.UpdateNodeOperands(Result, Tmp1);
-      if (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)) ==
-          TargetLowering::Custom) {
-        Tmp1 = TLI.LowerOperation(Result, DAG);
-        if (Tmp1.getNode()) {
-          Result = Tmp1;
-        }
-      }
-      break;
-    case TargetLowering::Promote: {
-      MVT OVT = Tmp1.getValueType();
-      MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT);
-
-      // Zero extend the argument.
-      Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Tmp1);
-      // Perform the larger operation, then subtract if needed.
-      Tmp1 = DAG.getNode(Node->getOpcode(), dl, Node->getValueType(0), Tmp1);
-      switch (Node->getOpcode()) {
-      case ISD::CTPOP:
-        Result = Tmp1;
-        break;
-      case ISD::CTTZ:
-        //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
-        Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()),
-                            Tmp1, DAG.getConstant(NVT.getSizeInBits(), NVT),
-                            ISD::SETEQ);
-        Result = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2,
-                             DAG.getConstant(OVT.getSizeInBits(), NVT), Tmp1);
-        break;
-      case ISD::CTLZ:
-        // Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT))
-        Result = DAG.getNode(ISD::SUB, dl, NVT, Tmp1,
-                             DAG.getConstant(NVT.getSizeInBits() -
-                                             OVT.getSizeInBits(), NVT));
-        break;
-      }
-      break;
-    }
-    case TargetLowering::Expand:
-      Result = ExpandBitCount(Node->getOpcode(), Tmp1, dl);
-      break;
-    }
-    break;
-
-    // Unary operators
-  case ISD::FABS:
-  case ISD::FNEG:
-  case ISD::FSQRT:
-  case ISD::FSIN:
-  case ISD::FCOS:
-  case ISD::FLOG:
-  case ISD::FLOG2:
-  case ISD::FLOG10:
-  case ISD::FEXP:
-  case ISD::FEXP2:
-  case ISD::FTRUNC:
-  case ISD::FFLOOR:
-  case ISD::FCEIL:
-  case ISD::FRINT:
-  case ISD::FNEARBYINT:
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
-    case TargetLowering::Promote:
-    case TargetLowering::Custom:
-     isCustom = true;
-     // FALLTHROUGH
-    case TargetLowering::Legal:
-      Result = DAG.UpdateNodeOperands(Result, Tmp1);
-      if (isCustom) {
-        Tmp1 = TLI.LowerOperation(Result, DAG);
-        if (Tmp1.getNode()) Result = Tmp1;
-      }
-      break;
-    case TargetLowering::Expand:
-      switch (Node->getOpcode()) {
-      default: assert(0 && "Unreachable!");
-      case ISD::FNEG:
-        // Expand Y = FNEG(X) ->  Y = SUB -0.0, X
-        Tmp2 = DAG.getConstantFP(-0.0, Node->getValueType(0));
-        Result = DAG.getNode(ISD::FSUB, dl, Node->getValueType(0), Tmp2, Tmp1);
-        break;
-      case ISD::FABS: {
-        // Expand Y = FABS(X) -> Y = (X >u 0.0) ? X : fneg(X).
-        MVT VT = Node->getValueType(0);
-        Tmp2 = DAG.getConstantFP(0.0, VT);
-        Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()),
-                            Tmp1, Tmp2, ISD::SETUGT);
-        Tmp3 = DAG.getNode(ISD::FNEG, dl, VT, Tmp1);
-        Result = DAG.getNode(ISD::SELECT, dl, VT, Tmp2, Tmp1, Tmp3);
-        break;
-      }
-      case ISD::FSQRT:
-      case ISD::FSIN:
-      case ISD::FCOS:
-      case ISD::FLOG:
-      case ISD::FLOG2:
-      case ISD::FLOG10:
-      case ISD::FEXP:
-      case ISD::FEXP2:
-      case ISD::FTRUNC:
-      case ISD::FFLOOR:
-      case ISD::FCEIL:
-      case ISD::FRINT:
-      case ISD::FNEARBYINT: {
-        MVT VT = Node->getValueType(0);
-
-        assert(!VT.isVector() && "Vector shouldn't get here!");
+        assert(!VT.isVector() && "Vector shouldn't get here!");
 
         RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
         switch(Node->getOpcode()) {
@@ -3393,264 +2706,6 @@
     Result = ExpandLibCall(LC, Node, false/*sign irrelevant*/, Dummy);
     break;
   }
-  case ISD::BIT_CONVERT:
-    switch (TLI.getOperationAction(ISD::BIT_CONVERT,
-                                   Node->getOperand(0).getValueType())) {
-    default: assert(0 && "Unknown operation action!");
-    case TargetLowering::Expand:
-      Result = EmitStackConvert(Node->getOperand(0), Node->getValueType(0),
-                                Node->getValueType(0), dl);
-      break;
-    case TargetLowering::Legal:
-      Tmp1 = LegalizeOp(Node->getOperand(0));
-      Result = DAG.UpdateNodeOperands(Result, Tmp1);
-      break;
-    }
-    break;
-  case ISD::CONVERT_RNDSAT: {
-    ISD::CvtCode CvtCode = cast<CvtRndSatSDNode>(Node)->getCvtCode();
-    switch (CvtCode) {
-    default: assert(0 && "Unknown cvt code!");
-    case ISD::CVT_SF:
-    case ISD::CVT_UF:
-    case ISD::CVT_FF:
-      break;
-    case ISD::CVT_FS:
-    case ISD::CVT_FU:
-    case ISD::CVT_SS:
-    case ISD::CVT_SU:
-    case ISD::CVT_US:
-    case ISD::CVT_UU: {
-      SDValue DTyOp = Node->getOperand(1);
-      SDValue STyOp = Node->getOperand(2);
-      SDValue RndOp = Node->getOperand(3);
-      SDValue SatOp = Node->getOperand(4);
-      Tmp1 = LegalizeOp(Node->getOperand(0));
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, DTyOp, STyOp,
-                                      RndOp, SatOp);
-      if (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)) ==
-          TargetLowering::Custom) {
-        Tmp1 = TLI.LowerOperation(Result, DAG);
-        if (Tmp1.getNode()) Result = Tmp1;
-      }
-      break;
-    }
-    } // end switch CvtCode
-    break;
-  }
-    // Conversion operators.  The source and destination have different types.
-  case ISD::SINT_TO_FP:
-  case ISD::UINT_TO_FP: {
-    bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP;
-    Result = LegalizeINT_TO_FP(Result, isSigned,
-                               Node->getValueType(0), Node->getOperand(0), dl);
-    break;
-  }
-  case ISD::TRUNCATE:
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) {
-    default: assert(0 && "Unknown TRUNCATE legalization operation action!");
-    case TargetLowering::Custom:
-      isCustom = true;
-      // FALLTHROUGH
-    case TargetLowering::Legal:
-      Result = DAG.UpdateNodeOperands(Result, Tmp1);
-      if (isCustom) {
-        Tmp1 = TLI.LowerOperation(Result, DAG);
-        if (Tmp1.getNode()) Result = Tmp1;
-      }
-      break;
-    }
-    break;
-
-  case ISD::FP_TO_SINT:
-  case ISD::FP_TO_UINT:
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-
-    switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))){
-    default: assert(0 && "Unknown operation action!");
-    case TargetLowering::Custom:
-      isCustom = true;
-      // FALLTHROUGH
-    case TargetLowering::Legal:
-      Result = DAG.UpdateNodeOperands(Result, Tmp1);
-      if (isCustom) {
-        Tmp1 = TLI.LowerOperation(Result, DAG);
-        if (Tmp1.getNode()) Result = Tmp1;
-      }
-      break;
-    case TargetLowering::Promote:
-      Result = PromoteLegalFP_TO_INT(Tmp1, Node->getValueType(0),
-                                     Node->getOpcode() == ISD::FP_TO_SINT,
-                                     dl);
-      break;
-    case TargetLowering::Expand:
-      if (Node->getOpcode() == ISD::FP_TO_UINT) {
-        SDValue True, False;
-        MVT VT =  Node->getOperand(0).getValueType();
-        MVT NVT = Node->getValueType(0);
-        const uint64_t zero[] = {0, 0};
-        APFloat apf = APFloat(APInt(VT.getSizeInBits(), 2, zero));
-        APInt x = APInt::getSignBit(NVT.getSizeInBits());
-        (void)apf.convertFromAPInt(x, false, APFloat::rmNearestTiesToEven);
-        Tmp2 = DAG.getConstantFP(apf, VT);
-        Tmp3 = DAG.getSetCC(dl, TLI.getSetCCResultType(VT),
-                            Node->getOperand(0),
-                            Tmp2, ISD::SETLT);
-        True = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, Node->getOperand(0));
-        False = DAG.getNode(ISD::FP_TO_SINT, dl, NVT,
-                            DAG.getNode(ISD::FSUB, dl, VT,
-                                        Node->getOperand(0), Tmp2));
-        False = DAG.getNode(ISD::XOR, dl, NVT, False,
-                            DAG.getConstant(x, NVT));
-        Result = DAG.getNode(ISD::SELECT, dl, NVT, Tmp3, True, False);
-      } else {
-        assert(0 && "Do not know how to expand FP_TO_SINT yet!");
-      }
-      break;
-    }
-    break;
-
-  case ISD::FP_EXTEND: {
-    MVT DstVT = Op.getValueType();
-    MVT SrcVT = Op.getOperand(0).getValueType();
-    if (TLI.getConvertAction(SrcVT, DstVT) == TargetLowering::Expand) {
-      // The only other way we can lower this is to turn it into a STORE,
-      // LOAD pair, targetting a temporary location (a stack slot).
-      Result = EmitStackConvert(Node->getOperand(0), SrcVT, DstVT, dl);
-      break;
-    }
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    Result = DAG.UpdateNodeOperands(Result, Tmp1);
-    break;
-  }
-  case ISD::FP_ROUND: {
-    MVT DstVT = Op.getValueType();
-    MVT SrcVT = Op.getOperand(0).getValueType();
-    if (TLI.getConvertAction(SrcVT, DstVT) == TargetLowering::Expand) {
-      if (SrcVT == MVT::ppcf128) {
-        // FIXME: Figure out how to extract the double without
-        // help from type legalization
-      }
-      // The only other way we can lower this is to turn it into a STORE,
-      // LOAD pair, targetting a temporary location (a stack slot).
-      Result = EmitStackConvert(Node->getOperand(0), DstVT, DstVT, dl);
-      break;
-    }
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1));
-    break;
-  }
-  case ISD::ANY_EXTEND:
-  case ISD::ZERO_EXTEND:
-  case ISD::SIGN_EXTEND:
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    Result = DAG.UpdateNodeOperands(Result, Tmp1);
-    if (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)) ==
-        TargetLowering::Custom) {
-      Tmp1 = TLI.LowerOperation(Result, DAG);
-      if (Tmp1.getNode()) Result = Tmp1;
-    }
-    break;
-  case ISD::FP_ROUND_INREG:
-  case ISD::SIGN_EXTEND_INREG: {
-    Tmp1 = LegalizeOp(Node->getOperand(0));
-    MVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
-
-    // If this operation is not supported, convert it to a shl/shr or load/store
-    // pair.
-    switch (TLI.getOperationAction(Node->getOpcode(), ExtraVT)) {
-    default: assert(0 && "This action not supported for this op yet!");
-    case TargetLowering::Legal:
-      Result = DAG.UpdateNodeOperands(Result, Tmp1, Node->getOperand(1));
-      break;
-    case TargetLowering::Expand:
-      // If this is an integer extend and shifts are supported, do that.
-      if (Node->getOpcode() == ISD::SIGN_EXTEND_INREG) {
-        // NOTE: we could fall back on load/store here too for targets without
-        // SAR.  However, it is doubtful that any exist.
-        unsigned BitsDiff = Node->getValueType(0).getSizeInBits() -
-                            ExtraVT.getSizeInBits();
-        SDValue ShiftCst = DAG.getConstant(BitsDiff, TLI.getShiftAmountTy());
-        Result = DAG.getNode(ISD::SHL, dl, Node->getValueType(0),
-                             Node->getOperand(0), ShiftCst);
-        Result = DAG.getNode(ISD::SRA, dl, Node->getValueType(0),
-                             Result, ShiftCst);
-      } else if (Node->getOpcode() == ISD::FP_ROUND_INREG) {
-        // The only way we can lower this is to turn it into a TRUNCSTORE,
-        // EXTLOAD pair, targetting a temporary location (a stack slot).
-
-        // NOTE: there is a choice here between constantly creating new stack
-        // slots and always reusing the same one.  We currently always create
-        // new ones, as reuse may inhibit scheduling.
-        Result = EmitStackConvert(Node->getOperand(0), ExtraVT,
-                                  Node->getValueType(0), dl);
-      } else {
-        assert(0 && "Unknown op");
-      }
-      break;
-    }
-    break;
-  }
-  case ISD::TRAMPOLINE: {
-    SDValue Ops[6];
-    for (unsigned i = 0; i != 6; ++i)
-      Ops[i] = LegalizeOp(Node->getOperand(i));
-    Result = DAG.UpdateNodeOperands(Result, Ops, 6);
-    // The only option for this node is to custom lower it.
-    Result = TLI.LowerOperation(Result, DAG);
-    assert(Result.getNode() && "Should always custom lower!");
-
-    // Since trampoline produces two values, make sure to remember that we
-    // legalized both of them.
-    Tmp1 = LegalizeOp(Result.getValue(1));
-    Result = LegalizeOp(Result);
-    AddLegalizedOperand(SDValue(Node, 0), Result);
-    AddLegalizedOperand(SDValue(Node, 1), Tmp1);
-    return Op.getResNo() ? Tmp1 : Result;
-  }
-  case ISD::FLT_ROUNDS_: {
-    MVT VT = Node->getValueType(0);
-    switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
-    default: assert(0 && "This action not supported for this op yet!");
-    case TargetLowering::Custom:
-      Result = TLI.LowerOperation(Op, DAG);
-      if (Result.getNode()) break;
-      // Fall Thru
-    case TargetLowering::Legal:
-      // If this operation is not supported, lower it to constant 1
-      Result = DAG.getConstant(1, VT);
-      break;
-    }
-    break;
-  }
-  case ISD::TRAP: {
-    MVT VT = Node->getValueType(0);
-    switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
-    default: assert(0 && "This action not supported for this op yet!");
-    case TargetLowering::Legal:
-      Tmp1 = LegalizeOp(Node->getOperand(0));
-      Result = DAG.UpdateNodeOperands(Result, Tmp1);
-      break;
-    case TargetLowering::Custom:
-      Result = TLI.LowerOperation(Op, DAG);
-      if (Result.getNode()) break;
-      // Fall Thru
-    case TargetLowering::Expand:
-      // If this operation is not supported, lower it to 'abort()' call
-      Tmp1 = LegalizeOp(Node->getOperand(0));
-      TargetLowering::ArgListTy Args;
-      std::pair<SDValue, SDValue> CallResult =
-        TLI.LowerCallTo(Tmp1, Type::VoidTy,
-                        false, false, false, false, CallingConv::C, false,
-                        DAG.getExternalSymbol("abort", TLI.getPointerTy()),
-                        Args, DAG, dl);
-      Result = CallResult.second;
-      break;
-    }
-    break;
-  }
-
   case ISD::SADDO:
   case ISD::SSUBO: {
     MVT VT = Node->getValueType(0);
@@ -3740,25 +2795,6 @@
 
     break;
   }
-  case ISD::SMULO:
-  case ISD::UMULO: {
-    MVT VT = Node->getValueType(0);
-    switch (TLI.getOperationAction(Node->getOpcode(), VT)) {
-    default: assert(0 && "This action is not supported at all!");
-    case TargetLowering::Custom:
-      Result = TLI.LowerOperation(Op, DAG);
-      if (Result.getNode()) break;
-      // Fall Thru
-    case TargetLowering::Legal:
-      // FIXME: According to Hacker's Delight, this can be implemented in
-      // target independent lowering, but it would be inefficient, since it
-      // requires a division + a branch.
-      assert(0 && "Target independent lowering is not supported for SMULO/UMULO!");
-    break;
-    }
-    break;
-  }
-
   }
 
   assert(Result.getValueType() == Op.getValueType() &&
@@ -3774,52 +2810,6 @@
   return Result;
 }
 
-/// ExpandEXTRACT_VECTOR_ELT - Expand an EXTRACT_VECTOR_ELT operation into
-/// a legal EXTRACT_VECTOR_ELT operation, scalar code, or memory traffic,
-/// based on the vector type. The return type of this matches the element type
-/// of the vector, which may not be legal for the target.
-SDValue SelectionDAGLegalize::ExpandEXTRACT_VECTOR_ELT(SDValue Op) {
-  // We know that operand #0 is the Vec vector.  If the index is a constant
-  // or if the invec is a supported hardware type, we can use it.  Otherwise,
-  // lower to a store then an indexed load.
-  SDValue Vec = Op.getOperand(0);
-  SDValue Idx = Op.getOperand(1);
-  DebugLoc dl = Op.getDebugLoc();
-
-  MVT TVT = Vec.getValueType();
-  unsigned NumElems = TVT.getVectorNumElements();
-
-  switch (TLI.getOperationAction(ISD::EXTRACT_VECTOR_ELT, TVT)) {
-  default: assert(0 && "This action is not supported yet!");
-  case TargetLowering::Custom: {
-    Vec = LegalizeOp(Vec);
-    Op = DAG.UpdateNodeOperands(Op, Vec, Idx);
-    SDValue Tmp3 = TLI.LowerOperation(Op, DAG);
-    if (Tmp3.getNode())
-      return Tmp3;
-    break;
-  }
-  case TargetLowering::Legal:
-    if (isTypeLegal(TVT)) {
-      Vec = LegalizeOp(Vec);
-      Op = DAG.UpdateNodeOperands(Op, Vec, Idx);
-      return Op;
-    }
-    break;
-  case TargetLowering::Promote:
-    assert(TVT.isVector() && "not vector type");
-    // fall thru to expand since vectors are by default are promote
-  case TargetLowering::Expand:
-    break;
-  }
-
-  if (NumElems == 1)
-    // This must be an access of the only element.  Return it.
-    return DAG.getNode(ISD::BIT_CONVERT, dl, Op.getValueType(), Vec);
-  else
-    return ExpandExtractFromVectorThroughStack(Op);
-}
-
 SDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) {
   SDValue Vec = Op.getOperand(0);
   SDValue Idx = Op.getOperand(1);
@@ -4169,41 +3159,6 @@
   return CallInfo.first;
 }
 
-/// LegalizeINT_TO_FP - Legalize a [US]INT_TO_FP operation.
-///
-SDValue SelectionDAGLegalize::
-LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, SDValue Op,
-                  DebugLoc dl) {
-  bool isCustom = false;
-  SDValue Tmp1;
-  switch (TLI.getOperationAction(isSigned ? ISD::SINT_TO_FP : ISD::UINT_TO_FP,
-                                 Op.getValueType())) {
-  default: assert(0 && "Unknown operation action!");
-  case TargetLowering::Custom:
-    isCustom = true;
-    // FALLTHROUGH
-  case TargetLowering::Legal:
-    Tmp1 = LegalizeOp(Op);
-    if (Result.getNode())
-      Result = DAG.UpdateNodeOperands(Result, Tmp1);
-    else
-      Result = DAG.getNode(isSigned ? ISD::SINT_TO_FP : ISD::UINT_TO_FP, dl,
-                           DestTy, Tmp1);
-    if (isCustom) {
-      Tmp1 = TLI.LowerOperation(Result, DAG);
-      if (Tmp1.getNode()) Result = Tmp1;
-    }
-    break;
-  case TargetLowering::Expand:
-    Result = ExpandLegalINT_TO_FP(isSigned, LegalizeOp(Op), DestTy, dl);
-    break;
-  case TargetLowering::Promote:
-    Result = PromoteLegalINT_TO_FP(LegalizeOp(Op), DestTy, isSigned, dl);
-    break;
-  }
-  return Result;
-}
-
 /// ExpandLegalINT_TO_FP - This function is responsible for legalizing a
 /// INT_TO_FP operation of the specified operand when the target requests that
 /// we expand it.  At this point, we know that the result and operand types are
@@ -4551,6 +3506,229 @@
   }
 }
 
+void SelectionDAGLegalize::ExpandNode(SDNode *Node,
+                                      SmallVectorImpl<SDValue> &Results) {
+  DebugLoc dl = Node->getDebugLoc();
+  SDValue Tmp1, Tmp2;
+  switch (Node->getOpcode()) {
+  case ISD::CTPOP:
+  case ISD::CTLZ:
+  case ISD::CTTZ:
+    Tmp1 = ExpandBitCount(Node->getOpcode(), Node->getOperand(0), dl);
+    Results.push_back(Tmp1);
+    break;
+  case ISD::BSWAP:
+    Results.push_back(ExpandBSWAP(Node->getOperand(0), dl));
+    break;
+  case ISD::FRAMEADDR:
+  case ISD::RETURNADDR:
+  case ISD::FRAME_TO_ARGS_OFFSET:
+    Results.push_back(DAG.getConstant(0, Node->getValueType(0)));
+    break;
+  case ISD::FLT_ROUNDS_:
+    Results.push_back(DAG.getConstant(1, Node->getValueType(0)));
+    break;
+  case ISD::EH_RETURN:
+  case ISD::DECLARE:
+  case ISD::DBG_LABEL:
+  case ISD::EH_LABEL:
+  case ISD::PREFETCH:
+  case ISD::MEMBARRIER:
+  case ISD::VAEND:
+    Results.push_back(Node->getOperand(0));
+    break;
+  case ISD::MERGE_VALUES:
+    for (unsigned i = 0; i < Node->getNumValues(); i++)
+      Results.push_back(Node->getOperand(i));
+    break;
+  case ISD::UNDEF: {
+    MVT VT = Node->getValueType(0);
+    if (VT.isInteger())
+      Results.push_back(DAG.getConstant(0, VT));
+    else if (VT.isFloatingPoint())
+      Results.push_back(DAG.getConstantFP(0, VT));
+    else
+      assert(0 && "Unknown value type!");
+    break;
+  }
+  case ISD::TRAP: {
+    // If this operation is not supported, lower it to 'abort()' call
+    TargetLowering::ArgListTy Args;
+    std::pair<SDValue, SDValue> CallResult =
+      TLI.LowerCallTo(Node->getOperand(0), Type::VoidTy,
+                      false, false, false, false, CallingConv::C, false,
+                      DAG.getExternalSymbol("abort", TLI.getPointerTy()),
+                      Args, DAG, dl);
+    Results.push_back(CallResult.second);
+    break;
+  }
+  case ISD::FP_ROUND:
+  case ISD::BIT_CONVERT:
+    Tmp1 = EmitStackConvert(Node->getOperand(0), Node->getValueType(0),
+                            Node->getValueType(0), dl);
+    Results.push_back(Tmp1);
+    break;
+  case ISD::FP_EXTEND:
+    Tmp1 = EmitStackConvert(Node->getOperand(0),
+                            Node->getOperand(0).getValueType(),
+                            Node->getValueType(0), dl);
+    Results.push_back(Tmp1);
+    break;
+  case ISD::SIGN_EXTEND_INREG: {
+    // NOTE: we could fall back on load/store here too for targets without
+    // SAR.  However, it is doubtful that any exist.
+    MVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
+    unsigned BitsDiff = Node->getValueType(0).getSizeInBits() -
+                        ExtraVT.getSizeInBits();
+    SDValue ShiftCst = DAG.getConstant(BitsDiff, TLI.getShiftAmountTy());
+    Tmp1 = DAG.getNode(ISD::SHL, dl, Node->getValueType(0),
+                       Node->getOperand(0), ShiftCst);
+    Tmp1 = DAG.getNode(ISD::SRA, dl, Node->getValueType(0), Tmp1, ShiftCst);
+    Results.push_back(Tmp1);
+    break;
+  }
+  case ISD::FP_ROUND_INREG: {
+    // The only way we can lower this is to turn it into a TRUNCSTORE,
+    // EXTLOAD pair, targetting a temporary location (a stack slot).
+
+    // NOTE: there is a choice here between constantly creating new stack
+    // slots and always reusing the same one.  We currently always create
+    // new ones, as reuse may inhibit scheduling.
+    MVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT();
+    Tmp1 = EmitStackConvert(Node->getOperand(0), ExtraVT,
+                            Node->getValueType(0), dl);
+    Results.push_back(Tmp1);
+    break;
+  }
+  case ISD::SINT_TO_FP:
+  case ISD::UINT_TO_FP:
+    Tmp1 = ExpandLegalINT_TO_FP(Node->getOpcode() == ISD::SINT_TO_FP,
+                                Node->getOperand(0), Node->getValueType(0), dl);
+    Results.push_back(Tmp1);
+    break;
+  case ISD::FP_TO_UINT: {
+    SDValue True, False;
+    MVT VT =  Node->getOperand(0).getValueType();
+    MVT NVT = Node->getValueType(0);
+    const uint64_t zero[] = {0, 0};
+    APFloat apf = APFloat(APInt(VT.getSizeInBits(), 2, zero));
+    APInt x = APInt::getSignBit(NVT.getSizeInBits());
+    (void)apf.convertFromAPInt(x, false, APFloat::rmNearestTiesToEven);
+    Tmp1 = DAG.getConstantFP(apf, VT);
+    Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(VT),
+                        Node->getOperand(0),
+                        Tmp1, ISD::SETLT);
+    True = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, Node->getOperand(0));
+    False = DAG.getNode(ISD::FP_TO_SINT, dl, NVT,
+                        DAG.getNode(ISD::FSUB, dl, VT,
+                                    Node->getOperand(0), Tmp1));
+    False = DAG.getNode(ISD::XOR, dl, NVT, False,
+                        DAG.getConstant(x, NVT));
+    Tmp1 = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2, True, False);
+    Results.push_back(Tmp1);
+    break;
+  }
+  case ISD::VACOPY: {
+    // This defaults to loading a pointer from the input and storing it to the
+    // output, returning the chain.
+    const Value *VD = cast<SrcValueSDNode>(Node->getOperand(3))->getValue();
+    const Value *VS = cast<SrcValueSDNode>(Node->getOperand(4))->getValue();
+    Tmp1 = DAG.getLoad(TLI.getPointerTy(), dl, Node->getOperand(0),
+                       Node->getOperand(2), VS, 0);
+    Tmp1 = DAG.getStore(Tmp1.getValue(1), dl, Tmp1, Node->getOperand(1), VD, 0);
+    Results.push_back(Tmp1);
+    break;
+  }
+  case ISD::EXTRACT_VECTOR_ELT:
+    if (Node->getOperand(0).getValueType().getVectorNumElements() == 1)
+      // This must be an access of the only element.  Return it.
+      Tmp1 = DAG.getNode(ISD::BIT_CONVERT, dl, Node->getValueType(0), 
+                         Node->getOperand(0));
+    else
+      Tmp1 = ExpandExtractFromVectorThroughStack(SDValue(Node, 0));
+    Results.push_back(Tmp1);
+    break;
+  case ISD::EXTRACT_SUBVECTOR:
+    Results.push_back(ExpandExtractFromVectorThroughStack(SDValue(Node, 0)));
+    break;
+  case ISD::SCALAR_TO_VECTOR:
+    Results.push_back(ExpandSCALAR_TO_VECTOR(Node));
+    break;
+  case ISD::EXTRACT_ELEMENT: {
+    MVT OpTy = Node->getOperand(0).getValueType();
+    if (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) {
+      // 1 -> Hi
+      Tmp1 = DAG.getNode(ISD::SRL, dl, OpTy, Node->getOperand(0),
+                         DAG.getConstant(OpTy.getSizeInBits()/2,
+                                         TLI.getShiftAmountTy()));
+      Tmp1 = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Tmp1);
+    } else {
+      // 0 -> Lo
+      Tmp1 = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0),
+                         Node->getOperand(0));
+    }
+    Results.push_back(Tmp1);
+    break;
+  }
+  }
+}
+void SelectionDAGLegalize::PromoteNode(SDNode *Node,
+                                       SmallVectorImpl<SDValue> &Results) {
+  MVT OVT = Node->getValueType(0);
+  if (Node->getOpcode() == ISD::UINT_TO_FP ||
+      Node->getOpcode() == ISD::SINT_TO_FP) {
+    OVT = Node->getOperand(0).getValueType();
+  }
+  MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT);
+  DebugLoc dl = Node->getDebugLoc();
+  SDValue Tmp1, Tmp2;
+  switch (Node->getOpcode()) {
+  case ISD::CTTZ:
+  case ISD::CTLZ:
+  case ISD::CTPOP:
+    // Zero extend the argument.
+    Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Node->getOperand(0));
+    // Perform the larger operation.
+    Tmp1 = DAG.getNode(Node->getOpcode(), dl, Node->getValueType(0), Tmp1);
+    if (Node->getOpcode() == ISD::CTTZ) {
+      //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT)
+      Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()),
+                          Tmp1, DAG.getConstant(NVT.getSizeInBits(), NVT),
+                          ISD::SETEQ);
+      Tmp1 = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2,
+                          DAG.getConstant(OVT.getSizeInBits(), NVT), Tmp1);
+    } else if (Node->getOpcode() == ISD::CTLZ) {
+      // Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT))
+      Tmp1 = DAG.getNode(ISD::SUB, dl, NVT, Tmp1,
+                          DAG.getConstant(NVT.getSizeInBits() -
+                                          OVT.getSizeInBits(), NVT));
+    }
+    Results.push_back(Tmp1);
+    break;
+  case ISD::BSWAP: {
+    unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits();
+    Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Tmp1);
+    Tmp1 = DAG.getNode(ISD::BSWAP, dl, NVT, Tmp1);
+    Tmp1 = DAG.getNode(ISD::SRL, dl, NVT, Tmp1,
+                          DAG.getConstant(DiffBits, TLI.getShiftAmountTy()));
+    Results.push_back(Tmp1);
+    break;
+  }
+  case ISD::FP_TO_UINT:
+  case ISD::FP_TO_SINT:
+    Tmp1 = PromoteLegalFP_TO_INT(Node->getOperand(0), Node->getValueType(0),
+                                 Node->getOpcode() == ISD::FP_TO_SINT, dl);
+    Results.push_back(Tmp1);
+    break;
+  case ISD::UINT_TO_FP:
+  case ISD::SINT_TO_FP:
+    Tmp1 = PromoteLegalINT_TO_FP(Node->getOperand(0), Node->getValueType(0),
+                                 Node->getOpcode() == ISD::SINT_TO_FP, dl);
+    Results.push_back(Tmp1);
+    break;
+  }
+}
+
 // SelectionDAG::Legalize - This is the entry point for the file.
 //
 void SelectionDAG::Legalize(bool TypesNeedLegalizing,





More information about the llvm-commits mailing list