X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FLegalizeFloatTypes.cpp;h=520924d14e7839d186cd7bbe5a24f6a7b281b21d;hb=7ba11c552b8a25ad1272b44d96e886a784dae0b7;hp=b2580f5fa70e8e59ac1892b83de0f339efd64d8e;hpb=8dd5af562b8ab9ddf4c6e3a74ca3c4f66dcd0e9e;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index b2580f5fa70..520924d14e7 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -48,28 +48,13 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) { cerr << "\n"); SDOperand R = SDOperand(); - // FIXME: Custom lowering for float-to-int? -#if 0 - // See if the target wants to custom convert this node to an integer. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) { - // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.FloatToIntOperationResult(N, DAG)) { - // Everything that once used N now uses P. We are guaranteed that the - // result value types of N and the result value types of P match. - ReplaceNodeWith(N, P); - return; - } - } -#endif - switch (N->getOpcode()) { default: #ifndef NDEBUG cerr << "SoftenFloatResult #" << ResNo << ": "; N->dump(&DAG); cerr << "\n"; #endif - assert(0 && "Do not know how to convert the result of this operator!"); + assert(0 && "Do not know how to soften the result of this operator!"); abort(); case ISD::BIT_CONVERT: R = SoftenFloatRes_BIT_CONVERT(N); break; @@ -78,7 +63,11 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) { R = SoftenFloatRes_ConstantFP(cast(N)); break; case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break; + case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break; + case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break; case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break; + case ISD::SELECT: R = SoftenFloatRes_SELECT(N); break; + case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N); break; case ISD::SINT_TO_FP: case ISD::UINT_TO_FP: R = SoftenFloatRes_XINT_TO_FP(N); break; @@ -172,6 +161,46 @@ SDOperand DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { NVT, Ops, 2, false); } +SDOperand DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDOperand Op = N->getOperand(0); + + RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; + switch (Op.getValueType().getSimpleVT()) { + default: + assert(false && "Unsupported FP_EXTEND!"); + case MVT::f32: + switch (N->getValueType(0).getSimpleVT()) { + default: + assert(false && "Unsupported FP_EXTEND!"); + case MVT::f64: + LC = RTLIB::FPEXT_F32_F64; + } + } + + return MakeLibCall(LC, NVT, &Op, 1, false); +} + +SDOperand DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDOperand Op = N->getOperand(0); + + RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; + switch (Op.getValueType().getSimpleVT()) { + default: + assert(false && "Unsupported FP_ROUND!"); + case MVT::f64: + switch (N->getValueType(0).getSimpleVT()) { + default: + assert(false && "Unsupported FP_ROUND!"); + case MVT::f32: + LC = RTLIB::FPROUND_F64_F32; + } + } + + return MakeLibCall(LC, NVT, &Op, 1, false); +} + SDOperand DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDOperand Ops[2] = { GetSoftenedFloat(N->getOperand(0)), @@ -205,6 +234,19 @@ SDOperand DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, VT, NL)); } +SDOperand DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N) { + SDOperand LHS = GetSoftenedFloat(N->getOperand(1)); + SDOperand RHS = GetSoftenedFloat(N->getOperand(2)); + return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS); +} + +SDOperand DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N) { + SDOperand LHS = GetSoftenedFloat(N->getOperand(2)); + SDOperand RHS = GetSoftenedFloat(N->getOperand(3)); + return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0), + N->getOperand(1), LHS, RHS, N->getOperand(4)); +} + SDOperand DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) { bool isSigned = N->getOpcode() == ISD::SINT_TO_FP; MVT DestVT = N->getValueType(0); @@ -313,31 +355,23 @@ SDOperand DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) { bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) { DEBUG(cerr << "Soften float operand " << OpNo << ": "; N->dump(&DAG); cerr << "\n"); - SDOperand Res(0, 0); + SDOperand Res = SDOperand(); - // FIXME: Custom lowering for float-to-int? -#if 0 - if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) - == TargetLowering::Custom) - Res = TLI.LowerOperation(SDOperand(N, 0), DAG); -#endif - - if (Res.Val == 0) { - switch (N->getOpcode()) { - default: + switch (N->getOpcode()) { + default: #ifndef NDEBUG - cerr << "SoftenFloatOperand Op #" << OpNo << ": "; - N->dump(&DAG); cerr << "\n"; + cerr << "SoftenFloatOperand Op #" << OpNo << ": "; + N->dump(&DAG); cerr << "\n"; #endif - assert(0 && "Do not know how to convert this operator's operand!"); - abort(); + assert(0 && "Do not know how to soften this operator's operand!"); + abort(); - case ISD::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break; + case ISD::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break; - case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(N); break; - case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break; - case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break; - } + case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(N); break; + case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break; + case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break; + case ISD::STORE: Res = SoftenFloatOp_STORE(N, OpNo); break; } // If the result is null, the sub-method took care of registering results etc. @@ -366,8 +400,7 @@ void DAGTypeLegalizer::SoftenSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS, ISD::CondCode &CCCode) { SDOperand LHSInt = GetSoftenedFloat(NewLHS); SDOperand RHSInt = GetSoftenedFloat(NewRHS); - MVT VT = NewLHS.getValueType(); - MVT NVT = LHSInt.getValueType(); + MVT VT = NewLHS.getValueType(); assert((VT == MVT::f32 || VT == MVT::f64) && "Unsupported setcc type!"); @@ -402,6 +435,7 @@ void DAGTypeLegalizer::SoftenSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS, LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64; break; case ISD::SETO: + LC1 = (VT == MVT::f32) ? RTLIB::O_F32 : RTLIB::O_F64; break; default: LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64; @@ -430,13 +464,13 @@ void DAGTypeLegalizer::SoftenSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS, } SDOperand Ops[2] = { LHSInt, RHSInt }; - NewLHS = MakeLibCall(LC1, NVT, Ops, 2, false/*sign irrelevant*/); - NewRHS = DAG.getConstant(0, NVT); + NewLHS = MakeLibCall(LC1, MVT::i32, Ops, 2, false/*sign irrelevant*/); + NewRHS = DAG.getConstant(0, MVT::i32); + CCCode = TLI.getCmpLibcallCC(LC1); if (LC2 != RTLIB::UNKNOWN_LIBCALL) { SDOperand Tmp = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(NewLHS), - NewLHS, NewRHS, - DAG.getCondCode(TLI.getCmpLibcallCC(LC1))); - NewLHS = MakeLibCall(LC2, NVT, Ops, 2, false/*sign irrelevant*/); + NewLHS, NewRHS, DAG.getCondCode(CCCode)); + NewLHS = MakeLibCall(LC2, MVT::i32, Ops, 2, false/*sign irrelevant*/); NewLHS = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(NewLHS), NewLHS, NewRHS, DAG.getCondCode(TLI.getCmpLibcallCC(LC2))); NewLHS = DAG.getNode(ISD::OR, Tmp.getValueType(), Tmp, NewLHS); @@ -502,6 +536,24 @@ SDOperand DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) { DAG.getCondCode(CCCode)); } +SDOperand DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) { + assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); + assert(OpNo == 1 && "Can only soften the stored value!"); + StoreSDNode *ST = cast(N); + SDOperand Val = ST->getValue(); + + if (ST->isTruncatingStore()) + // Do an FP_ROUND followed by a non-truncating store. + Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, ST->getMemoryVT(), + Val, DAG.getIntPtrConstant(0))); + else + Val = GetSoftenedFloat(Val); + + return DAG.getStore(ST->getChain(), Val, ST->getBasePtr(), + ST->getSrcValue(), ST->getSrcValueOffset(), + ST->isVolatile(), ST->getAlignment()); +} + //===----------------------------------------------------------------------===// // Float Result Expansion @@ -517,10 +569,10 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { Lo = Hi = SDOperand(); // See if the target wants to custom expand this node. - if (TLI.getOperationAction(N->getOpcode(), N->getValueType(0)) == - TargetLowering::Custom) { + if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) == + TargetLowering::Custom) { // If the target wants to, allow it to lower this itself. - if (SDNode *P = TLI.ExpandOperationResult(N, DAG)) { + if (SDNode *P = TLI.ReplaceNodeResults(N, DAG)) { // Everything that once used N now uses P. We are guaranteed that the // result value types of N and the result value types of P match. ReplaceNodeWith(N, P); @@ -738,11 +790,11 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDOperand &Lo, /// need promotion or expansion as well as the specified one. bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) { DEBUG(cerr << "Expand float operand: "; N->dump(&DAG); cerr << "\n"); - SDOperand Res(0, 0); + SDOperand Res = SDOperand(); if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) == TargetLowering::Custom) - Res = TLI.LowerOperation(SDOperand(N, 0), DAG); + Res = TLI.LowerOperation(SDOperand(N, OpNo), DAG); if (Res.Val == 0) { switch (N->getOpcode()) {