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
This commit is contained in:
Duncan Sands
2008-07-10 15:35:05 +00:00
parent be1ad4de29
commit 5ac319ac71
3 changed files with 67 additions and 21 deletions

View File

@@ -35,14 +35,19 @@ namespace RTLIB {
SRA_I64, SRA_I64,
MUL_I32, MUL_I32,
MUL_I64, MUL_I64,
MUL_I128,
SDIV_I32, SDIV_I32,
SDIV_I64, SDIV_I64,
SDIV_I128,
UDIV_I32, UDIV_I32,
UDIV_I64, UDIV_I64,
UDIV_I128,
SREM_I32, SREM_I32,
SREM_I64, SREM_I64,
SREM_I128,
UREM_I32, UREM_I32,
UREM_I64, UREM_I64,
UREM_I128,
NEG_I32, NEG_I32,
NEG_I64, NEG_I64,

View File

@@ -1077,8 +1077,8 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N,
MVT VT = N->getValueType(0); MVT VT = N->getValueType(0);
MVT NVT = TLI.getTypeToTransformTo(VT); MVT NVT = TLI.getTypeToTransformTo(VT);
SDOperand Ch = N->getChain(); // Legalize the chain. SDOperand Ch = N->getChain();
SDOperand Ptr = N->getBasePtr(); // Legalize the pointer. SDOperand Ptr = N->getBasePtr();
ISD::LoadExtType ExtType = N->getExtensionType(); ISD::LoadExtType ExtType = N->getExtensionType();
int SVOffset = N->getSrcValueOffset(); int SVOffset = N->getSrcValueOffset();
unsigned Alignment = N->getAlignment(); unsigned Alignment = N->getAlignment();
@@ -1330,14 +1330,14 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
} }
// If nothing else, we can make a libcall. // If nothing else, we can make a libcall.
RTLIB::Libcall LC; RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
switch (VT.getSimpleVT()) { if (VT == MVT::i32)
default: LC = RTLIB::MUL_I32;
assert(false && "Unsupported MUL!"); else if (VT == MVT::i64)
case MVT::i64:
LC = RTLIB::MUL_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) }; SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
SplitInteger(MakeLibCall(LC, VT, Ops, 2, true/*sign irrelevant*/), Lo, Hi); 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, void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
SDOperand &Lo, SDOperand &Hi) { 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) }; SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
SplitInteger(MakeLibCall(RTLIB::SDIV_I64, N->getValueType(0), Ops, 2, true), SplitInteger(MakeLibCall(LC, VT, Ops, 2, true), Lo, Hi);
Lo, Hi);
} }
void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N,
SDOperand &Lo, SDOperand &Hi) { 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) }; SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
SplitInteger(MakeLibCall(RTLIB::SREM_I64, N->getValueType(0), Ops, 2, true), SplitInteger(MakeLibCall(LC, VT, Ops, 2, true), Lo, Hi);
Lo, Hi);
} }
void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N,
SDOperand &Lo, SDOperand &Hi) { 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) }; SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
SplitInteger(MakeLibCall(RTLIB::UDIV_I64, N->getValueType(0), Ops, 2, false), SplitInteger(MakeLibCall(LC, VT, Ops, 2, false), Lo, Hi);
Lo, Hi);
} }
void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N,
SDOperand &Lo, SDOperand &Hi) { 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) }; SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
SplitInteger(MakeLibCall(RTLIB::UREM_I64, N->getValueType(0), Ops, 2, false), SplitInteger(MakeLibCall(LC, VT, Ops, 2, false), Lo, Hi);
Lo, Hi);
} }
void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N,

View File

@@ -37,14 +37,19 @@ static void InitLibcallNames(const char **Names) {
Names[RTLIB::SRA_I64] = "__ashrdi3"; Names[RTLIB::SRA_I64] = "__ashrdi3";
Names[RTLIB::MUL_I32] = "__mulsi3"; Names[RTLIB::MUL_I32] = "__mulsi3";
Names[RTLIB::MUL_I64] = "__muldi3"; Names[RTLIB::MUL_I64] = "__muldi3";
Names[RTLIB::MUL_I128] = "__multi3";
Names[RTLIB::SDIV_I32] = "__divsi3"; Names[RTLIB::SDIV_I32] = "__divsi3";
Names[RTLIB::SDIV_I64] = "__divdi3"; Names[RTLIB::SDIV_I64] = "__divdi3";
Names[RTLIB::SDIV_I128] = "__divti3";
Names[RTLIB::UDIV_I32] = "__udivsi3"; Names[RTLIB::UDIV_I32] = "__udivsi3";
Names[RTLIB::UDIV_I64] = "__udivdi3"; Names[RTLIB::UDIV_I64] = "__udivdi3";
Names[RTLIB::UDIV_I128] = "__udivti3";
Names[RTLIB::SREM_I32] = "__modsi3"; Names[RTLIB::SREM_I32] = "__modsi3";
Names[RTLIB::SREM_I64] = "__moddi3"; Names[RTLIB::SREM_I64] = "__moddi3";
Names[RTLIB::SREM_I128] = "__modti3";
Names[RTLIB::UREM_I32] = "__umodsi3"; Names[RTLIB::UREM_I32] = "__umodsi3";
Names[RTLIB::UREM_I64] = "__umoddi3"; Names[RTLIB::UREM_I64] = "__umoddi3";
Names[RTLIB::UREM_I128] = "__umodti3";
Names[RTLIB::NEG_I32] = "__negsi2"; Names[RTLIB::NEG_I32] = "__negsi2";
Names[RTLIB::NEG_I64] = "__negdi2"; Names[RTLIB::NEG_I64] = "__negdi2";
Names[RTLIB::ADD_F32] = "__addsf3"; Names[RTLIB::ADD_F32] = "__addsf3";