diff options
author | Chris Lattner <sabre@nondot.org> | 2005-01-08 19:27:05 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-01-08 19:27:05 +0000 |
commit | 4e6c74689944be1de80c99dc0688ec0bcbd743aa (patch) | |
tree | 6f2358b16e7b8f5fbf3f1003b13425c61cb03bf0 | |
parent | cf5734dddd66af9388a171b44996505ede47feed (diff) | |
download | external_llvm-4e6c74689944be1de80c99dc0688ec0bcbd743aa.zip external_llvm-4e6c74689944be1de80c99dc0688ec0bcbd743aa.tar.gz external_llvm-4e6c74689944be1de80c99dc0688ec0bcbd743aa.tar.bz2 |
Implement handling of most long operators through libcalls.
Fix a bug legalizing "ret (Val,Val)"
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19375 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 70 |
1 files changed, 65 insertions, 5 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index e42d7f2..964c511 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -19,6 +19,20 @@ #include <iostream> using namespace llvm; +static const Type *getTypeFor(MVT::ValueType VT) { + switch (VT) { + default: assert(0 && "Unknown MVT!"); + case MVT::i1: return Type::BoolTy; + case MVT::i8: return Type::UByteTy; + case MVT::i16: return Type::UShortTy; + case MVT::i32: return Type::UIntTy; + case MVT::i64: return Type::ULongTy; + case MVT::f32: return Type::FloatTy; + case MVT::f64: return Type::DoubleTy; + } +} + + //===----------------------------------------------------------------------===// /// SelectionDAGLegalize - This takes an arbitrary SelectionDAG as input and /// hacks on it until the target machine can handle it. This involves @@ -403,7 +417,7 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) { for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i) switch (getTypeAction(Node->getOperand(i).getValueType())) { case Legal: - NewValues.push_back(LegalizeOp(Node->getOperand(1))); + NewValues.push_back(LegalizeOp(Node->getOperand(i))); break; case Expand: { SDOperand Lo, Hi; @@ -638,10 +652,11 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ } } - // If we are lowering to a type that the target doesn't support, we will have - // to iterate lowering. - if (!isTypeLegal(NVT)) - NeedsAnotherIteration = true; + // Expanding to multiple registers needs to perform an optimization step, and + // is not careful to avoid operations the target does not support. Make sure + // that all generated operations are legalized in the next iteration. + NeedsAnotherIteration = true; + const char *LibCallName = 0; LegalizeAction Action; switch (Node->getOpcode()) { @@ -750,6 +765,51 @@ void SelectionDAGLegalize::ExpandOp(SDOperand Op, SDOperand &Lo, SDOperand &Hi){ // The high part is just a zero. Hi = DAG.getConstant(0, NVT); break; + + // These operators cannot be expanded directly, emit them as calls to + // library functions. + case ISD::FP_TO_SINT: + if (Node->getOperand(0).getValueType() == MVT::f32) + LibCallName = "__fixsfdi"; + else + LibCallName = "__fixdfdi"; + break; + case ISD::FP_TO_UINT: + if (Node->getOperand(0).getValueType() == MVT::f32) + LibCallName = "__fixunssfdi"; + else + LibCallName = "__fixunsdfdi"; + break; + + case ISD::ADD: LibCallName = "__adddi3"; break; + case ISD::SUB: LibCallName = "__subdi3"; break; + case ISD::MUL: LibCallName = "__muldi3"; break; + case ISD::SDIV: LibCallName = "__divdi3"; break; + case ISD::UDIV: LibCallName = "__udivdi3"; break; + case ISD::SREM: LibCallName = "__moddi3"; break; + case ISD::UREM: LibCallName = "__umoddi3"; break; + case ISD::SHL: LibCallName = "__lshrdi3"; break; + case ISD::SRA: LibCallName = "__ashrdi3"; break; + case ISD::SRL: LibCallName = "__ashldi3"; break; + } + + // Int2FP -> __floatdisf/__floatdidf + + // If this is to be expanded into a libcall... do so now. + if (LibCallName) { + TargetLowering::ArgListTy Args; + for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) + Args.push_back(std::make_pair(Node->getOperand(i), + getTypeFor(Node->getOperand(i).getValueType()))); + SDOperand Callee = DAG.getExternalSymbol(LibCallName, TLI.getPointerTy()); + + // We don't care about token chains for libcalls. We just use the entry + // node as our input and ignore the output chain. This allows us to place + // calls wherever we need them to satisfy data dependences. + SDOperand Result = TLI.LowerCallTo(DAG.getEntryNode(), + getTypeFor(Op.getValueType()), Callee, + Args, DAG).first; + ExpandOp(Result, Lo, Hi); } // Remember in a map if the values will be reused later. |