if (MVT::isInteger(VT))
Result = DAG.getConstant(0, VT);
else if (MVT::isFloatingPoint(VT))
- Result = DAG.getConstantFP(0, VT);
+ Result = DAG.getConstantFP(APFloat(APInt(MVT::getSizeInBits(VT), 0)),
+ VT);
else
assert(0 && "Unknown value type!");
break;
if (Tmp1.Val) Result = Tmp1;
break;
case TargetLowering::Expand: {
+ MVT::ValueType VT = Op.getValueType();
+
+ // See if multiply or divide can be lowered using two-result operations.
+ SDVTList VTs = DAG.getVTList(VT, VT);
+ if (Node->getOpcode() == ISD::MUL) {
+ // We just need the low half of the multiply; try both the signed
+ // and unsigned forms. If the target supports both SMUL_LOHI and
+ // UMUL_LOHI, form a preference by checking which forms of plain
+ // MULH it supports.
+ bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, VT);
+ bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, VT);
+ bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, VT);
+ bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, VT);
+ unsigned OpToUse = 0;
+ if (HasSMUL_LOHI && !HasMULHS) {
+ OpToUse = ISD::SMUL_LOHI;
+ } else if (HasUMUL_LOHI && !HasMULHU) {
+ OpToUse = ISD::UMUL_LOHI;
+ } else if (HasSMUL_LOHI) {
+ OpToUse = ISD::SMUL_LOHI;
+ } else if (HasUMUL_LOHI) {
+ OpToUse = ISD::UMUL_LOHI;
+ }
+ if (OpToUse) {
+ Result = SDOperand(DAG.getNode(OpToUse, VTs, Tmp1, Tmp2).Val, 0);
+ break;
+ }
+ }
+ if (Node->getOpcode() == ISD::MULHS &&
+ TLI.isOperationLegal(ISD::SMUL_LOHI, VT)) {
+ Result = SDOperand(DAG.getNode(ISD::SMUL_LOHI, VTs, Tmp1, Tmp2).Val, 1);
+ break;
+ }
+ if (Node->getOpcode() == ISD::MULHU &&
+ TLI.isOperationLegal(ISD::UMUL_LOHI, VT)) {
+ Result = SDOperand(DAG.getNode(ISD::UMUL_LOHI, VTs, Tmp1, Tmp2).Val, 1);
+ break;
+ }
+ if (Node->getOpcode() == ISD::SDIV &&
+ TLI.isOperationLegal(ISD::SDIVREM, VT)) {
+ Result = SDOperand(DAG.getNode(ISD::SDIVREM, VTs, Tmp1, Tmp2).Val, 0);
+ break;
+ }
+ if (Node->getOpcode() == ISD::UDIV &&
+ TLI.isOperationLegal(ISD::UDIVREM, VT)) {
+ Result = SDOperand(DAG.getNode(ISD::UDIVREM, VTs, Tmp1, Tmp2).Val, 0);
+ break;
+ }
+
if (Node->getValueType(0) == MVT::i32) {
switch (Node->getOpcode()) {
default: assert(0 && "Do not know how to expand this integer BinOp!");
}
break;
+ case ISD::SMUL_LOHI:
+ case ISD::UMUL_LOHI:
+ case ISD::SDIVREM:
+ case ISD::UDIVREM:
+ // These nodes will only be produced by target-specific lowering, so
+ // they shouldn't be here if they aren't legal.
+ assert(TLI.isOperationLegal(Node->getValueType(0), Node->getValueType(0)) &&
+ "This must be legal!");
+
+ Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
+ Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS
+ Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2);
+ break;
+
case ISD::FCOPYSIGN: // FCOPYSIGN does not require LHS/RHS to match type!
Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS
switch (getTypeAction(Node->getOperand(1).getValueType())) {
if (Tmp1.Val) Result = Tmp1;
}
break;
- case TargetLowering::Expand:
+ case TargetLowering::Expand: {
unsigned DivOpc= (Node->getOpcode() == ISD::UREM) ? ISD::UDIV : ISD::SDIV;
bool isSigned = DivOpc == ISD::SDIV;
- if (MVT::isInteger(Node->getValueType(0))) {
- if (TLI.getOperationAction(DivOpc, Node->getValueType(0)) ==
+ MVT::ValueType VT = Node->getValueType(0);
+
+ // See if remainder can be lowered using two-result operations.
+ SDVTList VTs = DAG.getVTList(VT, VT);
+ if (Node->getOpcode() == ISD::SREM &&
+ TLI.isOperationLegal(ISD::SDIVREM, VT)) {
+ Result = SDOperand(DAG.getNode(ISD::SDIVREM, VTs, Tmp1, Tmp2).Val, 1);
+ break;
+ }
+ if (Node->getOpcode() == ISD::UREM &&
+ TLI.isOperationLegal(ISD::UDIVREM, VT)) {
+ Result = SDOperand(DAG.getNode(ISD::UDIVREM, VTs, Tmp1, Tmp2).Val, 1);
+ break;
+ }
+
+ if (MVT::isInteger(VT)) {
+ if (TLI.getOperationAction(DivOpc, VT) ==
TargetLowering::Legal) {
// X % Y -> X-X/Y*Y
- MVT::ValueType VT = Node->getValueType(0);
Result = DAG.getNode(DivOpc, VT, Tmp1, Tmp2);
Result = DAG.getNode(ISD::MUL, VT, Result, Tmp2);
Result = DAG.getNode(ISD::SUB, VT, Tmp1, Result);
} else {
- assert(Node->getValueType(0) == MVT::i32 &&
+ assert(VT == MVT::i32 &&
"Cannot expand this binary operator!");
RTLIB::Libcall LC = Node->getOpcode() == ISD::UREM
? RTLIB::UREM_I32 : RTLIB::SREM_I32;
}
} else {
// Floating point mod -> fmod libcall.
- RTLIB::Libcall LC = Node->getValueType(0) == MVT::f32
+ RTLIB::Libcall LC = VT == MVT::f32
? RTLIB::REM_F32 : RTLIB::REM_F64;
SDOperand Dummy;
Result = ExpandLibCall(TLI.getLibcallName(LC), Node,
}
break;
}
+ }
break;
case ISD::VAARG: {
Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain.
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
switch(Node->getOpcode()) {
case ISD::FSQRT:
- LC = VT == MVT::f32 ? RTLIB::SQRT_F32 : RTLIB::SQRT_F64;
+ LC = VT == MVT::f32 ? RTLIB::SQRT_F32 :
+ VT == MVT::f64 ? RTLIB::SQRT_F64 :
+ VT == MVT::f80 ? RTLIB::SQRT_F80 :
+ VT == MVT::ppcf128 ? RTLIB::SQRT_PPCF128 :
+ RTLIB::UNKNOWN_LIBCALL;
break;
case ISD::FSIN:
LC = VT == MVT::f32 ? RTLIB::SIN_F32 : RTLIB::SIN_F64;
break;
case ISD::FPOWI: {
// We always lower FPOWI into a libcall. No target support it yet.
- RTLIB::Libcall LC = Node->getValueType(0) == MVT::f32
- ? RTLIB::POWI_F32 : RTLIB::POWI_F64;
+ RTLIB::Libcall LC =
+ Node->getValueType(0) == MVT::f32 ? RTLIB::POWI_F32 :
+ Node->getValueType(0) == MVT::f64 ? RTLIB::POWI_F64 :
+ Node->getValueType(0) == MVT::f80 ? RTLIB::POWI_F80 :
+ Node->getValueType(0) == MVT::ppcf128 ? RTLIB::POWI_PPCF128 :
+ RTLIB::UNKNOWN_LIBCALL;
SDOperand Dummy;
Result = ExpandLibCall(TLI.getLibcallName(LC), Node,
false/*sign irrelevant*/, Dummy);
const uint64_t zero[] = {0, 0};
APFloat apf = APFloat(APInt(MVT::getSizeInBits(VT), 2, zero));
uint64_t x = 1ULL << ShiftAmt;
- (void)apf.convertFromInteger(&x, MVT::getSizeInBits(NVT), false,
- APFloat::rmTowardZero);
+ (void)apf.convertFromZeroExtendedInteger
+ (&x, MVT::getSizeInBits(NVT), false, APFloat::rmNearestTiesToEven);
Tmp2 = DAG.getConstantFP(apf, VT);
Tmp3 = DAG.getSetCC(TLI.getSetCCResultTy(),
Node->getOperand(0), Tmp2, ISD::SETLT);
else if (OVT == MVT::f64)
LC = (VT == MVT::i32)
? RTLIB::FPTOSINT_F64_I32 : RTLIB::FPTOSINT_F64_I64;
- else if (OVT == MVT::f80 || OVT == MVT::f128 || OVT == MVT::ppcf128) {
+ else if (OVT == MVT::f80) {
+ assert(VT == MVT::i64);
+ LC = RTLIB::FPTOSINT_F80_I64;
+ }
+ else if (OVT == MVT::ppcf128) {
assert(VT == MVT::i64);
- LC = RTLIB::FPTOSINT_LD_I64;
+ LC = RTLIB::FPTOSINT_PPCF128_I64;
}
break;
}
else if (OVT == MVT::f64)
LC = (VT == MVT::i32)
? RTLIB::FPTOUINT_F64_I32 : RTLIB::FPTOSINT_F64_I64;
- else if (OVT == MVT::f80 || OVT == MVT::f128 || OVT == MVT::ppcf128) {
+ else if (OVT == MVT::f80) {
LC = (VT == MVT::i32)
- ? RTLIB::FPTOUINT_LD_I32 : RTLIB::FPTOUINT_LD_I64;
+ ? RTLIB::FPTOUINT_F80_I32 : RTLIB::FPTOUINT_F80_I64;
+ }
+ else if (OVT == MVT::ppcf128) {
+ assert(VT == MVT::i64);
+ LC = RTLIB::FPTOUINT_PPCF128_I64;
}
break;
}
MVT::ValueType newVT = Op.getValueType();
MVT::ValueType oldVT = Op.getOperand(0).getValueType();
if (TLI.getConvertAction(oldVT, newVT) == TargetLowering::Expand) {
- // The only way we can lower this is to turn it into a STORE,
- // LOAD pair, targetting a temporary location (a stack slot).
-
- // NOTE: there is a choice here between constantly creating new stack
- // slots and always reusing the same one. We currently always create
- // new ones, as reuse may inhibit scheduling.
- MVT::ValueType slotVT =
- (Node->getOpcode() == ISD::FP_EXTEND) ? oldVT : newVT;
- const Type *Ty = MVT::getTypeForValueType(slotVT);
- uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);
- unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(Ty);
- MachineFunction &MF = DAG.getMachineFunction();
- int SSFI =
- MF.getFrameInfo()->CreateStackObject(TySize, Align);
- SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
- if (Node->getOpcode() == ISD::FP_EXTEND) {
- Result = DAG.getStore(DAG.getEntryNode(), Node->getOperand(0),
- StackSlot, NULL, 0);
- Result = DAG.getExtLoad(ISD::EXTLOAD, newVT,
- Result, StackSlot, NULL, 0, oldVT);
+ if (Node->getOpcode() == ISD::FP_ROUND && oldVT == MVT::ppcf128) {
+ SDOperand Lo, Hi;
+ ExpandOp(Node->getOperand(0), Lo, Hi);
+ if (newVT == MVT::f64)
+ Result = Hi;
+ else
+ Result = DAG.getNode(ISD::FP_ROUND, newVT, Hi);
+ break;
} else {
- Result = DAG.getTruncStore(DAG.getEntryNode(), Node->getOperand(0),
- StackSlot, NULL, 0, newVT);
- Result = DAG.getLoad(newVT, Result, StackSlot, NULL, 0, newVT);
+ // The only other way we can lower this is to turn it into a STORE,
+ // LOAD pair, targetting a temporary location (a stack slot).
+
+ // NOTE: there is a choice here between constantly creating new stack
+ // slots and always reusing the same one. We currently always create
+ // new ones, as reuse may inhibit scheduling.
+ MVT::ValueType slotVT =
+ (Node->getOpcode() == ISD::FP_EXTEND) ? oldVT : newVT;
+ const Type *Ty = MVT::getTypeForValueType(slotVT);
+ uint64_t TySize = TLI.getTargetData()->getTypeSize(Ty);
+ unsigned Align = TLI.getTargetData()->getPrefTypeAlignment(Ty);
+ MachineFunction &MF = DAG.getMachineFunction();
+ int SSFI =
+ MF.getFrameInfo()->CreateStackObject(TySize, Align);
+ SDOperand StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
+ if (Node->getOpcode() == ISD::FP_EXTEND) {
+ Result = DAG.getStore(DAG.getEntryNode(), Node->getOperand(0),
+ StackSlot, NULL, 0);
+ Result = DAG.getExtLoad(ISD::EXTLOAD, newVT,
+ Result, StackSlot, NULL, 0, oldVT);
+ } else {
+ Result = DAG.getTruncStore(DAG.getEntryNode(), Node->getOperand(0),
+ StackSlot, NULL, 0, newVT);
+ Result = DAG.getLoad(newVT, Result, StackSlot, NULL, 0, newVT);
+ }
+ break;
}
- break;
}
}
// FALL THROUGH
SDOperand Vec = Op.getOperand(0);
SDOperand Idx = Op.getOperand(1);
- SDNode *InVal = Vec.Val;
- MVT::ValueType TVT = InVal->getValueType(0);
+ MVT::ValueType TVT = Vec.getValueType();
unsigned NumElems = MVT::getVectorNumElements(TVT);
switch (TLI.getOperationAction(ISD::EXTRACT_VECTOR_ELT, TVT)) {
void SelectionDAGLegalize::LegalizeSetCCOperands(SDOperand &LHS,
SDOperand &RHS,
SDOperand &CC) {
- SDOperand Tmp1, Tmp2, Result;
+ SDOperand Tmp1, Tmp2, Tmp3, Result;
switch (getTypeAction(LHS.getValueType())) {
case Legal:
SDOperand LHSLo, LHSHi, RHSLo, RHSHi;
ExpandOp(LHS, LHSLo, LHSHi);
- ExpandOp(RHS, RHSLo, RHSHi);
- switch (cast<CondCodeSDNode>(CC)->get()) {
+ ExpandOp(RHS, RHSLo, RHSHi);
+ ISD::CondCode CCCode = cast<CondCodeSDNode>(CC)->get();
+
+ if (VT==MVT::ppcf128) {
+ // FIXME: This generated code sucks. We want to generate
+ // FCMP crN, hi1, hi2
+ // BNE crN, L:
+ // FCMP crN, lo1, lo2
+ // The following can be improved, but not that much.
+ Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETEQ);
+ Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSLo, RHSLo, CCCode);
+ Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
+ Tmp1 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, ISD::SETNE);
+ Tmp2 = DAG.getSetCC(TLI.getSetCCResultTy(), LHSHi, RHSHi, CCCode);
+ Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
+ Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3);
+ Tmp2 = SDOperand();
+ break;
+ }
+
+ switch (CCCode) {
case ISD::SETEQ:
case ISD::SETNE:
if (RHSLo == RHSHi)
// FIXME: This generated code sucks.
ISD::CondCode LowCC;
- ISD::CondCode CCCode = cast<CondCodeSDNode>(CC)->get();
switch (CCCode) {
default: assert(0 && "Unknown integer setcc!");
case ISD::SETLT:
}
}
- RTLIB::Libcall LC;
+ RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (Node->getOperand(0).getValueType() == MVT::f32)
LC = RTLIB::FPTOSINT_F32_I64;
else if (Node->getOperand(0).getValueType() == MVT::f64)
LC = RTLIB::FPTOSINT_F64_I64;
- else
- LC = RTLIB::FPTOSINT_LD_I64;
+ else if (Node->getOperand(0).getValueType() == MVT::f80)
+ LC = RTLIB::FPTOSINT_F80_I64;
+ else if (Node->getOperand(0).getValueType() == MVT::ppcf128)
+ LC = RTLIB::FPTOSINT_PPCF128_I64;
Lo = ExpandLibCall(TLI.getLibcallName(LC), Node,
false/*sign irrelevant*/, Hi);
break;
}
}
- RTLIB::Libcall LC;
+ RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (Node->getOperand(0).getValueType() == MVT::f32)
LC = RTLIB::FPTOUINT_F32_I64;
- else
+ else if (Node->getOperand(0).getValueType() == MVT::f64)
LC = RTLIB::FPTOUINT_F64_I64;
+ else if (Node->getOperand(0).getValueType() == MVT::f80)
+ LC = RTLIB::FPTOUINT_F80_I64;
+ else if (Node->getOperand(0).getValueType() == MVT::ppcf128)
+ LC = RTLIB::FPTOUINT_PPCF128_I64;
Lo = ExpandLibCall(TLI.getLibcallName(LC), Node,
false/*sign irrelevant*/, Hi);
break;
bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, NVT);
bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, NVT);
- if (HasMULHS || HasMULHU) {
+ bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, NVT);
+ bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, NVT);
+ if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) {
SDOperand LL, LH, RL, RH;
ExpandOp(Node->getOperand(0), LL, LH);
ExpandOp(Node->getOperand(1), RL, RH);
- unsigned SH = MVT::getSizeInBits(RH.getValueType())-1;
- // FIXME: Move this to the dag combiner.
- // MULHS implicitly sign extends its inputs. Check to see if ExpandOp
- // extended the sign bit of the low half through the upper half, and if so
- // emit a MULHS instead of the alternate sequence that is valid for any
- // i64 x i64 multiply.
- if (HasMULHS &&
- // is RH an extension of the sign bit of RL?
- RH.getOpcode() == ISD::SRA && RH.getOperand(0) == RL &&
- RH.getOperand(1).getOpcode() == ISD::Constant &&
- cast<ConstantSDNode>(RH.getOperand(1))->getValue() == SH &&
- // is LH an extension of the sign bit of LL?
- LH.getOpcode() == ISD::SRA && LH.getOperand(0) == LL &&
- LH.getOperand(1).getOpcode() == ISD::Constant &&
- cast<ConstantSDNode>(LH.getOperand(1))->getValue() == SH) {
- // Low part:
- Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
- // High part:
- Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL);
+ unsigned BitSize = MVT::getSizeInBits(RH.getValueType());
+ unsigned LHSSB = DAG.ComputeNumSignBits(Op.getOperand(0));
+ unsigned RHSSB = DAG.ComputeNumSignBits(Op.getOperand(1));
+ // FIXME: generalize this to handle other bit sizes
+ if (LHSSB == 32 && RHSSB == 32 &&
+ DAG.MaskedValueIsZero(Op.getOperand(0), 0xFFFFFFFF00000000ULL) &&
+ DAG.MaskedValueIsZero(Op.getOperand(1), 0xFFFFFFFF00000000ULL)) {
+ // The inputs are both zero-extended.
+ if (HasUMUL_LOHI) {
+ // We can emit a umul_lohi.
+ Lo = DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL);
+ Hi = SDOperand(Lo.Val, 1);
+ break;
+ }
+ if (HasMULHU) {
+ // We can emit a mulhu+mul.
+ Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
+ Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL);
+ break;
+ }
break;
- } else if (HasMULHU) {
- // Low part:
- Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
-
- // High part:
- Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL);
+ }
+ if (LHSSB > BitSize && RHSSB > BitSize) {
+ // The input values are both sign-extended.
+ if (HasSMUL_LOHI) {
+ // We can emit a smul_lohi.
+ Lo = DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL);
+ Hi = SDOperand(Lo.Val, 1);
+ break;
+ }
+ if (HasMULHS) {
+ // We can emit a mulhs+mul.
+ Lo = DAG.getNode(ISD::MUL, NVT, LL, RL);
+ Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL);
+ break;
+ }
+ }
+ if (HasUMUL_LOHI) {
+ // Lo,Hi = umul LHS, RHS.
+ SDOperand UMulLOHI = DAG.getNode(ISD::UMUL_LOHI,
+ DAG.getVTList(NVT, NVT), LL, RL);
+ Lo = UMulLOHI;
+ Hi = UMulLOHI.getValue(1);
RH = DAG.getNode(ISD::MUL, NVT, LL, RH);
LH = DAG.getNode(ISD::MUL, NVT, LH, RL);
Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH);
}
}
+ // If nothing else, we can make a libcall.
Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::MUL_I64), Node,
false/*sign irrelevant*/, Hi);
break;
break;
case ISD::FADD:
- Lo = ExpandLibCall(TLI.getLibcallName((VT == MVT::f32)
- ? RTLIB::ADD_F32 : RTLIB::ADD_F64),
+ Lo = ExpandLibCall(TLI.getLibcallName(VT == MVT::f32 ? RTLIB::ADD_F32 :
+ VT == MVT::f64 ? RTLIB::ADD_F64 :
+ VT == MVT::ppcf128 ?
+ RTLIB::ADD_PPCF128 :
+ RTLIB::UNKNOWN_LIBCALL),
Node, false, Hi);
break;
case ISD::FSUB:
- Lo = ExpandLibCall(TLI.getLibcallName((VT == MVT::f32)
- ? RTLIB::SUB_F32 : RTLIB::SUB_F64),
+ Lo = ExpandLibCall(TLI.getLibcallName(VT == MVT::f32 ? RTLIB::SUB_F32 :
+ VT == MVT::f64 ? RTLIB::SUB_F64 :
+ VT == MVT::ppcf128 ?
+ RTLIB::SUB_PPCF128 :
+ RTLIB::UNKNOWN_LIBCALL),
Node, false, Hi);
break;
case ISD::FMUL:
- Lo = ExpandLibCall(TLI.getLibcallName((VT == MVT::f32)
- ? RTLIB::MUL_F32 : RTLIB::MUL_F64),
+ Lo = ExpandLibCall(TLI.getLibcallName(VT == MVT::f32 ? RTLIB::MUL_F32 :
+ VT == MVT::f64 ? RTLIB::MUL_F64 :
+ VT == MVT::ppcf128 ?
+ RTLIB::MUL_PPCF128 :
+ RTLIB::UNKNOWN_LIBCALL),
Node, false, Hi);
break;
case ISD::FDIV:
- Lo = ExpandLibCall(TLI.getLibcallName((VT == MVT::f32)
- ? RTLIB::DIV_F32 : RTLIB::DIV_F64),
+ Lo = ExpandLibCall(TLI.getLibcallName(VT == MVT::f32 ? RTLIB::DIV_F32 :
+ VT == MVT::f64 ? RTLIB::DIV_F64 :
+ VT == MVT::ppcf128 ?
+ RTLIB::DIV_PPCF128 :
+ RTLIB::UNKNOWN_LIBCALL),
Node, false, Hi);
break;
case ISD::FP_EXTEND:
Lo = ExpandLibCall(TLI.getLibcallName(RTLIB::FPROUND_F64_F32),Node,true,Hi);
break;
case ISD::FPOWI:
- Lo = ExpandLibCall(TLI.getLibcallName((VT == MVT::f32)
- ? RTLIB::POWI_F32 : RTLIB::POWI_F64),
+ Lo = ExpandLibCall(TLI.getLibcallName((VT == MVT::f32) ? RTLIB::POWI_F32 :
+ (VT == MVT::f64) ? RTLIB::POWI_F64 :
+ (VT == MVT::f80) ? RTLIB::POWI_F80 :
+ (VT == MVT::ppcf128) ?
+ RTLIB::POWI_PPCF128 :
+ RTLIB::UNKNOWN_LIBCALL),
Node, false, Hi);
break;
case ISD::FSQRT:
RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
switch(Node->getOpcode()) {
case ISD::FSQRT:
- LC = (VT == MVT::f32) ? RTLIB::SQRT_F32 : RTLIB::SQRT_F64;
+ LC = (VT == MVT::f32) ? RTLIB::SQRT_F32 :
+ (VT == MVT::f64) ? RTLIB::SQRT_F64 :
+ (VT == MVT::f80) ? RTLIB::SQRT_F80 :
+ (VT == MVT::ppcf128) ? RTLIB::SQRT_PPCF128 :
+ RTLIB::UNKNOWN_LIBCALL;
break;
case ISD::FSIN:
LC = (VT == MVT::f32) ? RTLIB::SIN_F32 : RTLIB::SIN_F64;
case ISD::UINT_TO_FP: {
bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP;
MVT::ValueType SrcVT = Node->getOperand(0).getValueType();
- RTLIB::Libcall LC;
+ RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
if (Node->getOperand(0).getValueType() == MVT::i64) {
if (VT == MVT::f32)
LC = isSigned ? RTLIB::SINTTOFP_I64_F32 : RTLIB::UINTTOFP_I64_F32;
else if (VT == MVT::f64)
LC = isSigned ? RTLIB::SINTTOFP_I64_F64 : RTLIB::UINTTOFP_I64_F64;
- else if (VT == MVT::f80 || VT == MVT::f128 || VT == MVT::ppcf128) {
+ else if (VT == MVT::f80) {
assert(isSigned);
- LC = RTLIB::SINTTOFP_I64_LD;
+ LC = RTLIB::SINTTOFP_I64_F80;
+ }
+ else if (VT == MVT::ppcf128) {
+ assert(isSigned);
+ LC = RTLIB::SINTTOFP_I64_PPCF128;
}
} else {
if (VT == MVT::f32)
SDOperand &Hi) {
assert(MVT::isVector(Op.getValueType()) && "Cannot split non-vector type!");
SDNode *Node = Op.Val;
- unsigned NumElements = MVT::getVectorNumElements(Node->getValueType(0));
+ unsigned NumElements = MVT::getVectorNumElements(Op.getValueType());
assert(NumElements > 1 && "Cannot split a single element vector!");
unsigned NewNumElts = NumElements/2;
- MVT::ValueType NewEltVT = MVT::getVectorElementType(Node->getValueType(0));
+ MVT::ValueType NewEltVT = MVT::getVectorElementType(Op.getValueType());
MVT::ValueType NewVT = MVT::getVectorType(NewEltVT, NewNumElts);
// See if we already split it.
Lo = Node->getOperand(0);
Hi = Node->getOperand(1);
break;
+ case ISD::INSERT_VECTOR_ELT: {
+ SplitVectorOp(Node->getOperand(0), Lo, Hi);
+ unsigned Index = cast<ConstantSDNode>(Node->getOperand(2))->getValue();
+ SDOperand ScalarOp = Node->getOperand(1);
+ if (Index < NewNumElts)
+ Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT, Lo, ScalarOp,
+ DAG.getConstant(Index, TLI.getPointerTy()));
+ else
+ Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT, Hi, ScalarOp,
+ DAG.getConstant(Index - NewNumElts, TLI.getPointerTy()));
+ break;
+ }
case ISD::BUILD_VECTOR: {
SmallVector<SDOperand, 8> LoOps(Node->op_begin(),
Node->op_begin()+NewNumElts);