1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-02-01 13:11:39 +01:00

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.

llvm-svn: 53408
This commit is contained in:
Duncan Sands 2008-07-10 15:35:05 +00:00
parent 90a916539d
commit a6c09579f0
3 changed files with 67 additions and 21 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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";