aboutsummaryrefslogtreecommitdiffstats
path: root/lib/CodeGen
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2008-04-14 06:48:48 +0000
committerDuncan Sands <baldrick@free.fr>2008-04-14 06:48:48 +0000
commitddc016cc8592fe5c9379feb42a1fb4fb63164a91 (patch)
treef1bed018d7e455f6921a374fb1a240095de80b7b /lib/CodeGen
parent75caee241955fdcd9942c42be8b77ba9996e94d6 (diff)
downloadexternal_llvm-ddc016cc8592fe5c9379feb42a1fb4fb63164a91.zip
external_llvm-ddc016cc8592fe5c9379feb42a1fb4fb63164a91.tar.gz
external_llvm-ddc016cc8592fe5c9379feb42a1fb4fb63164a91.tar.bz2
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
Diffstat (limited to 'lib/CodeGen')
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.cpp24
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypes.h7
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeTypesExpand.cpp85
3 files changed, 116 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp
index 34f99da..c26656a 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<SDOperand,SDOperand> 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 b5ec7d1..d2196f3 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 fcde8f3..5cb1562 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<LoadSDNode>(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) {