diff --git a/include/llvm/CodeGen/RuntimeLibcalls.h b/include/llvm/CodeGen/RuntimeLibcalls.h index 9452d9ed62a..aae95bf8b07 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 bde61ad81ad..0db87e9e6a2 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 18e1c879439..ee72012133a 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";