aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDuncan Sands <baldrick@free.fr>2008-07-10 15:35:05 +0000
committerDuncan Sands <baldrick@free.fr>2008-07-10 15:35:05 +0000
commit5ac319ac7125b009adddcc49294d2e040c4a91e5 (patch)
tree7af9693511fe3b278f6b59126a18719791ec7461
parentbe1ad4de2900451626c8d4ace07b9ea16099ea1d (diff)
downloadexternal_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.h5
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp78
-rw-r--r--lib/CodeGen/SelectionDAG/TargetLowering.cpp5
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";