diff options
author | Duncan Sands <baldrick@free.fr> | 2008-07-10 15:35:05 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2008-07-10 15:35:05 +0000 |
commit | 5ac319ac7125b009adddcc49294d2e040c4a91e5 (patch) | |
tree | 7af9693511fe3b278f6b59126a18719791ec7461 | |
parent | be1ad4de2900451626c8d4ace07b9ea16099ea1d (diff) | |
download | external_llvm-5ac319ac7125b009adddcc49294d2e040c4a91e5.zip external_llvm-5ac319ac7125b009adddcc49294d2e040c4a91e5.tar.gz external_llvm-5ac319ac7125b009adddcc49294d2e040c4a91e5.tar.bz2 |
Add support for 128 bit multiplicative operations.
Lack of these caused a bootstrap failure with Fortran
on x86-64 with LegalizeTypes turned on. While there,
be nice to 16 bit machines and support expansion of
i32 too.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@53408 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/llvm/CodeGen/RuntimeLibcalls.h | 5 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 78 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/TargetLowering.cpp | 5 |
3 files changed, 67 insertions, 21 deletions
diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h index 9452d9e..aae95bf 100644 --- a/include/llvm/CodeGen/RuntimeLibcalls.h +++ b/include/llvm/CodeGen/RuntimeLibcalls.h @@ -35,14 +35,19 @@ namespace RTLIB { SRA_I64, MUL_I32, MUL_I64, + MUL_I128, SDIV_I32, SDIV_I64, + SDIV_I128, UDIV_I32, UDIV_I64, + UDIV_I128, SREM_I32, SREM_I64, + SREM_I128, UREM_I32, UREM_I64, + UREM_I128, NEG_I32, NEG_I64, diff --git a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index bde61ad..0db87e9 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -1077,8 +1077,8 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, MVT VT = N->getValueType(0); MVT NVT = TLI.getTypeToTransformTo(VT); - SDOperand Ch = N->getChain(); // Legalize the chain. - SDOperand Ptr = N->getBasePtr(); // Legalize the pointer. + SDOperand Ch = N->getChain(); + SDOperand Ptr = N->getBasePtr(); ISD::LoadExtType ExtType = N->getExtensionType(); int SVOffset = N->getSrcValueOffset(); unsigned Alignment = N->getAlignment(); @@ -1330,14 +1330,14 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N, } // If nothing else, we can make a libcall. - RTLIB::Libcall LC; - switch (VT.getSimpleVT()) { - default: - assert(false && "Unsupported MUL!"); - case MVT::i64: + RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; + if (VT == MVT::i32) + LC = RTLIB::MUL_I32; + else if (VT == MVT::i64) LC = RTLIB::MUL_I64; - break; - } + else if (VT == MVT::i128) + LC = RTLIB::MUL_I128; + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported MUL!"); SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) }; SplitInteger(MakeLibCall(LC, VT, Ops, 2, true/*sign irrelevant*/), Lo, Hi); @@ -1345,34 +1345,70 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N, SDOperand &Lo, SDOperand &Hi) { - assert(N->getValueType(0) == MVT::i64 && "Unsupported sdiv!"); + MVT VT = N->getValueType(0); + + RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; + if (VT == MVT::i32) + LC = RTLIB::SDIV_I32; + else if (VT == MVT::i64) + LC = RTLIB::SDIV_I64; + else if (VT == MVT::i128) + LC = RTLIB::SDIV_I128; + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!"); + SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) }; - SplitInteger(MakeLibCall(RTLIB::SDIV_I64, N->getValueType(0), Ops, 2, true), - Lo, Hi); + SplitInteger(MakeLibCall(LC, VT, Ops, 2, true), Lo, Hi); } void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N, SDOperand &Lo, SDOperand &Hi) { - assert(N->getValueType(0) == MVT::i64 && "Unsupported srem!"); + MVT VT = N->getValueType(0); + + RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; + if (VT == MVT::i32) + LC = RTLIB::SREM_I32; + else if (VT == MVT::i64) + LC = RTLIB::SREM_I64; + else if (VT == MVT::i128) + LC = RTLIB::SREM_I128; + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!"); + SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) }; - SplitInteger(MakeLibCall(RTLIB::SREM_I64, N->getValueType(0), Ops, 2, true), - Lo, Hi); + SplitInteger(MakeLibCall(LC, VT, Ops, 2, true), Lo, Hi); } void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N, SDOperand &Lo, SDOperand &Hi) { - assert(N->getValueType(0) == MVT::i64 && "Unsupported udiv!"); + MVT VT = N->getValueType(0); + + RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; + if (VT == MVT::i32) + LC = RTLIB::UDIV_I32; + else if (VT == MVT::i64) + LC = RTLIB::UDIV_I64; + else if (VT == MVT::i128) + LC = RTLIB::UDIV_I128; + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UDIV!"); + SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) }; - SplitInteger(MakeLibCall(RTLIB::UDIV_I64, N->getValueType(0), Ops, 2, false), - Lo, Hi); + SplitInteger(MakeLibCall(LC, VT, Ops, 2, false), Lo, Hi); } void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N, SDOperand &Lo, SDOperand &Hi) { - assert(N->getValueType(0) == MVT::i64 && "Unsupported urem!"); + MVT VT = N->getValueType(0); + + RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; + if (VT == MVT::i32) + LC = RTLIB::UREM_I32; + else if (VT == MVT::i64) + LC = RTLIB::UREM_I64; + else if (VT == MVT::i128) + LC = RTLIB::UREM_I128; + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UREM!"); + SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) }; - SplitInteger(MakeLibCall(RTLIB::UREM_I64, N->getValueType(0), Ops, 2, false), - Lo, Hi); + SplitInteger(MakeLibCall(LC, VT, Ops, 2, false), Lo, Hi); } void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N, diff --git a/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 18e1c87..ee720121 100644 --- a/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -37,14 +37,19 @@ static void InitLibcallNames(const char **Names) { Names[RTLIB::SRA_I64] = "__ashrdi3"; Names[RTLIB::MUL_I32] = "__mulsi3"; Names[RTLIB::MUL_I64] = "__muldi3"; + Names[RTLIB::MUL_I128] = "__multi3"; Names[RTLIB::SDIV_I32] = "__divsi3"; Names[RTLIB::SDIV_I64] = "__divdi3"; + Names[RTLIB::SDIV_I128] = "__divti3"; Names[RTLIB::UDIV_I32] = "__udivsi3"; Names[RTLIB::UDIV_I64] = "__udivdi3"; + Names[RTLIB::UDIV_I128] = "__udivti3"; Names[RTLIB::SREM_I32] = "__modsi3"; Names[RTLIB::SREM_I64] = "__moddi3"; + Names[RTLIB::SREM_I128] = "__modti3"; Names[RTLIB::UREM_I32] = "__umodsi3"; Names[RTLIB::UREM_I64] = "__umoddi3"; + Names[RTLIB::UREM_I128] = "__umodti3"; Names[RTLIB::NEG_I32] = "__negsi2"; Names[RTLIB::NEG_I64] = "__negdi2"; Names[RTLIB::ADD_F32] = "__addsf3"; |