From ddc016cc8592fe5c9379feb42a1fb4fb63164a91 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Mon, 14 Apr 2008 06:48:48 +0000 Subject: [PATCH] Initial libcall support for LegalizeTypes. This is much simpler than in LegalizeDAG because calls are not yet expanded into call sequences: that happens after type legalization has finished. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49634 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/SelectionDAG/LegalizeTypes.cpp | 24 ++++++ lib/CodeGen/SelectionDAG/LegalizeTypes.h | 7 ++ .../SelectionDAG/LegalizeTypesExpand.cpp | 85 +++++++++++++++++++ 3 files changed, 116 insertions(+) diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 34f99da49fa..c26656a8676 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "LegalizeTypes.h" +#include "llvm/CallingConv.h" #include "llvm/Constants.h" #include "llvm/DerivedTypes.h" #include "llvm/Support/CommandLine.h" @@ -524,6 +525,29 @@ void DAGTypeLegalizer::SplitInteger(SDOperand Op, SplitInteger(Op, HalfVT, HalfVT, Lo, Hi); } +/// MakeLibCall - Expand a node into a libcall and return the result. +SDOperand DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, SDNode *N, + bool isSigned) { + TargetLowering::ArgListTy Args; + TargetLowering::ArgListEntry Entry; + for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) { + MVT::ValueType ArgVT = N->getOperand(i).getValueType(); + Entry.Node = N->getOperand(i); + Entry.Ty = MVT::getTypeForValueType(ArgVT); + Entry.isSExt = isSigned; + Entry.isZExt = !isSigned; + Args.push_back(Entry); + } + SDOperand Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), + TLI.getPointerTy()); + + const Type *RetTy = MVT::getTypeForValueType(N->getValueType(0)); + std::pair CallInfo = + TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, + CallingConv::C, false, Callee, Args, DAG); + return CallInfo.first; +} + //===----------------------------------------------------------------------===// // Entry Point //===----------------------------------------------------------------------===// diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/lib/CodeGen/SelectionDAG/LegalizeTypes.h index b5ec7d1ca8e..d2196f3dd51 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -169,6 +169,7 @@ private: void SplitInteger(SDOperand Op, SDOperand &Lo, SDOperand &Hi); void SplitInteger(SDOperand Op, MVT::ValueType LoVT, MVT::ValueType HiVT, SDOperand &Lo, SDOperand &Hi); + SDOperand MakeLibCall(RTLIB::Libcall LC, SDNode *N, bool isSigned); //===--------------------------------------------------------------------===// // Promotion Support: LegalizeTypesPromote.cpp @@ -262,6 +263,8 @@ private: 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); @@ -271,6 +274,10 @@ private: 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, diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp index fcde8f32d25..5cb15620a0b 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp @@ -64,6 +64,8 @@ void DAGTypeLegalizer::ExpandResult(SDNode *N, unsigned ResNo) { 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(N), Lo, Hi); break; case ISD::AND: @@ -79,6 +81,10 @@ void DAGTypeLegalizer::ExpandResult(SDNode *N, unsigned ResNo) { 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; @@ -315,6 +321,62 @@ ExpandResult_SIGN_EXTEND_INREG(SDNode *N, SDOperand &Lo, SDOperand &Hi) { } } +void DAGTypeLegalizer::ExpandResult_FP_TO_SINT(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { + MVT::ValueType VT = N->getValueType(0); + RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; + if (VT == MVT::i64) { + if (N->getOperand(0).getValueType() == MVT::f32) + LC = RTLIB::FPTOSINT_F32_I64; + else if (N->getOperand(0).getValueType() == MVT::f64) + LC = RTLIB::FPTOSINT_F64_I64; + else if (N->getOperand(0).getValueType() == MVT::f80) + LC = RTLIB::FPTOSINT_F80_I64; + else if (N->getOperand(0).getValueType() == MVT::ppcf128) + LC = RTLIB::FPTOSINT_PPCF128_I64; + } else if (VT == MVT::i128) { + if (N->getOperand(0).getValueType() == MVT::f32) + LC = RTLIB::FPTOSINT_F32_I128; + else if (N->getOperand(0).getValueType() == MVT::f64) + LC = RTLIB::FPTOSINT_F64_I128; + else if (N->getOperand(0).getValueType() == MVT::f80) + LC = RTLIB::FPTOSINT_F80_I128; + else if (N->getOperand(0).getValueType() == MVT::ppcf128) + LC = RTLIB::FPTOSINT_PPCF128_I128; + } else { + assert(0 && "Unexpected fp-to-sint conversion!"); + } + SplitInteger(MakeLibCall(LC, N, true/*sign irrelevant*/), Lo, Hi); +} + +void DAGTypeLegalizer::ExpandResult_FP_TO_UINT(SDNode *N, SDOperand &Lo, + SDOperand &Hi) { + MVT::ValueType VT = N->getValueType(0); + RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; + if (VT == MVT::i64) { + if (N->getOperand(0).getValueType() == MVT::f32) + LC = RTLIB::FPTOUINT_F32_I64; + else if (N->getOperand(0).getValueType() == MVT::f64) + LC = RTLIB::FPTOUINT_F64_I64; + else if (N->getOperand(0).getValueType() == MVT::f80) + LC = RTLIB::FPTOUINT_F80_I64; + else if (N->getOperand(0).getValueType() == MVT::ppcf128) + LC = RTLIB::FPTOUINT_PPCF128_I64; + } else if (VT == MVT::i128) { + if (N->getOperand(0).getValueType() == MVT::f32) + LC = RTLIB::FPTOUINT_F32_I128; + else if (N->getOperand(0).getValueType() == MVT::f64) + LC = RTLIB::FPTOUINT_F64_I128; + else if (N->getOperand(0).getValueType() == MVT::f80) + LC = RTLIB::FPTOUINT_F80_I128; + else if (N->getOperand(0).getValueType() == MVT::ppcf128) + LC = RTLIB::FPTOUINT_PPCF128_I128; + } else { + assert(0 && "Unexpected fp-to-uint conversion!"); + } + SplitInteger(MakeLibCall(LC, N, false/*sign irrelevant*/), Lo, Hi); +} + void DAGTypeLegalizer::ExpandResult_LOAD(LoadSDNode *N, SDOperand &Lo, SDOperand &Hi) { MVT::ValueType VT = N->getValueType(0); @@ -614,6 +676,29 @@ void DAGTypeLegalizer::ExpandResult_MUL(SDNode *N, #endif } +void DAGTypeLegalizer::ExpandResult_SDIV(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + assert(N->getValueType(0) == MVT::i64 && "Unsupported sdiv!"); + SplitInteger(MakeLibCall(RTLIB::SDIV_I64, N, true), Lo, Hi); +} + +void DAGTypeLegalizer::ExpandResult_SREM(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + assert(N->getValueType(0) == MVT::i64 && "Unsupported srem!"); + SplitInteger(MakeLibCall(RTLIB::SREM_I64, N, true), Lo, Hi); +} + +void DAGTypeLegalizer::ExpandResult_UDIV(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + assert(N->getValueType(0) == MVT::i64 && "Unsupported udiv!"); + SplitInteger(MakeLibCall(RTLIB::UDIV_I64, N, false), Lo, Hi); +} + +void DAGTypeLegalizer::ExpandResult_UREM(SDNode *N, + SDOperand &Lo, SDOperand &Hi) { + assert(N->getValueType(0) == MVT::i64 && "Unsupported urem!"); + SplitInteger(MakeLibCall(RTLIB::UREM_I64, N, false), Lo, Hi); +} void DAGTypeLegalizer::ExpandResult_Shift(SDNode *N, SDOperand &Lo, SDOperand &Hi) {