-SDOperand DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) {
- SDOperand InL, InH;
- GetExpandedInteger(N->getOperand(0), InL, InH);
- // Just truncate the low part of the source.
- return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), InL);
-}
-
-SDOperand DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDNode *N) {
- SDOperand Op = N->getOperand(0);
- MVT SrcVT = Op.getValueType();
- MVT DstVT = N->getValueType(0);
-
- RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
- if (SrcVT == MVT::i32) {
- if (DstVT == MVT::f32)
- LC = RTLIB::SINTTOFP_I32_F32;
- else if (DstVT == MVT::f64)
- LC = RTLIB::SINTTOFP_I32_F64;
- else if (DstVT == MVT::f80)
- LC = RTLIB::SINTTOFP_I32_F80;
- else if (DstVT == MVT::ppcf128)
- LC = RTLIB::SINTTOFP_I32_PPCF128;
- } else if (SrcVT == MVT::i64) {
- if (DstVT == MVT::f32)
- LC = RTLIB::SINTTOFP_I64_F32;
- else if (DstVT == MVT::f64)
- LC = RTLIB::SINTTOFP_I64_F64;
- else if (DstVT == MVT::f80)
- LC = RTLIB::SINTTOFP_I64_F80;
- else if (DstVT == MVT::ppcf128)
- LC = RTLIB::SINTTOFP_I64_PPCF128;
- } else if (SrcVT == MVT::i128) {
- if (DstVT == MVT::f32)
- LC = RTLIB::SINTTOFP_I128_F32;
- else if (DstVT == MVT::f64)
- LC = RTLIB::SINTTOFP_I128_F64;
- else if (DstVT == MVT::f80)
- LC = RTLIB::SINTTOFP_I128_F80;
- else if (DstVT == MVT::ppcf128)
- LC = RTLIB::SINTTOFP_I128_PPCF128;
- }
- assert(LC != RTLIB::UNKNOWN_LIBCALL &&
- "Don't know how to expand this SINT_TO_FP!");
-
- return MakeLibCall(LC, DstVT, &Op, 1, true);
-}
-
-SDOperand DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) {
- SDOperand Op = N->getOperand(0);
- MVT SrcVT = Op.getValueType();
- MVT DstVT = N->getValueType(0);
-
- if (TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) == TargetLowering::Custom){
- // Do a signed conversion then adjust the result.
- SDOperand SignedConv = DAG.getNode(ISD::SINT_TO_FP, DstVT, Op);
- SignedConv = TLI.LowerOperation(SignedConv, DAG);
-
- // The result of the signed conversion needs adjusting if the 'sign bit' of
- // the incoming integer was set. To handle this, we dynamically test to see
- // if it is set, and, if so, add a fudge factor.
-
- const uint64_t F32TwoE32 = 0x4F800000ULL;
- const uint64_t F32TwoE64 = 0x5F800000ULL;
- const uint64_t F32TwoE128 = 0x7F800000ULL;
-
- APInt FF(32, 0);
- if (SrcVT == MVT::i32)
- FF = APInt(32, F32TwoE32);
- else if (SrcVT == MVT::i64)
- FF = APInt(32, F32TwoE64);
- else if (SrcVT == MVT::i128)
- FF = APInt(32, F32TwoE128);
- else
- assert(false && "Unsupported UINT_TO_FP!");
-
- // Check whether the sign bit is set.
- SDOperand Lo, Hi;
- GetExpandedInteger(Op, Lo, Hi);
- SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi), Hi,
- DAG.getConstant(0, Hi.getValueType()),
- ISD::SETLT);
-
- // Build a 64 bit pair (0, FF) in the constant pool, with FF in the lo bits.
- SDOperand FudgePtr = DAG.getConstantPool(ConstantInt::get(FF.zext(64)),
- TLI.getPointerTy());
-
- // Get a pointer to FF if the sign bit was set, or to 0 otherwise.
- SDOperand Zero = DAG.getIntPtrConstant(0);
- SDOperand Four = DAG.getIntPtrConstant(4);
- if (TLI.isBigEndian()) std::swap(Zero, Four);
- SDOperand Offset = DAG.getNode(ISD::SELECT, Zero.getValueType(), SignSet,
- Zero, Four);
- FudgePtr = DAG.getNode(ISD::ADD, TLI.getPointerTy(), FudgePtr, Offset);
-
- // Load the value out, extending it from f32 to the destination float type.
- // FIXME: Avoid the extend by constructing the right constant pool?
- SDOperand Fudge = DAG.getExtLoad(ISD::EXTLOAD, DstVT, DAG.getEntryNode(),
- FudgePtr, NULL, 0, MVT::f32);
- return DAG.getNode(ISD::FADD, DstVT, SignedConv, Fudge);
- }
-
- // Otherwise, use a libcall.
- RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
- if (SrcVT == MVT::i32) {
- if (DstVT == MVT::f32)
- LC = RTLIB::UINTTOFP_I32_F32;
- else if (DstVT == MVT::f64)
- LC = RTLIB::UINTTOFP_I32_F64;
- else if (DstVT == MVT::f80)
- LC = RTLIB::UINTTOFP_I32_F80;
- else if (DstVT == MVT::ppcf128)
- LC = RTLIB::UINTTOFP_I32_PPCF128;
- } else if (SrcVT == MVT::i64) {
- if (DstVT == MVT::f32)
- LC = RTLIB::UINTTOFP_I64_F32;
- else if (DstVT == MVT::f64)
- LC = RTLIB::UINTTOFP_I64_F64;
- else if (DstVT == MVT::f80)
- LC = RTLIB::UINTTOFP_I64_F80;
- else if (DstVT == MVT::ppcf128)
- LC = RTLIB::UINTTOFP_I64_PPCF128;
- } else if (SrcVT == MVT::i128) {
- if (DstVT == MVT::f32)
- LC = RTLIB::UINTTOFP_I128_F32;
- else if (DstVT == MVT::f64)
- LC = RTLIB::UINTTOFP_I128_F64;
- else if (DstVT == MVT::f80)
- LC = RTLIB::UINTTOFP_I128_F80;
- else if (DstVT == MVT::ppcf128)
- LC = RTLIB::UINTTOFP_I128_PPCF128;
- }
- assert(LC != RTLIB::UNKNOWN_LIBCALL &&
- "Don't know how to expand this UINT_TO_FP!");
-
- return MakeLibCall(LC, DstVT, &Op, 1, true);
-}
-
-SDOperand DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) {
- SDOperand NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
- ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
- IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode);
-
- // If ExpandSetCCOperands returned a scalar, we need to compare the result
- // against zero to select between true and false values.
- if (NewRHS.Val == 0) {
- NewRHS = DAG.getConstant(0, NewLHS.getValueType());
- CCCode = ISD::SETNE;
- }
-
- // Update N to have the operands specified.
- return DAG.UpdateNodeOperands(SDOperand(N, 0), N->getOperand(0),
- DAG.getCondCode(CCCode), NewLHS, NewRHS,
- N->getOperand(4));
-}
-
-SDOperand DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) {
- SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
- ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
- IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode);
-
- // If ExpandSetCCOperands returned a scalar, we need to compare the result
- // against zero to select between true and false values.
- if (NewRHS.Val == 0) {
- NewRHS = DAG.getConstant(0, NewLHS.getValueType());
- CCCode = ISD::SETNE;
- }
-
- // Update N to have the operands specified.
- return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS,
- N->getOperand(2), N->getOperand(3),
- DAG.getCondCode(CCCode));
-}
-
-SDOperand DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) {
- SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
- ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
- IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode);
-
- // If ExpandSetCCOperands returned a scalar, use it.
- if (NewRHS.Val == 0) {
- assert(NewLHS.getValueType() == N->getValueType(0) &&
- "Unexpected setcc expansion!");
- return NewLHS;
- }
-
- // Otherwise, update N to have the operands specified.
- return DAG.UpdateNodeOperands(SDOperand(N, 0), NewLHS, NewRHS,
- DAG.getCondCode(CCCode));
-}
-