X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FSelectionDAG%2FLegalizeFloatTypes.cpp;h=b0583cfa75ea676a324429cd7730bc818c3e7eed;hb=49c18cce976c158e86f54c681dff21bb81640fb8;hp=bfe2ce6d8832dedb395c4ba124b6bfbc2b17b09c;hpb=126d90770bdb17e6925b2fe26de99aa079b7b9b3;p=oota-llvm.git diff --git a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index bfe2ce6d883..b0583cfa75e 100644 --- a/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -20,9 +20,6 @@ //===----------------------------------------------------------------------===// #include "LegalizeTypes.h" -#include "llvm/CodeGen/PseudoSourceValue.h" -#include "llvm/Constants.h" -#include "llvm/DerivedTypes.h" using namespace llvm; /// GetFPLibCall - Return the right libcall for the given floating point type. @@ -46,19 +43,7 @@ static RTLIB::Libcall GetFPLibCall(MVT VT, void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) { DEBUG(cerr << "Soften float result " << ResNo << ": "; N->dump(&DAG); cerr << "\n"); - SDOperand R = SDOperand(); - - // See if the target wants to custom expand this node. - 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.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); - return; - } - } + SDValue R = SDValue(); switch (N->getOpcode()) { default: @@ -66,7 +51,7 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) { 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; @@ -74,26 +59,32 @@ void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) { case ISD::ConstantFP: R = SoftenFloatRes_ConstantFP(cast(N)); break; + case ISD::FABS: R = SoftenFloatRes_FABS(N); break; + case ISD::FADD: R = SoftenFloatRes_FADD(N); break; case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break; + case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break; + case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break; + case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break; + case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break; + case ISD::FPOWI: R = SoftenFloatRes_FPOWI(N); break; + case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break; case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break; - case ISD::SINT_TO_FP: - case ISD::UINT_TO_FP: R = SoftenFloatRes_XINT_TO_FP(N); break; - - case ISD::FADD: R = SoftenFloatRes_FADD(N); break; - case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break; - case ISD::FSUB: R = SoftenFloatRes_FSUB(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: R = SoftenFloatRes_SINT_TO_FP(N); break; + case ISD::UINT_TO_FP: R = SoftenFloatRes_UINT_TO_FP(N); break; } // If R is null, the sub-method took care of registering the result. - if (R.Val) - SetSoftenedFloat(SDOperand(N, ResNo), R); + if (R.getNode()) + SetSoftenedFloat(SDValue(N, ResNo), R); } -SDOperand DAGTypeLegalizer::SoftenFloatRes_BIT_CONVERT(SDNode *N) { +SDValue DAGTypeLegalizer::SoftenFloatRes_BIT_CONVERT(SDNode *N) { return BitConvertToInteger(N->getOperand(0)); } -SDOperand DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) { +SDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) { // Convert the inputs to integers, and build a new pair out of them. return DAG.getNode(ISD::BUILD_PAIR, TLI.getTypeToTransformTo(N->getValueType(0)), @@ -101,14 +92,25 @@ SDOperand DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) { BitConvertToInteger(N->getOperand(1))); } -SDOperand DAGTypeLegalizer::SoftenFloatRes_ConstantFP(ConstantFPSDNode *N) { - return DAG.getConstant(N->getValueAPF().convertToAPInt(), +SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(ConstantFPSDNode *N) { + return DAG.getConstant(N->getValueAPF().bitcastToAPInt(), TLI.getTypeToTransformTo(N->getValueType(0))); } -SDOperand DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) { +SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + unsigned Size = NVT.getSizeInBits(); + + // Mask = ~(1 << (Size-1)) + SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1), + NVT); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return DAG.getNode(ISD::AND, NVT, Op, Mask); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDOperand Ops[2] = { GetSoftenedFloat(N->getOperand(0)), + SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), GetSoftenedFloat(N->getOperand(1)) }; return MakeLibCall(GetFPLibCall(N->getValueType(0), RTLIB::ADD_F32, @@ -118,9 +120,9 @@ SDOperand DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) { NVT, Ops, 2, false); } -SDOperand DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { - SDOperand LHS = GetSoftenedFloat(N->getOperand(0)); - SDOperand RHS = BitConvertToInteger(N->getOperand(1)); +SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { + SDValue LHS = GetSoftenedFloat(N->getOperand(0)); + SDValue RHS = BitConvertToInteger(N->getOperand(1)); MVT LVT = LHS.getValueType(); MVT RVT = RHS.getValueType(); @@ -129,7 +131,7 @@ SDOperand DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { unsigned RSize = RVT.getSizeInBits(); // First get the sign bit of second operand. - SDOperand SignBit = DAG.getNode(ISD::SHL, RVT, DAG.getConstant(1, RVT), + SDValue SignBit = DAG.getNode(ISD::SHL, RVT, DAG.getConstant(1, RVT), DAG.getConstant(RSize - 1, TLI.getShiftAmountTy())); SignBit = DAG.getNode(ISD::AND, RVT, RHS, SignBit); @@ -147,7 +149,7 @@ SDOperand DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { } // Clear the sign bit of the first operand. - SDOperand Mask = DAG.getNode(ISD::SHL, LVT, DAG.getConstant(1, LVT), + SDValue Mask = DAG.getNode(ISD::SHL, LVT, DAG.getConstant(1, LVT), DAG.getConstant(LSize - 1, TLI.getShiftAmountTy())); Mask = DAG.getNode(ISD::SUB, LVT, Mask, DAG.getConstant(1, LVT)); @@ -157,9 +159,21 @@ SDOperand DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { return DAG.getNode(ISD::OR, LVT, LHS, SignBit); } -SDOperand DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { +SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDOperand Ops[2] = { GetSoftenedFloat(N->getOperand(0)), + SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), + GetSoftenedFloat(N->getOperand(1)) }; + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::DIV_F32, + RTLIB::DIV_F64, + RTLIB::DIV_F80, + RTLIB::DIV_PPCF128), + NVT, Ops, 2, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), GetSoftenedFloat(N->getOperand(1)) }; return MakeLibCall(GetFPLibCall(N->getValueType(0), RTLIB::MUL_F32, @@ -169,9 +183,36 @@ SDOperand DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { NVT, Ops, 2, false); } -SDOperand DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) { +SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = N->getOperand(0); + RTLIB::Libcall LC = RTLIB::getFPEXT(Op.getValueType(), N->getValueType(0)); + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!"); + return MakeLibCall(LC, NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Op = N->getOperand(0); + RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), N->getValueType(0)); + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND!"); + return MakeLibCall(LC, NVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), N->getOperand(1) }; + return MakeLibCall(GetFPLibCall(N->getValueType(0), + RTLIB::POWI_F32, + RTLIB::POWI_F64, + RTLIB::POWI_F80, + RTLIB::POWI_PPCF128), + NVT, Ops, 2, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDOperand Ops[2] = { GetSoftenedFloat(N->getOperand(0)), + SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), GetSoftenedFloat(N->getOperand(1)) }; return MakeLibCall(GetFPLibCall(N->getValueType(0), RTLIB::SUB_F32, @@ -181,125 +222,63 @@ SDOperand DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) { NVT, Ops, 2, false); } -SDOperand DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { +SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { LoadSDNode *L = cast(N); MVT VT = N->getValueType(0); MVT NVT = TLI.getTypeToTransformTo(VT); - if (L->getExtensionType() == ISD::NON_EXTLOAD) - return DAG.getLoad(L->getAddressingMode(), L->getExtensionType(), - NVT, L->getChain(), L->getBasePtr(), L->getOffset(), - L->getSrcValue(), L->getSrcValueOffset(), NVT, - L->isVolatile(), L->getAlignment()); + SDValue NewL; + if (L->getExtensionType() == ISD::NON_EXTLOAD) { + NewL = DAG.getLoad(L->getAddressingMode(), L->getExtensionType(), + NVT, L->getChain(), L->getBasePtr(), L->getOffset(), + L->getSrcValue(), L->getSrcValueOffset(), NVT, + L->isVolatile(), L->getAlignment()); + // Legalized the chain result - switch anything that used the old chain to + // use the new one. + ReplaceValueWith(SDValue(N, 1), NewL.getValue(1)); + return NewL; + } // Do a non-extending load followed by FP_EXTEND. - SDOperand NL = DAG.getLoad(L->getAddressingMode(), ISD::NON_EXTLOAD, - L->getMemoryVT(), L->getChain(), - L->getBasePtr(), L->getOffset(), - L->getSrcValue(), L->getSrcValueOffset(), - L->getMemoryVT(), - L->isVolatile(), L->getAlignment()); - return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, VT, NL)); -} - -SDOperand DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) { - bool isSigned = N->getOpcode() == ISD::SINT_TO_FP; - MVT DestVT = N->getValueType(0); - SDOperand Op = N->getOperand(0); - - if (Op.getValueType() == MVT::i32) { - // simple 32-bit [signed|unsigned] integer to float/double expansion - - // Get the stack frame index of a 8 byte buffer. - SDOperand StackSlot = DAG.CreateStackTemporary(MVT::f64); - - // word offset constant for Hi/Lo address computation - SDOperand Offset = - DAG.getConstant(MVT(MVT::i32).getSizeInBits() / 8, - TLI.getPointerTy()); - // set up Hi and Lo (into buffer) address based on endian - SDOperand Hi = StackSlot; - SDOperand Lo = DAG.getNode(ISD::ADD, TLI.getPointerTy(), StackSlot, Offset); - if (TLI.isLittleEndian()) - std::swap(Hi, Lo); - - // if signed map to unsigned space - SDOperand OpMapped; - if (isSigned) { - // constant used to invert sign bit (signed to unsigned mapping) - SDOperand SignBit = DAG.getConstant(0x80000000u, MVT::i32); - OpMapped = DAG.getNode(ISD::XOR, MVT::i32, Op, SignBit); - } else { - OpMapped = Op; - } - // store the lo of the constructed double - based on integer input - SDOperand Store1 = DAG.getStore(DAG.getEntryNode(), - OpMapped, Lo, NULL, 0); - // initial hi portion of constructed double - SDOperand InitialHi = DAG.getConstant(0x43300000u, MVT::i32); - // store the hi of the constructed double - biased exponent - SDOperand Store2=DAG.getStore(Store1, InitialHi, Hi, NULL, 0); - // load the constructed double - SDOperand Load = DAG.getLoad(MVT::f64, Store2, StackSlot, NULL, 0); - // FP constant to bias correct the final result - SDOperand Bias = DAG.getConstantFP(isSigned ? - BitsToDouble(0x4330000080000000ULL) - : BitsToDouble(0x4330000000000000ULL), - MVT::f64); - // subtract the bias - SDOperand Sub = DAG.getNode(ISD::FSUB, MVT::f64, Load, Bias); - // final result - SDOperand Result; - // handle final rounding - if (DestVT == MVT::f64) { - // do nothing - Result = Sub; - } else if (DestVT.bitsLT(MVT::f64)) { - Result = DAG.getNode(ISD::FP_ROUND, DestVT, Sub, - DAG.getIntPtrConstant(0)); - } else if (DestVT.bitsGT(MVT::f64)) { - Result = DAG.getNode(ISD::FP_EXTEND, DestVT, Sub); - } - return BitConvertToInteger(Result); - } - assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet"); - SDOperand Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op); - - SDOperand SignSet = DAG.getSetCC(TLI.getSetCCResultType(Op), Op, - DAG.getConstant(0, Op.getValueType()), - ISD::SETLT); - SDOperand Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4); - SDOperand CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(), - SignSet, Four, Zero); - - // If the sign bit of the integer is set, the large number will be treated - // as a negative number. To counteract this, the dynamic code adds an - // offset depending on the data type. - uint64_t FF; - switch (Op.getValueType().getSimpleVT()) { - default: assert(0 && "Unsupported integer type!"); - case MVT::i8 : FF = 0x43800000ULL; break; // 2^8 (as a float) - case MVT::i16: FF = 0x47800000ULL; break; // 2^16 (as a float) - case MVT::i32: FF = 0x4F800000ULL; break; // 2^32 (as a float) - case MVT::i64: FF = 0x5F800000ULL; break; // 2^64 (as a float) - } - if (TLI.isLittleEndian()) FF <<= 32; - static Constant *FudgeFactor = ConstantInt::get(Type::Int64Ty, FF); - - SDOperand CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy()); - CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset); - SDOperand FudgeInReg; - if (DestVT == MVT::f32) - FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, - PseudoSourceValue::getConstantPool(), 0); - else { - FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, DestVT, - DAG.getEntryNode(), CPIdx, - PseudoSourceValue::getConstantPool(), 0, - MVT::f32); - } + NewL = DAG.getLoad(L->getAddressingMode(), ISD::NON_EXTLOAD, + L->getMemoryVT(), L->getChain(), + L->getBasePtr(), L->getOffset(), + L->getSrcValue(), L->getSrcValueOffset(), + L->getMemoryVT(), + L->isVolatile(), L->getAlignment()); + // Legalized the chain result - switch anything that used the old chain to + // use the new one. + ReplaceValueWith(SDValue(N, 1), NewL.getValue(1)); + return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, VT, NewL)); +} - return BitConvertToInteger(DAG.getNode(ISD::FADD, DestVT, Tmp1, FudgeInReg)); +SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N) { + SDValue LHS = GetSoftenedFloat(N->getOperand(1)); + SDValue RHS = GetSoftenedFloat(N->getOperand(2)); + return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N) { + SDValue LHS = GetSoftenedFloat(N->getOperand(2)); + SDValue RHS = GetSoftenedFloat(N->getOperand(3)); + return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0), + N->getOperand(1), LHS, RHS, N->getOperand(4)); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_SINT_TO_FP(SDNode *N) { + SDValue Op = N->getOperand(0); + MVT RVT = N->getValueType(0); + RTLIB::Libcall LC = RTLIB::getSINTTOFP(Op.getValueType(), RVT); + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SINT_TO_FP!"); + return MakeLibCall(LC, TLI.getTypeToTransformTo(RVT), &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatRes_UINT_TO_FP(SDNode *N) { + SDValue Op = N->getOperand(0); + MVT RVT = N->getValueType(0); + RTLIB::Libcall LC = RTLIB::getUINTTOFP(Op.getValueType(), RVT); + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UINT_TO_FP!"); + return MakeLibCall(LC, TLI.getTypeToTransformTo(RVT), &Op, 1, false); } @@ -310,36 +289,33 @@ 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); - - if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) - == TargetLowering::Custom) - Res = TLI.LowerOperation(SDOperand(N, OpNo), DAG); + SDValue Res = SDValue(); - 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(); - - case ISD::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break; + assert(0 && "Do not know how to soften this operator's operand!"); + abort(); - 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::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break; + case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(N); break; + case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break; + case ISD::FP_TO_SINT: Res = SoftenFloatOp_FP_TO_SINT(N); break; + case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_UINT(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. - if (!Res.Val) return false; + if (!Res.getNode()) return false; // If the result is N, the sub-method updated N in place. Check to see if any // operands are new, and if so, mark them. - if (Res.Val == N) { + if (Res.getNode() == N) { // Mark N as new and remark N and its operands. This allows us to correctly // revisit N if it needs another step of promotion and allows us to visit // any new operands to N. @@ -350,18 +326,17 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) { assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && "Invalid operand expansion"); - ReplaceValueWith(SDOperand(N, 0), Res); + ReplaceValueWith(SDValue(N, 0), Res); return false; } /// SoftenSetCCOperands - Soften the operands of a comparison. This code is /// shared among BR_CC, SELECT_CC, and SETCC handlers. -void DAGTypeLegalizer::SoftenSetCCOperands(SDOperand &NewLHS, SDOperand &NewRHS, +void DAGTypeLegalizer::SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, ISD::CondCode &CCCode) { - SDOperand LHSInt = GetSoftenedFloat(NewLHS); - SDOperand RHSInt = GetSoftenedFloat(NewRHS); - MVT VT = NewLHS.getValueType(); - MVT NVT = LHSInt.getValueType(); + SDValue LHSInt = GetSoftenedFloat(NewLHS); + SDValue RHSInt = GetSoftenedFloat(NewRHS); + MVT VT = NewLHS.getValueType(); assert((VT == MVT::f32 || VT == MVT::f64) && "Unsupported setcc type!"); @@ -396,6 +371,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; @@ -423,79 +399,125 @@ 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); + MVT RetVT = MVT::i32; // FIXME: is this the correct return type? + SDValue Ops[2] = { LHSInt, RHSInt }; + NewLHS = MakeLibCall(LC1, RetVT, Ops, 2, false/*sign irrelevant*/); + NewRHS = DAG.getConstant(0, RetVT); + 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*/); + SDValue Tmp = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(NewLHS), + NewLHS, NewRHS, DAG.getCondCode(CCCode)); + NewLHS = MakeLibCall(LC2, RetVT, 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); - NewRHS = SDOperand(); + NewRHS = SDValue(); } } -SDOperand DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) { +SDValue DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) { return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), GetSoftenedFloat(N->getOperand(0))); } -SDOperand DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) { - SDOperand NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); +SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) { + MVT SVT = N->getOperand(0).getValueType(); + MVT RVT = N->getValueType(0); + + RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, RVT); + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall"); + + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(LC, RVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) { + SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); ISD::CondCode CCCode = cast(N->getOperand(1))->get(); SoftenSetCCOperands(NewLHS, NewRHS, CCCode); // If SoftenSetCCOperands returned a scalar, we need to compare the result // against zero to select between true and false values. - if (NewRHS.Val == 0) { + if (NewRHS.getNode() == 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), + return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), DAG.getCondCode(CCCode), NewLHS, NewRHS, N->getOperand(4)); } -SDOperand DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) { - SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); +SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode *N) { + MVT RVT = N->getValueType(0); + RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(LC, RVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) { + MVT RVT = N->getValueType(0); + RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); + SDValue Op = GetSoftenedFloat(N->getOperand(0)); + return MakeLibCall(LC, RVT, &Op, 1, false); +} + +SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) { + SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); ISD::CondCode CCCode = cast(N->getOperand(4))->get(); SoftenSetCCOperands(NewLHS, NewRHS, CCCode); // If SoftenSetCCOperands returned a scalar, we need to compare the result // against zero to select between true and false values. - if (NewRHS.Val == 0) { + if (NewRHS.getNode() == 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, + return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, N->getOperand(2), N->getOperand(3), DAG.getCondCode(CCCode)); } -SDOperand DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) { - SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); +SDValue DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) { + SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); ISD::CondCode CCCode = cast(N->getOperand(2))->get(); SoftenSetCCOperands(NewLHS, NewRHS, CCCode); // If SoftenSetCCOperands returned a scalar, use it. - if (NewRHS.Val == 0) { + if (NewRHS.getNode() == 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, + return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, DAG.getCondCode(CCCode)); } +SDValue 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); + SDValue 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 @@ -507,8 +529,8 @@ SDOperand DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) { /// know that (at least) one result needs expansion. void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { DEBUG(cerr << "Expand float result: "; N->dump(&DAG); cerr << "\n"); - SDOperand Lo, Hi; - Lo = Hi = SDOperand(); + SDValue Lo, Hi; + Lo = Hi = SDValue(); // See if the target wants to custom expand this node. if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) == @@ -542,9 +564,12 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break; + case ISD::FABS: ExpandFloatRes_FABS(N, Lo, Hi); break; case ISD::FADD: ExpandFloatRes_FADD(N, Lo, Hi); break; case ISD::FDIV: ExpandFloatRes_FDIV(N, Lo, Hi); break; case ISD::FMUL: ExpandFloatRes_FMUL(N, Lo, Hi); break; + case ISD::FNEG: ExpandFloatRes_FNEG(N, Lo, Hi); break; + case ISD::FP_EXTEND: ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break; case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break; case ISD::LOAD: ExpandFloatRes_LOAD(N, Lo, Hi); break; case ISD::SINT_TO_FP: @@ -552,80 +577,107 @@ void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { } // If Lo/Hi is null, the sub-method took care of registering results etc. - if (Lo.Val) - SetExpandedFloat(SDOperand(N, ResNo), Lo, Hi); + if (Lo.getNode()) + SetExpandedFloat(SDValue(N, ResNo), Lo, Hi); } -void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDOperand &Lo, - SDOperand &Hi) { +void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo, + SDValue &Hi) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); assert(NVT.getSizeInBits() == integerPartWidth && "Do not know how to expand this float constant!"); - APInt C = cast(N)->getValueAPF().convertToAPInt(); + APInt C = cast(N)->getValueAPF().bitcastToAPInt(); Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, &C.getRawData()[1])), NVT); Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, &C.getRawData()[0])), NVT); } -void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDOperand &Lo, - SDOperand &Hi) { - SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) }; - SDOperand Call = MakeLibCall(GetFPLibCall(N->getValueType(0), +void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; + SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), RTLIB::ADD_F32, RTLIB::ADD_F64, RTLIB::ADD_F80, RTLIB::ADD_PPCF128), N->getValueType(0), Ops, 2, false); - assert(Call.Val->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); + assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); Lo = Call.getOperand(0); Hi = Call.getOperand(1); } -void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDOperand &Lo, - SDOperand &Hi) { - SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) }; - SDOperand Call = MakeLibCall(GetFPLibCall(N->getValueType(0), +void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo, + SDValue &Hi) { + assert(N->getValueType(0) == MVT::ppcf128 && + "Logic only correct for ppcf128!"); + SDValue Tmp; + GetExpandedFloat(N->getOperand(0), Lo, Tmp); + Hi = DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp); + // Lo = Hi==fabs(Hi) ? Lo : -Lo; + Lo = DAG.getNode(ISD::SELECT_CC, Lo.getValueType(), Tmp, Hi, Lo, + DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo), + DAG.getCondCode(ISD::SETEQ)); +} + +void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; + SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), RTLIB::DIV_F32, RTLIB::DIV_F64, RTLIB::DIV_F80, RTLIB::DIV_PPCF128), N->getValueType(0), Ops, 2, false); - assert(Call.Val->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); + assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); Lo = Call.getOperand(0); Hi = Call.getOperand(1); } -void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDOperand &Lo, - SDOperand &Hi) { - SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) }; - SDOperand Call = MakeLibCall(GetFPLibCall(N->getValueType(0), +void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; + SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), RTLIB::MUL_F32, RTLIB::MUL_F64, RTLIB::MUL_F80, RTLIB::MUL_PPCF128), N->getValueType(0), Ops, 2, false); - assert(Call.Val->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); + assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); Lo = Call.getOperand(0); Hi = Call.getOperand(1); } -void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDOperand &Lo, - SDOperand &Hi) { - SDOperand Ops[2] = { N->getOperand(0), N->getOperand(1) }; - SDOperand Call = MakeLibCall(GetFPLibCall(N->getValueType(0), +void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo, + SDValue &Hi) { + GetExpandedFloat(N->getOperand(0), Lo, Hi); + Lo = DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo); + Hi = DAG.getNode(ISD::FNEG, Hi.getValueType(), Hi); +} + +void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo, + SDValue &Hi) { + MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + Hi = DAG.getNode(ISD::FP_EXTEND, NVT, N->getOperand(0)); + Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); +} + +void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo, + SDValue &Hi) { + SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; + SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), RTLIB::SUB_F32, RTLIB::SUB_F64, RTLIB::SUB_F80, RTLIB::SUB_PPCF128), N->getValueType(0), Ops, 2, false); - assert(Call.Val->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); + assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); Lo = Call.getOperand(0); Hi = Call.getOperand(1); } -void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDOperand &Lo, - SDOperand &Hi) { +void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo, + SDValue &Hi) { if (ISD::isNormalLoad(N)) { ExpandRes_NormalLoad(N, Lo, Hi); return; @@ -633,8 +685,8 @@ void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDOperand &Lo, assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!"); LoadSDNode *LD = cast(N); - SDOperand Chain = LD->getChain(); - SDOperand Ptr = LD->getBasePtr(); + SDValue Chain = LD->getChain(); + SDValue Ptr = LD->getBasePtr(); MVT NVT = TLI.getTypeToTransformTo(LD->getValueType(0)); assert(NVT.isByteSized() && "Expanded type not byte sized!"); @@ -653,15 +705,15 @@ void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDOperand &Lo, // Modified the chain - switch anything that used the old chain to use the // new one. - ReplaceValueWith(SDOperand(LD, 1), Chain); + ReplaceValueWith(SDValue(LD, 1), Chain); } -void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDOperand &Lo, - SDOperand &Hi) { +void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, + SDValue &Hi) { assert(N->getValueType(0) == MVT::ppcf128 && "Unsupported XINT_TO_FP!"); MVT VT = N->getValueType(0); MVT NVT = TLI.getTypeToTransformTo(VT); - SDOperand Src = N->getOperand(0); + SDValue Src = N->getOperand(0); MVT SrcVT = Src.getValueType(); // First do an SINT_TO_FP, whether the original was signed or unsigned. @@ -682,7 +734,7 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDOperand &Lo, assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!"); Hi = MakeLibCall(LC, VT, &Src, 1, true); - assert(Hi.Val->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); + assert(Hi.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); Lo = Hi.getOperand(0); Hi = Hi.getOperand(1); } @@ -715,10 +767,8 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDOperand &Lo, MVT::ppcf128)); Lo = DAG.getNode(ISD::SELECT_CC, VT, Src, DAG.getConstant(0, SrcVT), Lo, Hi, DAG.getCondCode(ISD::SETLT)); - Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, - DAG.getConstant(1, TLI.getPointerTy())); - Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, - DAG.getConstant(0, TLI.getPointerTy())); + Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, DAG.getIntPtrConstant(1)); + Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, DAG.getIntPtrConstant(0)); } @@ -732,13 +782,13 @@ 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); + SDValue Res = SDValue(); if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) == TargetLowering::Custom) - Res = TLI.LowerOperation(SDOperand(N, OpNo), DAG); + Res = TLI.LowerOperation(SDValue(N, OpNo), DAG); - if (Res.Val == 0) { + if (Res.getNode() == 0) { switch (N->getOpcode()) { default: #ifndef NDEBUG @@ -752,25 +802,22 @@ bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) { case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; - case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(N); break; - case ISD::SELECT_CC: Res = ExpandFloatOp_SELECT_CC(N); break; - case ISD::SETCC: Res = ExpandFloatOp_SETCC(N); break; - + case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(N); break; case ISD::FP_ROUND: Res = ExpandFloatOp_FP_ROUND(N); break; case ISD::FP_TO_SINT: Res = ExpandFloatOp_FP_TO_SINT(N); break; case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_UINT(N); break; - - case ISD::STORE: - Res = ExpandFloatOp_STORE(cast(N), OpNo); - break; + case ISD::SELECT_CC: Res = ExpandFloatOp_SELECT_CC(N); break; + case ISD::SETCC: Res = ExpandFloatOp_SETCC(N); break; + case ISD::STORE: Res = ExpandFloatOp_STORE(cast(N), + OpNo); break; } } // If the result is null, the sub-method took care of registering results etc. - if (!Res.Val) return false; + if (!Res.getNode()) return false; // If the result is N, the sub-method updated N in place. Check to see if any // operands are new, and if so, mark them. - if (Res.Val == N) { + if (Res.getNode() == N) { // Mark N as new and remark N and its operands. This allows us to correctly // revisit N if it needs another step of expansion and allows us to visit // any new operands to N. @@ -781,16 +828,16 @@ bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) { assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && "Invalid operand expansion"); - ReplaceValueWith(SDOperand(N, 0), Res); + ReplaceValueWith(SDValue(N, 0), Res); return false; } /// FloatExpandSetCCOperands - Expand the operands of a comparison. This code /// is shared among BR_CC, SELECT_CC, and SETCC handlers. -void DAGTypeLegalizer::FloatExpandSetCCOperands(SDOperand &NewLHS, - SDOperand &NewRHS, +void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS, + SDValue &NewRHS, ISD::CondCode &CCCode) { - SDOperand LHSLo, LHSHi, RHSLo, RHSHi; + SDValue LHSLo, LHSHi, RHSLo, RHSHi; GetExpandedFloat(NewLHS, LHSLo, LHSHi); GetExpandedFloat(NewRHS, RHSLo, RHSHi); @@ -802,7 +849,7 @@ void DAGTypeLegalizer::FloatExpandSetCCOperands(SDOperand &NewLHS, // BNE crN, L: // FCMP crN, lo1, lo2 // The following can be improved, but not that much. - SDOperand Tmp1, Tmp2, Tmp3; + SDValue Tmp1, Tmp2, Tmp3; Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, ISD::SETEQ); Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, CCCode); Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); @@ -810,115 +857,86 @@ void DAGTypeLegalizer::FloatExpandSetCCOperands(SDOperand &NewLHS, Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, CCCode); Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3); - NewRHS = SDOperand(); // LHS is the result, not a compare. + NewRHS = SDValue(); // LHS is the result, not a compare. } -SDOperand DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) { - SDOperand NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); +SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) { + SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); ISD::CondCode CCCode = cast(N->getOperand(1))->get(); FloatExpandSetCCOperands(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) { + if (NewRHS.getNode() == 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), + return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), DAG.getCondCode(CCCode), NewLHS, NewRHS, N->getOperand(4)); } -SDOperand DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) { - SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); +SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) { + assert(N->getOperand(0).getValueType() == MVT::ppcf128 && + "Logic only correct for ppcf128!"); + SDValue Lo, Hi; + GetExpandedFloat(N->getOperand(0), Lo, Hi); + // Round it the rest of the way (e.g. to f32) if needed. + return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Hi, N->getOperand(1)); +} + +SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { + MVT RVT = N->getValueType(0); + RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); + return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false); +} + +SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { + MVT RVT = N->getValueType(0); + RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); + return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false); +} + +SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) { + SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); ISD::CondCode CCCode = cast(N->getOperand(4))->get(); FloatExpandSetCCOperands(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) { + if (NewRHS.getNode() == 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, + return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, N->getOperand(2), N->getOperand(3), DAG.getCondCode(CCCode)); } -SDOperand DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) { - SDOperand NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); +SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) { + SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); ISD::CondCode CCCode = cast(N->getOperand(2))->get(); FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode); // If ExpandSetCCOperands returned a scalar, use it. - if (NewRHS.Val == 0) { + if (NewRHS.getNode() == 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, + return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, DAG.getCondCode(CCCode)); } -SDOperand DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { - assert(N->getOperand(0).getValueType() == MVT::ppcf128 && - "Unsupported FP_TO_UINT!"); - - RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; - switch (N->getValueType(0).getSimpleVT()) { - default: - assert(false && "Unsupported FP_TO_UINT!"); - case MVT::i32: - LC = RTLIB::FPTOUINT_PPCF128_I32; - break; - case MVT::i64: - LC = RTLIB::FPTOUINT_PPCF128_I64; - break; - case MVT::i128: - LC = RTLIB::FPTOUINT_PPCF128_I128; - break; - } - - return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false); -} - -SDOperand DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { - assert(N->getOperand(0).getValueType() == MVT::ppcf128 && - "Unsupported FP_TO_SINT!"); - - RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; - switch (N->getValueType(0).getSimpleVT()) { - default: - assert(false && "Unsupported FP_TO_SINT!"); - case MVT::i32: - LC = RTLIB::FPTOSINT_PPCF128_I32; - case MVT::i64: - LC = RTLIB::FPTOSINT_PPCF128_I64; - break; - case MVT::i128: - LC = RTLIB::FPTOSINT_PPCF128_I64; - break; - } - - return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false); -} - -SDOperand DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) { - assert(N->getOperand(0).getValueType() == MVT::ppcf128 && - "Logic only correct for ppcf128!"); - SDOperand Lo, Hi; - GetExpandedFloat(N->getOperand(0), Lo, Hi); - // Round it the rest of the way (e.g. to f32) if needed. - return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Hi, N->getOperand(1)); -} - -SDOperand DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) { +SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) { if (ISD::isNormalStore(N)) return ExpandOp_NormalStore(N, OpNo); @@ -926,14 +944,14 @@ SDOperand DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) { assert(OpNo == 1 && "Can only expand the stored value so far"); StoreSDNode *ST = cast(N); - SDOperand Chain = ST->getChain(); - SDOperand Ptr = ST->getBasePtr(); + SDValue Chain = ST->getChain(); + SDValue Ptr = ST->getBasePtr(); MVT NVT = TLI.getTypeToTransformTo(ST->getValue().getValueType()); assert(NVT.isByteSized() && "Expanded type not byte sized!"); assert(ST->getMemoryVT().bitsLE(NVT) && "Float type not round?"); - SDOperand Lo, Hi; + SDValue Lo, Hi; GetExpandedOp(ST->getValue(), Lo, Hi); return DAG.getTruncStore(Chain, Lo, Ptr,