// The count is the same in the promoted type except if the original
// value was zero. This can be handled by setting the bit just off
// the top of the original type.
- Op = DAG.getNode(ISD::OR, NVT, Op,
- // FIXME: Do this using an APINT constant.
- DAG.getConstant(1UL << OVT.getSizeInBits(), NVT));
+ APInt TopBit(NVT.getSizeInBits(), 0);
+ TopBit.set(OVT.getSizeInBits());
+ Op = DAG.getNode(ISD::OR, NVT, Op, DAG.getConstant(TopBit, NVT));
return DAG.getNode(ISD::CTTZ, NVT, Op);
}
return Tmp;
}
+
//===----------------------------------------------------------------------===//
// Integer Operand Promotion
//===----------------------------------------------------------------------===//
MVT VT = N->getValueType(0);
SDOperand Op = N->getOperand(0);
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
- if (VT == MVT::i64) {
+
+ if (VT == MVT::i32) {
+ if (Op.getValueType() == MVT::f32)
+ LC = RTLIB::FPTOSINT_F32_I32;
+ else if (Op.getValueType() == MVT::f64)
+ LC = RTLIB::FPTOSINT_F64_I32;
+ else if (Op.getValueType() == MVT::f80)
+ LC = RTLIB::FPTOSINT_F80_I32;
+ else if (Op.getValueType() == MVT::ppcf128)
+ LC = RTLIB::FPTOSINT_PPCF128_I32;
+ } else if (VT == MVT::i64) {
if (Op.getValueType() == MVT::f32)
LC = RTLIB::FPTOSINT_F32_I64;
else if (Op.getValueType() == MVT::f64)
LC = RTLIB::FPTOSINT_F80_I128;
else if (Op.getValueType() == MVT::ppcf128)
LC = RTLIB::FPTOSINT_PPCF128_I128;
- } else {
- assert(0 && "Unexpected fp-to-sint conversion!");
}
+ assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-sint conversion!");
SplitInteger(MakeLibCall(LC, VT, &Op, 1, true/*sign irrelevant*/), Lo, Hi);
}
MVT VT = N->getValueType(0);
SDOperand Op = N->getOperand(0);
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
- if (VT == MVT::i64) {
+ if (VT == MVT::i32) {
+ if (Op.getValueType() == MVT::f32)
+ LC = RTLIB::FPTOUINT_F32_I32;
+ else if (Op.getValueType() == MVT::f64)
+ LC = RTLIB::FPTOUINT_F64_I32;
+ else if (Op.getValueType() == MVT::f80)
+ LC = RTLIB::FPTOUINT_F80_I32;
+ else if (Op.getValueType() == MVT::ppcf128)
+ LC = RTLIB::FPTOUINT_PPCF128_I32;
+ } else if (VT == MVT::i64) {
if (Op.getValueType() == MVT::f32)
LC = RTLIB::FPTOUINT_F32_I64;
else if (Op.getValueType() == MVT::f64)
LC = RTLIB::FPTOUINT_F80_I128;
else if (Op.getValueType() == MVT::ppcf128)
LC = RTLIB::FPTOUINT_PPCF128_I128;
- } else {
- assert(0 && "Unexpected fp-to-uint conversion!");
}
+ assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-uint conversion!");
SplitInteger(MakeLibCall(LC, VT, &Op, 1, false/*sign irrelevant*/), Lo, Hi);
}
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();
}
// 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);
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,
}
// Otherwise, emit a libcall.
- assert(VT == MVT::i64 && "Unsupported shift!");
-
- RTLIB::Libcall LC;
+ RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
bool isSigned;
if (N->getOpcode() == ISD::SHL) {
- LC = RTLIB::SHL_I64;
isSigned = false; /*sign irrelevant*/
+ if (VT == MVT::i32)
+ LC = RTLIB::SHL_I32;
+ else if (VT == MVT::i64)
+ LC = RTLIB::SHL_I64;
+ else if (VT == MVT::i128)
+ LC = RTLIB::SHL_I128;
} else if (N->getOpcode() == ISD::SRL) {
- LC = RTLIB::SRL_I64;
isSigned = false;
+ if (VT == MVT::i32)
+ LC = RTLIB::SRL_I32;
+ else if (VT == MVT::i64)
+ LC = RTLIB::SRL_I64;
+ else if (VT == MVT::i128)
+ LC = RTLIB::SRL_I128;
} else {
assert(N->getOpcode() == ISD::SRA && "Unknown shift!");
- LC = RTLIB::SRA_I64;
isSigned = true;
+ if (VT == MVT::i32)
+ LC = RTLIB::SRA_I32;
+ else if (VT == MVT::i64)
+ LC = RTLIB::SRA_I64;
+ else if (VT == MVT::i128)
+ LC = RTLIB::SRA_I128;
}
+ assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported shift!");
SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) };
SplitInteger(MakeLibCall(LC, VT, Ops, 2, isSigned), Lo, Hi);
} else if (Amt == NVTBits) {
Lo = DAG.getConstant(0, NVT);
Hi = InL;
+ } else if (Amt == 1) {
+ // Emit this X << 1 as X+X.
+ SDVTList VTList = DAG.getVTList(NVT, MVT::Flag);
+ SDOperand LoOps[2] = { InL, InL };
+ Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2);
+ SDOperand HiOps[3] = { InH, InH, Lo.getValue(1) };
+ Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3);
} else {
Lo = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt, ShTy));
Hi = DAG.getNode(ISD::OR, NVT,