mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-11-02 07:17:36 +00:00
Port some integer multiplication fixes from LegalizeDAG.
Bail out with an error if there is no libcall available for the given size of integer. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52622 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1203,14 +1203,13 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
|
|||||||
GetExpandedInteger(N->getOperand(0), LL, LH);
|
GetExpandedInteger(N->getOperand(0), LL, LH);
|
||||||
GetExpandedInteger(N->getOperand(1), RL, RH);
|
GetExpandedInteger(N->getOperand(1), RL, RH);
|
||||||
unsigned OuterBitSize = VT.getSizeInBits();
|
unsigned OuterBitSize = VT.getSizeInBits();
|
||||||
unsigned BitSize = NVT.getSizeInBits();
|
unsigned InnerBitSize = NVT.getSizeInBits();
|
||||||
unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
|
unsigned LHSSB = DAG.ComputeNumSignBits(N->getOperand(0));
|
||||||
unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
|
unsigned RHSSB = DAG.ComputeNumSignBits(N->getOperand(1));
|
||||||
|
|
||||||
if (DAG.MaskedValueIsZero(N->getOperand(0),
|
APInt HighMask = APInt::getHighBitsSet(OuterBitSize, InnerBitSize);
|
||||||
APInt::getHighBitsSet(OuterBitSize, LHSSB)) &&
|
if (DAG.MaskedValueIsZero(N->getOperand(0), HighMask) &&
|
||||||
DAG.MaskedValueIsZero(N->getOperand(1),
|
DAG.MaskedValueIsZero(N->getOperand(1), HighMask)) {
|
||||||
APInt::getHighBitsSet(OuterBitSize, RHSSB))) {
|
|
||||||
// The inputs are both zero-extended.
|
// The inputs are both zero-extended.
|
||||||
if (HasUMUL_LOHI) {
|
if (HasUMUL_LOHI) {
|
||||||
// We can emit a umul_lohi.
|
// We can emit a umul_lohi.
|
||||||
@@ -1225,7 +1224,7 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (LHSSB > BitSize && RHSSB > BitSize) {
|
if (LHSSB > InnerBitSize && RHSSB > InnerBitSize) {
|
||||||
// The input values are both sign-extended.
|
// The input values are both sign-extended.
|
||||||
if (HasSMUL_LOHI) {
|
if (HasSMUL_LOHI) {
|
||||||
// We can emit a smul_lohi.
|
// We can emit a smul_lohi.
|
||||||
@@ -1252,12 +1251,29 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N,
|
|||||||
Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
|
Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (HasMULHU) {
|
||||||
|
Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
|
||||||
|
Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL);
|
||||||
|
RH = DAG.getNode(ISD::MUL, NVT, LL, RH);
|
||||||
|
LH = DAG.getNode(ISD::MUL, NVT, LH, RL);
|
||||||
|
Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH);
|
||||||
|
Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If nothing else, we can make a libcall.
|
// If nothing else, we can make a libcall.
|
||||||
|
RTLIB::Libcall LC;
|
||||||
|
switch (VT.getSimpleVT()) {
|
||||||
|
default:
|
||||||
|
assert(false && "Unsupported MUL!");
|
||||||
|
case MVT::i64:
|
||||||
|
LC = RTLIB::MUL_I64;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
|
SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
|
||||||
SplitInteger(MakeLibCall(RTLIB::MUL_I64, VT, Ops, 2, true/*sign irrelevant*/),
|
SplitInteger(MakeLibCall(LC, VT, Ops, 2, true/*sign irrelevant*/), Lo, Hi);
|
||||||
Lo, Hi);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
|
void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N,
|
||||||
|
|||||||
Reference in New Issue
Block a user