LegalizeFloatTypes.cpp revision 198090
1193323Sed//===-------- LegalizeFloatTypes.cpp - Legalization of float types --------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file implements float type expansion and softening for LegalizeTypes. 11193323Sed// Softening is the act of turning a computation in an illegal floating point 12193323Sed// type into a computation in an integer type of the same size; also known as 13193323Sed// "soft float". For example, turning f32 arithmetic into operations using i32. 14193323Sed// The resulting integer value is the same as what you would get by performing 15193323Sed// the floating point operation and bitcasting the result to the integer type. 16249423Sdim// Expansion is the act of changing a computation in an illegal type to be a 17249423Sdim// computation in two identical registers of a smaller type. For example, 18249423Sdim// implementing ppcf128 arithmetic in two f64 registers. 19249423Sdim// 20249423Sdim//===----------------------------------------------------------------------===// 21276479Sdim 22249423Sdim#include "LegalizeTypes.h" 23249423Sdim#include "llvm/Support/ErrorHandling.h" 24193323Sed#include "llvm/Support/raw_ostream.h" 25193323Sedusing namespace llvm; 26193323Sed 27218885Sdim/// GetFPLibCall - Return the right libcall for the given floating point type. 28218885Sdimstatic RTLIB::Libcall GetFPLibCall(EVT VT, 29249423Sdim RTLIB::Libcall Call_F32, 30249423Sdim RTLIB::Libcall Call_F64, 31249423Sdim RTLIB::Libcall Call_F80, 32249423Sdim RTLIB::Libcall Call_PPCF128) { 33249423Sdim return 34193323Sed VT == MVT::f32 ? Call_F32 : 35193323Sed VT == MVT::f64 ? Call_F64 : 36193323Sed VT == MVT::f80 ? Call_F80 : 37276479Sdim VT == MVT::ppcf128 ? Call_PPCF128 : 38276479Sdim RTLIB::UNKNOWN_LIBCALL; 39193323Sed} 40193323Sed 41198090Srdivacky//===----------------------------------------------------------------------===// 42193323Sed// Result Float to Integer Conversion. 43193323Sed//===----------------------------------------------------------------------===// 44193323Sed 45193323Sedvoid DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) { 46193323Sed DEBUG(errs() << "Soften float result " << ResNo << ": "; N->dump(&DAG); 47193323Sed errs() << "\n"); 48193323Sed SDValue R = SDValue(); 49193323Sed 50193323Sed switch (N->getOpcode()) { 51193323Sed default: 52234353Sdim#ifndef NDEBUG 53234353Sdim errs() << "SoftenFloatResult #" << ResNo << ": "; 54276479Sdim N->dump(&DAG); errs() << "\n"; 55234353Sdim#endif 56234353Sdim llvm_unreachable("Do not know how to soften the result of this operator!"); 57234353Sdim 58234353Sdim case ISD::BIT_CONVERT: R = SoftenFloatRes_BIT_CONVERT(N); break; 59234353Sdim case ISD::BUILD_PAIR: R = SoftenFloatRes_BUILD_PAIR(N); break; 60234353Sdim case ISD::ConstantFP: 61234353Sdim R = SoftenFloatRes_ConstantFP(cast<ConstantFPSDNode>(N)); 62234353Sdim break; 63234353Sdim case ISD::EXTRACT_VECTOR_ELT: 64234353Sdim R = SoftenFloatRes_EXTRACT_VECTOR_ELT(N); break; 65234353Sdim case ISD::FABS: R = SoftenFloatRes_FABS(N); break; 66234353Sdim case ISD::FADD: R = SoftenFloatRes_FADD(N); break; 67234353Sdim case ISD::FCEIL: R = SoftenFloatRes_FCEIL(N); break; 68234353Sdim case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break; 69234353Sdim case ISD::FCOS: R = SoftenFloatRes_FCOS(N); break; 70234353Sdim case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break; 71234353Sdim case ISD::FEXP: R = SoftenFloatRes_FEXP(N); break; 72234353Sdim case ISD::FEXP2: R = SoftenFloatRes_FEXP2(N); break; 73234353Sdim case ISD::FFLOOR: R = SoftenFloatRes_FFLOOR(N); break; 74234353Sdim case ISD::FLOG: R = SoftenFloatRes_FLOG(N); break; 75234353Sdim case ISD::FLOG2: R = SoftenFloatRes_FLOG2(N); break; 76234353Sdim case ISD::FLOG10: R = SoftenFloatRes_FLOG10(N); break; 77234353Sdim case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break; 78234353Sdim case ISD::FNEARBYINT: R = SoftenFloatRes_FNEARBYINT(N); break; 79234353Sdim case ISD::FNEG: R = SoftenFloatRes_FNEG(N); break; 80234353Sdim case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break; 81276479Sdim case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break; 82234353Sdim case ISD::FPOW: R = SoftenFloatRes_FPOW(N); break; 83234353Sdim case ISD::FPOWI: R = SoftenFloatRes_FPOWI(N); break; 84234353Sdim case ISD::FREM: R = SoftenFloatRes_FREM(N); break; 85280031Sdim case ISD::FRINT: R = SoftenFloatRes_FRINT(N); break; 86280031Sdim case ISD::FSIN: R = SoftenFloatRes_FSIN(N); break; 87280031Sdim case ISD::FSQRT: R = SoftenFloatRes_FSQRT(N); break; 88212793Sdim case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break; 89212793Sdim case ISD::FTRUNC: R = SoftenFloatRes_FTRUNC(N); break; 90193323Sed case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break; 91193323Sed case ISD::SELECT: R = SoftenFloatRes_SELECT(N); break; 92193323Sed case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N); break; 93193323Sed case ISD::SINT_TO_FP: 94212793Sdim case ISD::UINT_TO_FP: R = SoftenFloatRes_XINT_TO_FP(N); break; 95193323Sed case ISD::UNDEF: R = SoftenFloatRes_UNDEF(N); break; 96193323Sed case ISD::VAARG: R = SoftenFloatRes_VAARG(N); break; 97193323Sed } 98193323Sed 99193323Sed // If R is null, the sub-method took care of registering the result. 100193323Sed if (R.getNode()) 101193323Sed SetSoftenedFloat(SDValue(N, ResNo), R); 102193323Sed} 103193323Sed 104193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_BIT_CONVERT(SDNode *N) { 105193323Sed return BitConvertToInteger(N->getOperand(0)); 106210006Srdivacky} 107193323Sed 108193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) { 109193323Sed // Convert the inputs to integers, and build a new pair out of them. 110193323Sed return DAG.getNode(ISD::BUILD_PAIR, N->getDebugLoc(), 111193323Sed TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)), 112193323Sed BitConvertToInteger(N->getOperand(0)), 113212793Sdim BitConvertToInteger(N->getOperand(1))); 114193323Sed} 115212793Sdim 116193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(ConstantFPSDNode *N) { 117212793Sdim return DAG.getConstant(N->getValueAPF().bitcastToAPInt(), 118193323Sed TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0))); 119212793Sdim} 120193323Sed 121212793SdimSDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N) { 122280031Sdim SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0)); 123212793Sdim return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N->getDebugLoc(), 124212793Sdim NewOp.getValueType().getVectorElementType(), 125212793Sdim NewOp, N->getOperand(1)); 126212793Sdim} 127212793Sdim 128212793SdimSDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) { 129193323Sed EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 130193323Sed unsigned Size = NVT.getSizeInBits(); 131280031Sdim 132280031Sdim // Mask = ~(1 << (Size-1)) 133193323Sed SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1), 134193323Sed NVT); 135193323Sed SDValue Op = GetSoftenedFloat(N->getOperand(0)); 136193323Sed return DAG.getNode(ISD::AND, N->getDebugLoc(), NVT, Op, Mask); 137212793Sdim} 138212793Sdim 139193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) { 140193323Sed EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 141212793Sdim SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 142193323Sed GetSoftenedFloat(N->getOperand(1)) }; 143212793Sdim return MakeLibCall(GetFPLibCall(N->getValueType(0), 144193323Sed RTLIB::ADD_F32, 145280031Sdim RTLIB::ADD_F64, 146276479Sdim RTLIB::ADD_F80, 147198090Srdivacky RTLIB::ADD_PPCF128), 148280031Sdim NVT, Ops, 2, false, N->getDebugLoc()); 149193323Sed} 150193323Sed 151193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) { 152193323Sed EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 153193323Sed SDValue Op = GetSoftenedFloat(N->getOperand(0)); 154280031Sdim return MakeLibCall(GetFPLibCall(N->getValueType(0), 155212793Sdim RTLIB::CEIL_F32, 156212793Sdim RTLIB::CEIL_F64, 157193323Sed RTLIB::CEIL_F80, 158280031Sdim RTLIB::CEIL_PPCF128), 159276479Sdim NVT, &Op, 1, false, N->getDebugLoc()); 160198090Srdivacky} 161212793Sdim 162198090SrdivackySDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { 163276479Sdim SDValue LHS = GetSoftenedFloat(N->getOperand(0)); 164193323Sed SDValue RHS = BitConvertToInteger(N->getOperand(1)); 165193323Sed DebugLoc dl = N->getDebugLoc(); 166193323Sed 167193323Sed EVT LVT = LHS.getValueType(); 168193323Sed EVT RVT = RHS.getValueType(); 169193323Sed 170193323Sed unsigned LSize = LVT.getSizeInBits(); 171276479Sdim unsigned RSize = RVT.getSizeInBits(); 172193323Sed 173193323Sed // First get the sign bit of second operand. 174193323Sed SDValue SignBit = DAG.getNode(ISD::SHL, dl, RVT, DAG.getConstant(1, RVT), 175193323Sed DAG.getConstant(RSize - 1, 176193323Sed TLI.getShiftAmountTy())); 177193323Sed SignBit = DAG.getNode(ISD::AND, dl, RVT, RHS, SignBit); 178193323Sed 179193323Sed // Shift right or sign-extend it if the two operands have different types. 180193323Sed int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits(); 181193323Sed if (SizeDiff > 0) { 182193323Sed SignBit = DAG.getNode(ISD::SRL, dl, RVT, SignBit, 183193323Sed DAG.getConstant(SizeDiff, TLI.getShiftAmountTy())); 184193323Sed SignBit = DAG.getNode(ISD::TRUNCATE, dl, LVT, SignBit); 185193323Sed } else if (SizeDiff < 0) { 186193323Sed SignBit = DAG.getNode(ISD::ANY_EXTEND, dl, LVT, SignBit); 187193323Sed SignBit = DAG.getNode(ISD::SHL, dl, LVT, SignBit, 188193323Sed DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy())); 189193323Sed } 190193323Sed 191193323Sed // Clear the sign bit of the first operand. 192193323Sed SDValue Mask = DAG.getNode(ISD::SHL, dl, LVT, DAG.getConstant(1, LVT), 193193323Sed DAG.getConstant(LSize - 1, 194193323Sed TLI.getShiftAmountTy())); 195193323Sed Mask = DAG.getNode(ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, LVT)); 196193323Sed LHS = DAG.getNode(ISD::AND, dl, LVT, LHS, Mask); 197224133Sdim 198224133Sdim // Or the value with the sign bit. 199226584Sdim return DAG.getNode(ISD::OR, dl, LVT, LHS, SignBit); 200224133Sdim} 201193323Sed 202224133SdimSDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) { 203224133Sdim EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 204224133Sdim SDValue Op = GetSoftenedFloat(N->getOperand(0)); 205224133Sdim return MakeLibCall(GetFPLibCall(N->getValueType(0), 206224133Sdim RTLIB::COS_F32, 207193323Sed RTLIB::COS_F64, 208193323Sed RTLIB::COS_F80, 209193323Sed RTLIB::COS_PPCF128), 210193323Sed NVT, &Op, 1, false, N->getDebugLoc()); 211193323Sed} 212193323Sed 213193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) { 214193323Sed EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 215193323Sed SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 216193323Sed GetSoftenedFloat(N->getOperand(1)) }; 217193323Sed return MakeLibCall(GetFPLibCall(N->getValueType(0), 218218885Sdim RTLIB::DIV_F32, 219193323Sed RTLIB::DIV_F64, 220193323Sed RTLIB::DIV_F80, 221193323Sed RTLIB::DIV_PPCF128), 222193323Sed NVT, Ops, 2, false, N->getDebugLoc()); 223193323Sed} 224193323Sed 225193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) { 226193323Sed EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 227193323Sed SDValue Op = GetSoftenedFloat(N->getOperand(0)); 228193323Sed return MakeLibCall(GetFPLibCall(N->getValueType(0), 229193323Sed RTLIB::EXP_F32, 230193323Sed RTLIB::EXP_F64, 231193323Sed RTLIB::EXP_F80, 232193323Sed RTLIB::EXP_PPCF128), 233193323Sed NVT, &Op, 1, false, N->getDebugLoc()); 234193323Sed} 235193323Sed 236193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) { 237193323Sed EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 238193323Sed SDValue Op = GetSoftenedFloat(N->getOperand(0)); 239193323Sed return MakeLibCall(GetFPLibCall(N->getValueType(0), 240193323Sed RTLIB::EXP2_F32, 241193323Sed RTLIB::EXP2_F64, 242193323Sed RTLIB::EXP2_F80, 243193323Sed RTLIB::EXP2_PPCF128), 244193323Sed NVT, &Op, 1, false, N->getDebugLoc()); 245193323Sed} 246210006Srdivacky 247193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) { 248193323Sed EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 249193323Sed SDValue Op = GetSoftenedFloat(N->getOperand(0)); 250193323Sed return MakeLibCall(GetFPLibCall(N->getValueType(0), 251193323Sed RTLIB::FLOOR_F32, 252193323Sed RTLIB::FLOOR_F64, 253193323Sed RTLIB::FLOOR_F80, 254193323Sed RTLIB::FLOOR_PPCF128), 255193323Sed NVT, &Op, 1, false, N->getDebugLoc()); 256198090Srdivacky} 257198090Srdivacky 258198090SrdivackySDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) { 259193323Sed EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 260193323Sed SDValue Op = GetSoftenedFloat(N->getOperand(0)); 261193323Sed return MakeLibCall(GetFPLibCall(N->getValueType(0), 262193323Sed RTLIB::LOG_F32, 263193323Sed RTLIB::LOG_F64, 264193323Sed RTLIB::LOG_F80, 265193323Sed RTLIB::LOG_PPCF128), 266193323Sed NVT, &Op, 1, false, N->getDebugLoc()); 267193323Sed} 268198090Srdivacky 269198090SrdivackySDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) { 270198090Srdivacky EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 271193323Sed SDValue Op = GetSoftenedFloat(N->getOperand(0)); 272193323Sed return MakeLibCall(GetFPLibCall(N->getValueType(0), 273193323Sed RTLIB::LOG2_F32, 274193323Sed RTLIB::LOG2_F64, 275193323Sed RTLIB::LOG2_F80, 276193323Sed RTLIB::LOG2_PPCF128), 277193323Sed NVT, &Op, 1, false, N->getDebugLoc()); 278193323Sed} 279193323Sed 280193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) { 281218885Sdim EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 282193323Sed SDValue Op = GetSoftenedFloat(N->getOperand(0)); 283193323Sed return MakeLibCall(GetFPLibCall(N->getValueType(0), 284193323Sed RTLIB::LOG10_F32, 285193323Sed RTLIB::LOG10_F64, 286193323Sed RTLIB::LOG10_F80, 287193323Sed RTLIB::LOG10_PPCF128), 288198090Srdivacky NVT, &Op, 1, false, N->getDebugLoc()); 289198090Srdivacky} 290193323Sed 291193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { 292193323Sed EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 293218885Sdim SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 294210006Srdivacky GetSoftenedFloat(N->getOperand(1)) }; 295193323Sed return MakeLibCall(GetFPLibCall(N->getValueType(0), 296193323Sed RTLIB::MUL_F32, 297193323Sed RTLIB::MUL_F64, 298193323Sed RTLIB::MUL_F80, 299210006Srdivacky RTLIB::MUL_PPCF128), 300198090Srdivacky NVT, Ops, 2, false, N->getDebugLoc()); 301276479Sdim} 302198090Srdivacky 303210006SrdivackySDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) { 304193323Sed EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 305193323Sed SDValue Op = GetSoftenedFloat(N->getOperand(0)); 306193323Sed return MakeLibCall(GetFPLibCall(N->getValueType(0), 307193323Sed RTLIB::NEARBYINT_F32, 308193323Sed RTLIB::NEARBYINT_F64, 309193323Sed RTLIB::NEARBYINT_F80, 310193323Sed RTLIB::NEARBYINT_PPCF128), 311193323Sed NVT, &Op, 1, false, N->getDebugLoc()); 312193323Sed} 313193323Sed 314234353SdimSDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) { 315234353Sdim EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 316234353Sdim // Expand Y = FNEG(X) -> Y = SUB -0.0, X 317234353Sdim SDValue Ops[2] = { DAG.getConstantFP(-0.0, N->getValueType(0)), 318234353Sdim GetSoftenedFloat(N->getOperand(0)) }; 319234353Sdim return MakeLibCall(GetFPLibCall(N->getValueType(0), 320234353Sdim RTLIB::SUB_F32, 321234353Sdim RTLIB::SUB_F64, 322276479Sdim RTLIB::SUB_F80, 323234353Sdim RTLIB::SUB_PPCF128), 324234353Sdim NVT, Ops, 2, false, N->getDebugLoc()); 325234353Sdim} 326234353Sdim 327234353SdimSDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) { 328276479Sdim EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 329234353Sdim SDValue Op = N->getOperand(0); 330234353Sdim RTLIB::Libcall LC = RTLIB::getFPEXT(Op.getValueType(), N->getValueType(0)); 331276479Sdim assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!"); 332234353Sdim return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc()); 333234353Sdim} 334234353Sdim 335193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) { 336193323Sed EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 337210006Srdivacky SDValue Op = N->getOperand(0); 338210006Srdivacky RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), N->getValueType(0)); 339193323Sed assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND!"); 340193323Sed return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc()); 341193323Sed} 342193323Sed 343193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) { 344193323Sed EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 345193323Sed SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 346193323Sed GetSoftenedFloat(N->getOperand(1)) }; 347280031Sdim return MakeLibCall(GetFPLibCall(N->getValueType(0), 348280031Sdim RTLIB::POW_F32, 349280031Sdim RTLIB::POW_F64, 350261991Sdim RTLIB::POW_F80, 351261991Sdim RTLIB::POW_PPCF128), 352276479Sdim NVT, Ops, 2, false, N->getDebugLoc()); 353261991Sdim} 354261991Sdim 355198090SrdivackySDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) { 356261991Sdim assert(N->getOperand(1).getValueType() == MVT::i32 && 357212793Sdim "Unsupported power type!"); 358276479Sdim EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 359193323Sed SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), N->getOperand(1) }; 360261991Sdim return MakeLibCall(GetFPLibCall(N->getValueType(0), 361193323Sed RTLIB::POWI_F32, 362261991Sdim RTLIB::POWI_F64, 363193323Sed RTLIB::POWI_F80, 364193323Sed RTLIB::POWI_PPCF128), 365193323Sed NVT, Ops, 2, false, N->getDebugLoc()); 366193323Sed} 367193323Sed 368193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_FREM(SDNode *N) { 369234353Sdim EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 370212793Sdim SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 371193323Sed GetSoftenedFloat(N->getOperand(1)) }; 372212793Sdim return MakeLibCall(GetFPLibCall(N->getValueType(0), 373212793Sdim RTLIB::REM_F32, 374261991Sdim RTLIB::REM_F64, 375212793Sdim RTLIB::REM_F80, 376212793Sdim RTLIB::REM_PPCF128), 377276479Sdim NVT, Ops, 2, false, N->getDebugLoc()); 378212793Sdim} 379212793Sdim 380193323SedSDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) { 381261991Sdim EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 382261991Sdim SDValue Op = GetSoftenedFloat(N->getOperand(0)); 383203954Srdivacky return MakeLibCall(GetFPLibCall(N->getValueType(0), 384193323Sed RTLIB::RINT_F32, 385212793Sdim RTLIB::RINT_F64, 386212793Sdim RTLIB::RINT_F80, 387280031Sdim RTLIB::RINT_PPCF128), 388193323Sed NVT, &Op, 1, false, N->getDebugLoc()); 389261991Sdim} 390193323Sed 391276479SdimSDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) { 392198090Srdivacky EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 393212793Sdim SDValue Op = GetSoftenedFloat(N->getOperand(0)); 394193323Sed return MakeLibCall(GetFPLibCall(N->getValueType(0), 395193323Sed RTLIB::SIN_F32, 396193323Sed RTLIB::SIN_F64, 397 RTLIB::SIN_F80, 398 RTLIB::SIN_PPCF128), 399 NVT, &Op, 1, false, N->getDebugLoc()); 400} 401 402SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) { 403 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 404 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 405 return MakeLibCall(GetFPLibCall(N->getValueType(0), 406 RTLIB::SQRT_F32, 407 RTLIB::SQRT_F64, 408 RTLIB::SQRT_F80, 409 RTLIB::SQRT_PPCF128), 410 NVT, &Op, 1, false, N->getDebugLoc()); 411} 412 413SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) { 414 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 415 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 416 GetSoftenedFloat(N->getOperand(1)) }; 417 return MakeLibCall(GetFPLibCall(N->getValueType(0), 418 RTLIB::SUB_F32, 419 RTLIB::SUB_F64, 420 RTLIB::SUB_F80, 421 RTLIB::SUB_PPCF128), 422 NVT, Ops, 2, false, N->getDebugLoc()); 423} 424 425SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) { 426 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 427 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 428 return MakeLibCall(GetFPLibCall(N->getValueType(0), 429 RTLIB::TRUNC_F32, 430 RTLIB::TRUNC_F64, 431 RTLIB::TRUNC_F80, 432 RTLIB::TRUNC_PPCF128), 433 NVT, &Op, 1, false, N->getDebugLoc()); 434} 435 436SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { 437 LoadSDNode *L = cast<LoadSDNode>(N); 438 EVT VT = N->getValueType(0); 439 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 440 DebugLoc dl = N->getDebugLoc(); 441 442 SDValue NewL; 443 if (L->getExtensionType() == ISD::NON_EXTLOAD) { 444 NewL = DAG.getLoad(L->getAddressingMode(), dl, L->getExtensionType(), 445 NVT, L->getChain(), L->getBasePtr(), L->getOffset(), 446 L->getSrcValue(), L->getSrcValueOffset(), NVT, 447 L->isVolatile(), L->getAlignment()); 448 // Legalized the chain result - switch anything that used the old chain to 449 // use the new one. 450 ReplaceValueWith(SDValue(N, 1), NewL.getValue(1)); 451 return NewL; 452 } 453 454 // Do a non-extending load followed by FP_EXTEND. 455 NewL = DAG.getLoad(L->getAddressingMode(), dl, ISD::NON_EXTLOAD, 456 L->getMemoryVT(), L->getChain(), 457 L->getBasePtr(), L->getOffset(), 458 L->getSrcValue(), L->getSrcValueOffset(), 459 L->getMemoryVT(), 460 L->isVolatile(), L->getAlignment()); 461 // Legalized the chain result - switch anything that used the old chain to 462 // use the new one. 463 ReplaceValueWith(SDValue(N, 1), NewL.getValue(1)); 464 return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, dl, VT, NewL)); 465} 466 467SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N) { 468 SDValue LHS = GetSoftenedFloat(N->getOperand(1)); 469 SDValue RHS = GetSoftenedFloat(N->getOperand(2)); 470 return DAG.getNode(ISD::SELECT, N->getDebugLoc(), 471 LHS.getValueType(), N->getOperand(0),LHS,RHS); 472} 473 474SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N) { 475 SDValue LHS = GetSoftenedFloat(N->getOperand(2)); 476 SDValue RHS = GetSoftenedFloat(N->getOperand(3)); 477 return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), 478 LHS.getValueType(), N->getOperand(0), 479 N->getOperand(1), LHS, RHS, N->getOperand(4)); 480} 481 482SDValue DAGTypeLegalizer::SoftenFloatRes_UNDEF(SDNode *N) { 483 return DAG.getUNDEF(TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0))); 484} 485 486SDValue DAGTypeLegalizer::SoftenFloatRes_VAARG(SDNode *N) { 487 SDValue Chain = N->getOperand(0); // Get the chain. 488 SDValue Ptr = N->getOperand(1); // Get the pointer. 489 EVT VT = N->getValueType(0); 490 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 491 DebugLoc dl = N->getDebugLoc(); 492 493 SDValue NewVAARG; 494 NewVAARG = DAG.getVAArg(NVT, dl, Chain, Ptr, N->getOperand(2)); 495 496 // Legalized the chain result - switch anything that used the old chain to 497 // use the new one. 498 ReplaceValueWith(SDValue(N, 1), NewVAARG.getValue(1)); 499 return NewVAARG; 500} 501 502SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) { 503 bool Signed = N->getOpcode() == ISD::SINT_TO_FP; 504 EVT SVT = N->getOperand(0).getValueType(); 505 EVT RVT = N->getValueType(0); 506 EVT NVT = EVT(); 507 DebugLoc dl = N->getDebugLoc(); 508 509 // If the input is not legal, eg: i1 -> fp, then it needs to be promoted to 510 // a larger type, eg: i8 -> fp. Even if it is legal, no libcall may exactly 511 // match. Look for an appropriate libcall. 512 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 513 for (unsigned t = MVT::FIRST_INTEGER_VALUETYPE; 514 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) { 515 NVT = (MVT::SimpleValueType)t; 516 // The source needs to big enough to hold the operand. 517 if (NVT.bitsGE(SVT)) 518 LC = Signed ? RTLIB::getSINTTOFP(NVT, RVT):RTLIB::getUINTTOFP (NVT, RVT); 519 } 520 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!"); 521 522 // Sign/zero extend the argument if the libcall takes a larger type. 523 SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, 524 NVT, N->getOperand(0)); 525 return MakeLibCall(LC, TLI.getTypeToTransformTo(*DAG.getContext(), RVT), &Op, 1, false, dl); 526} 527 528 529//===----------------------------------------------------------------------===// 530// Operand Float to Integer Conversion.. 531//===----------------------------------------------------------------------===// 532 533bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) { 534 DEBUG(errs() << "Soften float operand " << OpNo << ": "; N->dump(&DAG); 535 errs() << "\n"); 536 SDValue Res = SDValue(); 537 538 switch (N->getOpcode()) { 539 default: 540#ifndef NDEBUG 541 errs() << "SoftenFloatOperand Op #" << OpNo << ": "; 542 N->dump(&DAG); errs() << "\n"; 543#endif 544 llvm_unreachable("Do not know how to soften this operator's operand!"); 545 546 case ISD::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break; 547 case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(N); break; 548 case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break; 549 case ISD::FP_TO_SINT: Res = SoftenFloatOp_FP_TO_SINT(N); break; 550 case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_UINT(N); break; 551 case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break; 552 case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break; 553 case ISD::STORE: Res = SoftenFloatOp_STORE(N, OpNo); break; 554 } 555 556 // If the result is null, the sub-method took care of registering results etc. 557 if (!Res.getNode()) return false; 558 559 // If the result is N, the sub-method updated N in place. Tell the legalizer 560 // core about this. 561 if (Res.getNode() == N) 562 return true; 563 564 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 565 "Invalid operand expansion"); 566 567 ReplaceValueWith(SDValue(N, 0), Res); 568 return false; 569} 570 571/// SoftenSetCCOperands - Soften the operands of a comparison. This code is 572/// shared among BR_CC, SELECT_CC, and SETCC handlers. 573void DAGTypeLegalizer::SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, 574 ISD::CondCode &CCCode, DebugLoc dl) { 575 SDValue LHSInt = GetSoftenedFloat(NewLHS); 576 SDValue RHSInt = GetSoftenedFloat(NewRHS); 577 EVT VT = NewLHS.getValueType(); 578 579 assert((VT == MVT::f32 || VT == MVT::f64) && "Unsupported setcc type!"); 580 581 // Expand into one or more soft-fp libcall(s). 582 RTLIB::Libcall LC1 = RTLIB::UNKNOWN_LIBCALL, LC2 = RTLIB::UNKNOWN_LIBCALL; 583 switch (CCCode) { 584 case ISD::SETEQ: 585 case ISD::SETOEQ: 586 LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64; 587 break; 588 case ISD::SETNE: 589 case ISD::SETUNE: 590 LC1 = (VT == MVT::f32) ? RTLIB::UNE_F32 : RTLIB::UNE_F64; 591 break; 592 case ISD::SETGE: 593 case ISD::SETOGE: 594 LC1 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64; 595 break; 596 case ISD::SETLT: 597 case ISD::SETOLT: 598 LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64; 599 break; 600 case ISD::SETLE: 601 case ISD::SETOLE: 602 LC1 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64; 603 break; 604 case ISD::SETGT: 605 case ISD::SETOGT: 606 LC1 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64; 607 break; 608 case ISD::SETUO: 609 LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64; 610 break; 611 case ISD::SETO: 612 LC1 = (VT == MVT::f32) ? RTLIB::O_F32 : RTLIB::O_F64; 613 break; 614 default: 615 LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64; 616 switch (CCCode) { 617 case ISD::SETONE: 618 // SETONE = SETOLT | SETOGT 619 LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64; 620 // Fallthrough 621 case ISD::SETUGT: 622 LC2 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64; 623 break; 624 case ISD::SETUGE: 625 LC2 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64; 626 break; 627 case ISD::SETULT: 628 LC2 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64; 629 break; 630 case ISD::SETULE: 631 LC2 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64; 632 break; 633 case ISD::SETUEQ: 634 LC2 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64; 635 break; 636 default: assert(false && "Do not know how to soften this setcc!"); 637 } 638 } 639 640 EVT RetVT = MVT::i32; // FIXME: is this the correct return type? 641 SDValue Ops[2] = { LHSInt, RHSInt }; 642 NewLHS = MakeLibCall(LC1, RetVT, Ops, 2, false/*sign irrelevant*/, dl); 643 NewRHS = DAG.getConstant(0, RetVT); 644 CCCode = TLI.getCmpLibcallCC(LC1); 645 if (LC2 != RTLIB::UNKNOWN_LIBCALL) { 646 SDValue Tmp = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(RetVT), 647 NewLHS, NewRHS, DAG.getCondCode(CCCode)); 648 NewLHS = MakeLibCall(LC2, RetVT, Ops, 2, false/*sign irrelevant*/, dl); 649 NewLHS = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(RetVT), NewLHS, 650 NewRHS, DAG.getCondCode(TLI.getCmpLibcallCC(LC2))); 651 NewLHS = DAG.getNode(ISD::OR, dl, Tmp.getValueType(), Tmp, NewLHS); 652 NewRHS = SDValue(); 653 } 654} 655 656SDValue DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) { 657 return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), N->getValueType(0), 658 GetSoftenedFloat(N->getOperand(0))); 659} 660 661SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) { 662 EVT SVT = N->getOperand(0).getValueType(); 663 EVT RVT = N->getValueType(0); 664 665 RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, RVT); 666 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall"); 667 668 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 669 return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc()); 670} 671 672SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) { 673 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); 674 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get(); 675 SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 676 677 // If SoftenSetCCOperands returned a scalar, we need to compare the result 678 // against zero to select between true and false values. 679 if (NewRHS.getNode() == 0) { 680 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 681 CCCode = ISD::SETNE; 682 } 683 684 // Update N to have the operands specified. 685 return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 686 DAG.getCondCode(CCCode), NewLHS, NewRHS, 687 N->getOperand(4)); 688} 689 690SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode *N) { 691 EVT RVT = N->getValueType(0); 692 RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); 693 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); 694 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 695 return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc()); 696} 697 698SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) { 699 EVT RVT = N->getValueType(0); 700 RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); 701 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); 702 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 703 return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc()); 704} 705 706SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) { 707 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 708 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get(); 709 SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 710 711 // If SoftenSetCCOperands returned a scalar, we need to compare the result 712 // against zero to select between true and false values. 713 if (NewRHS.getNode() == 0) { 714 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 715 CCCode = ISD::SETNE; 716 } 717 718 // Update N to have the operands specified. 719 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 720 N->getOperand(2), N->getOperand(3), 721 DAG.getCondCode(CCCode)); 722} 723 724SDValue DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) { 725 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 726 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); 727 SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 728 729 // If SoftenSetCCOperands returned a scalar, use it. 730 if (NewRHS.getNode() == 0) { 731 assert(NewLHS.getValueType() == N->getValueType(0) && 732 "Unexpected setcc expansion!"); 733 return NewLHS; 734 } 735 736 // Otherwise, update N to have the operands specified. 737 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 738 DAG.getCondCode(CCCode)); 739} 740 741SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) { 742 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); 743 assert(OpNo == 1 && "Can only soften the stored value!"); 744 StoreSDNode *ST = cast<StoreSDNode>(N); 745 SDValue Val = ST->getValue(); 746 DebugLoc dl = N->getDebugLoc(); 747 748 if (ST->isTruncatingStore()) 749 // Do an FP_ROUND followed by a non-truncating store. 750 Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, dl, ST->getMemoryVT(), 751 Val, DAG.getIntPtrConstant(0))); 752 else 753 Val = GetSoftenedFloat(Val); 754 755 return DAG.getStore(ST->getChain(), dl, Val, ST->getBasePtr(), 756 ST->getSrcValue(), ST->getSrcValueOffset(), 757 ST->isVolatile(), ST->getAlignment()); 758} 759 760 761//===----------------------------------------------------------------------===// 762// Float Result Expansion 763//===----------------------------------------------------------------------===// 764 765/// ExpandFloatResult - This method is called when the specified result of the 766/// specified node is found to need expansion. At this point, the node may also 767/// have invalid operands or may have other results that need promotion, we just 768/// know that (at least) one result needs expansion. 769void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { 770 DEBUG(errs() << "Expand float result: "; N->dump(&DAG); errs() << "\n"); 771 SDValue Lo, Hi; 772 Lo = Hi = SDValue(); 773 774 // See if the target wants to custom expand this node. 775 if (CustomLowerNode(N, N->getValueType(ResNo), true)) 776 return; 777 778 switch (N->getOpcode()) { 779 default: 780#ifndef NDEBUG 781 errs() << "ExpandFloatResult #" << ResNo << ": "; 782 N->dump(&DAG); errs() << "\n"; 783#endif 784 llvm_unreachable("Do not know how to expand the result of this operator!"); 785 786 case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break; 787 case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; 788 case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; 789 case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; 790 791 case ISD::BIT_CONVERT: ExpandRes_BIT_CONVERT(N, Lo, Hi); break; 792 case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break; 793 case ISD::EXTRACT_ELEMENT: ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break; 794 case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; 795 case ISD::VAARG: ExpandRes_VAARG(N, Lo, Hi); break; 796 797 case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break; 798 case ISD::FABS: ExpandFloatRes_FABS(N, Lo, Hi); break; 799 case ISD::FADD: ExpandFloatRes_FADD(N, Lo, Hi); break; 800 case ISD::FCEIL: ExpandFloatRes_FCEIL(N, Lo, Hi); break; 801 case ISD::FCOS: ExpandFloatRes_FCOS(N, Lo, Hi); break; 802 case ISD::FDIV: ExpandFloatRes_FDIV(N, Lo, Hi); break; 803 case ISD::FEXP: ExpandFloatRes_FEXP(N, Lo, Hi); break; 804 case ISD::FEXP2: ExpandFloatRes_FEXP2(N, Lo, Hi); break; 805 case ISD::FFLOOR: ExpandFloatRes_FFLOOR(N, Lo, Hi); break; 806 case ISD::FLOG: ExpandFloatRes_FLOG(N, Lo, Hi); break; 807 case ISD::FLOG2: ExpandFloatRes_FLOG2(N, Lo, Hi); break; 808 case ISD::FLOG10: ExpandFloatRes_FLOG10(N, Lo, Hi); break; 809 case ISD::FMUL: ExpandFloatRes_FMUL(N, Lo, Hi); break; 810 case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT(N, Lo, Hi); break; 811 case ISD::FNEG: ExpandFloatRes_FNEG(N, Lo, Hi); break; 812 case ISD::FP_EXTEND: ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break; 813 case ISD::FPOW: ExpandFloatRes_FPOW(N, Lo, Hi); break; 814 case ISD::FPOWI: ExpandFloatRes_FPOWI(N, Lo, Hi); break; 815 case ISD::FRINT: ExpandFloatRes_FRINT(N, Lo, Hi); break; 816 case ISD::FSIN: ExpandFloatRes_FSIN(N, Lo, Hi); break; 817 case ISD::FSQRT: ExpandFloatRes_FSQRT(N, Lo, Hi); break; 818 case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break; 819 case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break; 820 case ISD::LOAD: ExpandFloatRes_LOAD(N, Lo, Hi); break; 821 case ISD::SINT_TO_FP: 822 case ISD::UINT_TO_FP: ExpandFloatRes_XINT_TO_FP(N, Lo, Hi); break; 823 } 824 825 // If Lo/Hi is null, the sub-method took care of registering results etc. 826 if (Lo.getNode()) 827 SetExpandedFloat(SDValue(N, ResNo), Lo, Hi); 828} 829 830void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo, 831 SDValue &Hi) { 832 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 833 assert(NVT.getSizeInBits() == integerPartWidth && 834 "Do not know how to expand this float constant!"); 835 APInt C = cast<ConstantFPSDNode>(N)->getValueAPF().bitcastToAPInt(); 836 Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, 837 &C.getRawData()[1])), NVT); 838 Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, 839 &C.getRawData()[0])), NVT); 840} 841 842void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo, 843 SDValue &Hi) { 844 assert(N->getValueType(0) == MVT::ppcf128 && 845 "Logic only correct for ppcf128!"); 846 DebugLoc dl = N->getDebugLoc(); 847 SDValue Tmp; 848 GetExpandedFloat(N->getOperand(0), Lo, Tmp); 849 Hi = DAG.getNode(ISD::FABS, dl, Tmp.getValueType(), Tmp); 850 // Lo = Hi==fabs(Hi) ? Lo : -Lo; 851 Lo = DAG.getNode(ISD::SELECT_CC, dl, Lo.getValueType(), Tmp, Hi, Lo, 852 DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo), 853 DAG.getCondCode(ISD::SETEQ)); 854} 855 856void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDValue &Lo, 857 SDValue &Hi) { 858 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 859 RTLIB::ADD_F32, RTLIB::ADD_F64, 860 RTLIB::ADD_F80, RTLIB::ADD_PPCF128), 861 N, false); 862 GetPairElements(Call, Lo, Hi); 863} 864 865void DAGTypeLegalizer::ExpandFloatRes_FCEIL(SDNode *N, 866 SDValue &Lo, SDValue &Hi) { 867 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 868 RTLIB::CEIL_F32, RTLIB::CEIL_F64, 869 RTLIB::CEIL_F80, RTLIB::CEIL_PPCF128), 870 N, false); 871 GetPairElements(Call, Lo, Hi); 872} 873 874void DAGTypeLegalizer::ExpandFloatRes_FCOS(SDNode *N, 875 SDValue &Lo, SDValue &Hi) { 876 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 877 RTLIB::COS_F32, RTLIB::COS_F64, 878 RTLIB::COS_F80, RTLIB::COS_PPCF128), 879 N, false); 880 GetPairElements(Call, Lo, Hi); 881} 882 883void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo, 884 SDValue &Hi) { 885 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 886 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 887 RTLIB::DIV_F32, 888 RTLIB::DIV_F64, 889 RTLIB::DIV_F80, 890 RTLIB::DIV_PPCF128), 891 N->getValueType(0), Ops, 2, false, 892 N->getDebugLoc()); 893 GetPairElements(Call, Lo, Hi); 894} 895 896void DAGTypeLegalizer::ExpandFloatRes_FEXP(SDNode *N, 897 SDValue &Lo, SDValue &Hi) { 898 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 899 RTLIB::EXP_F32, RTLIB::EXP_F64, 900 RTLIB::EXP_F80, RTLIB::EXP_PPCF128), 901 N, false); 902 GetPairElements(Call, Lo, Hi); 903} 904 905void DAGTypeLegalizer::ExpandFloatRes_FEXP2(SDNode *N, 906 SDValue &Lo, SDValue &Hi) { 907 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 908 RTLIB::EXP2_F32, RTLIB::EXP2_F64, 909 RTLIB::EXP2_F80, RTLIB::EXP2_PPCF128), 910 N, false); 911 GetPairElements(Call, Lo, Hi); 912} 913 914void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(SDNode *N, 915 SDValue &Lo, SDValue &Hi) { 916 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 917 RTLIB::FLOOR_F32,RTLIB::FLOOR_F64, 918 RTLIB::FLOOR_F80,RTLIB::FLOOR_PPCF128), 919 N, false); 920 GetPairElements(Call, Lo, Hi); 921} 922 923void DAGTypeLegalizer::ExpandFloatRes_FLOG(SDNode *N, 924 SDValue &Lo, SDValue &Hi) { 925 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 926 RTLIB::LOG_F32, RTLIB::LOG_F64, 927 RTLIB::LOG_F80, RTLIB::LOG_PPCF128), 928 N, false); 929 GetPairElements(Call, Lo, Hi); 930} 931 932void DAGTypeLegalizer::ExpandFloatRes_FLOG2(SDNode *N, 933 SDValue &Lo, SDValue &Hi) { 934 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 935 RTLIB::LOG2_F32, RTLIB::LOG2_F64, 936 RTLIB::LOG2_F80, RTLIB::LOG2_PPCF128), 937 N, false); 938 GetPairElements(Call, Lo, Hi); 939} 940 941void DAGTypeLegalizer::ExpandFloatRes_FLOG10(SDNode *N, 942 SDValue &Lo, SDValue &Hi) { 943 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 944 RTLIB::LOG10_F32,RTLIB::LOG10_F64, 945 RTLIB::LOG10_F80,RTLIB::LOG10_PPCF128), 946 N, false); 947 GetPairElements(Call, Lo, Hi); 948} 949 950void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo, 951 SDValue &Hi) { 952 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 953 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 954 RTLIB::MUL_F32, 955 RTLIB::MUL_F64, 956 RTLIB::MUL_F80, 957 RTLIB::MUL_PPCF128), 958 N->getValueType(0), Ops, 2, false, 959 N->getDebugLoc()); 960 GetPairElements(Call, Lo, Hi); 961} 962 963void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode *N, 964 SDValue &Lo, SDValue &Hi) { 965 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 966 RTLIB::NEARBYINT_F32, 967 RTLIB::NEARBYINT_F64, 968 RTLIB::NEARBYINT_F80, 969 RTLIB::NEARBYINT_PPCF128), 970 N, false); 971 GetPairElements(Call, Lo, Hi); 972} 973 974void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo, 975 SDValue &Hi) { 976 DebugLoc dl = N->getDebugLoc(); 977 GetExpandedFloat(N->getOperand(0), Lo, Hi); 978 Lo = DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo); 979 Hi = DAG.getNode(ISD::FNEG, dl, Hi.getValueType(), Hi); 980} 981 982void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo, 983 SDValue &Hi) { 984 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 985 Hi = DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), NVT, N->getOperand(0)); 986 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); 987} 988 989void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode *N, 990 SDValue &Lo, SDValue &Hi) { 991 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 992 RTLIB::POW_F32, RTLIB::POW_F64, 993 RTLIB::POW_F80, RTLIB::POW_PPCF128), 994 N, false); 995 GetPairElements(Call, Lo, Hi); 996} 997 998void DAGTypeLegalizer::ExpandFloatRes_FPOWI(SDNode *N, 999 SDValue &Lo, SDValue &Hi) { 1000 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 1001 RTLIB::POWI_F32, RTLIB::POWI_F64, 1002 RTLIB::POWI_F80, RTLIB::POWI_PPCF128), 1003 N, false); 1004 GetPairElements(Call, Lo, Hi); 1005} 1006 1007void DAGTypeLegalizer::ExpandFloatRes_FRINT(SDNode *N, 1008 SDValue &Lo, SDValue &Hi) { 1009 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 1010 RTLIB::RINT_F32, RTLIB::RINT_F64, 1011 RTLIB::RINT_F80, RTLIB::RINT_PPCF128), 1012 N, false); 1013 GetPairElements(Call, Lo, Hi); 1014} 1015 1016void DAGTypeLegalizer::ExpandFloatRes_FSIN(SDNode *N, 1017 SDValue &Lo, SDValue &Hi) { 1018 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 1019 RTLIB::SIN_F32, RTLIB::SIN_F64, 1020 RTLIB::SIN_F80, RTLIB::SIN_PPCF128), 1021 N, false); 1022 GetPairElements(Call, Lo, Hi); 1023} 1024 1025void DAGTypeLegalizer::ExpandFloatRes_FSQRT(SDNode *N, 1026 SDValue &Lo, SDValue &Hi) { 1027 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 1028 RTLIB::SQRT_F32, RTLIB::SQRT_F64, 1029 RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128), 1030 N, false); 1031 GetPairElements(Call, Lo, Hi); 1032} 1033 1034void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo, 1035 SDValue &Hi) { 1036 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 1037 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 1038 RTLIB::SUB_F32, 1039 RTLIB::SUB_F64, 1040 RTLIB::SUB_F80, 1041 RTLIB::SUB_PPCF128), 1042 N->getValueType(0), Ops, 2, false, 1043 N->getDebugLoc()); 1044 GetPairElements(Call, Lo, Hi); 1045} 1046 1047void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(SDNode *N, 1048 SDValue &Lo, SDValue &Hi) { 1049 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 1050 RTLIB::TRUNC_F32, RTLIB::TRUNC_F64, 1051 RTLIB::TRUNC_F80, RTLIB::TRUNC_PPCF128), 1052 N, false); 1053 GetPairElements(Call, Lo, Hi); 1054} 1055 1056void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo, 1057 SDValue &Hi) { 1058 if (ISD::isNormalLoad(N)) { 1059 ExpandRes_NormalLoad(N, Lo, Hi); 1060 return; 1061 } 1062 1063 assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!"); 1064 LoadSDNode *LD = cast<LoadSDNode>(N); 1065 SDValue Chain = LD->getChain(); 1066 SDValue Ptr = LD->getBasePtr(); 1067 DebugLoc dl = N->getDebugLoc(); 1068 1069 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), LD->getValueType(0)); 1070 assert(NVT.isByteSized() && "Expanded type not byte sized!"); 1071 assert(LD->getMemoryVT().bitsLE(NVT) && "Float type not round?"); 1072 1073 Hi = DAG.getExtLoad(LD->getExtensionType(), dl, NVT, Chain, Ptr, 1074 LD->getSrcValue(), LD->getSrcValueOffset(), 1075 LD->getMemoryVT(), 1076 LD->isVolatile(), LD->getAlignment()); 1077 1078 // Remember the chain. 1079 Chain = Hi.getValue(1); 1080 1081 // The low part is zero. 1082 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); 1083 1084 // Modified the chain - switch anything that used the old chain to use the 1085 // new one. 1086 ReplaceValueWith(SDValue(LD, 1), Chain); 1087} 1088 1089void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, 1090 SDValue &Hi) { 1091 assert(N->getValueType(0) == MVT::ppcf128 && "Unsupported XINT_TO_FP!"); 1092 EVT VT = N->getValueType(0); 1093 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 1094 SDValue Src = N->getOperand(0); 1095 EVT SrcVT = Src.getValueType(); 1096 bool isSigned = N->getOpcode() == ISD::SINT_TO_FP; 1097 DebugLoc dl = N->getDebugLoc(); 1098 1099 // First do an SINT_TO_FP, whether the original was signed or unsigned. 1100 // When promoting partial word types to i32 we must honor the signedness, 1101 // though. 1102 if (SrcVT.bitsLE(MVT::i32)) { 1103 // The integer can be represented exactly in an f64. 1104 Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, 1105 MVT::i32, Src); 1106 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); 1107 Hi = DAG.getNode(ISD::SINT_TO_FP, dl, NVT, Src); 1108 } else { 1109 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 1110 if (SrcVT.bitsLE(MVT::i64)) { 1111 Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, 1112 MVT::i64, Src); 1113 LC = RTLIB::SINTTOFP_I64_PPCF128; 1114 } else if (SrcVT.bitsLE(MVT::i128)) { 1115 Src = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i128, Src); 1116 LC = RTLIB::SINTTOFP_I128_PPCF128; 1117 } 1118 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!"); 1119 1120 Hi = MakeLibCall(LC, VT, &Src, 1, true, dl); 1121 GetPairElements(Hi, Lo, Hi); 1122 } 1123 1124 if (isSigned) 1125 return; 1126 1127 // Unsigned - fix up the SINT_TO_FP value just calculated. 1128 Hi = DAG.getNode(ISD::BUILD_PAIR, dl, VT, Lo, Hi); 1129 SrcVT = Src.getValueType(); 1130 1131 // x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128. 1132 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 }; 1133 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 }; 1134 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 }; 1135 const uint64_t *Parts = 0; 1136 1137 switch (SrcVT.getSimpleVT().SimpleTy) { 1138 default: 1139 assert(false && "Unsupported UINT_TO_FP!"); 1140 case MVT::i32: 1141 Parts = TwoE32; 1142 break; 1143 case MVT::i64: 1144 Parts = TwoE64; 1145 break; 1146 case MVT::i128: 1147 Parts = TwoE128; 1148 break; 1149 } 1150 1151 Lo = DAG.getNode(ISD::FADD, dl, VT, Hi, 1152 DAG.getConstantFP(APFloat(APInt(128, 2, Parts)), 1153 MVT::ppcf128)); 1154 Lo = DAG.getNode(ISD::SELECT_CC, dl, VT, Src, DAG.getConstant(0, SrcVT), 1155 Lo, Hi, DAG.getCondCode(ISD::SETLT)); 1156 GetPairElements(Lo, Lo, Hi); 1157} 1158 1159 1160//===----------------------------------------------------------------------===// 1161// Float Operand Expansion 1162//===----------------------------------------------------------------------===// 1163 1164/// ExpandFloatOperand - This method is called when the specified operand of the 1165/// specified node is found to need expansion. At this point, all of the result 1166/// types of the node are known to be legal, but other operands of the node may 1167/// need promotion or expansion as well as the specified one. 1168bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) { 1169 DEBUG(errs() << "Expand float operand: "; N->dump(&DAG); errs() << "\n"); 1170 SDValue Res = SDValue(); 1171 1172 if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) 1173 == TargetLowering::Custom) 1174 Res = TLI.LowerOperation(SDValue(N, 0), DAG); 1175 1176 if (Res.getNode() == 0) { 1177 switch (N->getOpcode()) { 1178 default: 1179 #ifndef NDEBUG 1180 errs() << "ExpandFloatOperand Op #" << OpNo << ": "; 1181 N->dump(&DAG); errs() << "\n"; 1182 #endif 1183 llvm_unreachable("Do not know how to expand this operator's operand!"); 1184 1185 case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break; 1186 case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; 1187 case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; 1188 1189 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(N); break; 1190 case ISD::FP_ROUND: Res = ExpandFloatOp_FP_ROUND(N); break; 1191 case ISD::FP_TO_SINT: Res = ExpandFloatOp_FP_TO_SINT(N); break; 1192 case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_UINT(N); break; 1193 case ISD::SELECT_CC: Res = ExpandFloatOp_SELECT_CC(N); break; 1194 case ISD::SETCC: Res = ExpandFloatOp_SETCC(N); break; 1195 case ISD::STORE: Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N), 1196 OpNo); break; 1197 } 1198 } 1199 1200 // If the result is null, the sub-method took care of registering results etc. 1201 if (!Res.getNode()) return false; 1202 1203 // If the result is N, the sub-method updated N in place. Tell the legalizer 1204 // core about this. 1205 if (Res.getNode() == N) 1206 return true; 1207 1208 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 1209 "Invalid operand expansion"); 1210 1211 ReplaceValueWith(SDValue(N, 0), Res); 1212 return false; 1213} 1214 1215/// FloatExpandSetCCOperands - Expand the operands of a comparison. This code 1216/// is shared among BR_CC, SELECT_CC, and SETCC handlers. 1217void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS, 1218 SDValue &NewRHS, 1219 ISD::CondCode &CCCode, 1220 DebugLoc dl) { 1221 SDValue LHSLo, LHSHi, RHSLo, RHSHi; 1222 GetExpandedFloat(NewLHS, LHSLo, LHSHi); 1223 GetExpandedFloat(NewRHS, RHSLo, RHSHi); 1224 1225 EVT VT = NewLHS.getValueType(); 1226 assert(VT == MVT::ppcf128 && "Unsupported setcc type!"); 1227 1228 // FIXME: This generated code sucks. We want to generate 1229 // FCMPU crN, hi1, hi2 1230 // BNE crN, L: 1231 // FCMPU crN, lo1, lo2 1232 // The following can be improved, but not that much. 1233 SDValue Tmp1, Tmp2, Tmp3; 1234 Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), 1235 LHSHi, RHSHi, ISD::SETOEQ); 1236 Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()), 1237 LHSLo, RHSLo, CCCode); 1238 Tmp3 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2); 1239 Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), 1240 LHSHi, RHSHi, ISD::SETUNE); 1241 Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), 1242 LHSHi, RHSHi, CCCode); 1243 Tmp1 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2); 1244 NewLHS = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp3); 1245 NewRHS = SDValue(); // LHS is the result, not a compare. 1246} 1247 1248SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) { 1249 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); 1250 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get(); 1251 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 1252 1253 // If ExpandSetCCOperands returned a scalar, we need to compare the result 1254 // against zero to select between true and false values. 1255 if (NewRHS.getNode() == 0) { 1256 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 1257 CCCode = ISD::SETNE; 1258 } 1259 1260 // Update N to have the operands specified. 1261 return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 1262 DAG.getCondCode(CCCode), NewLHS, NewRHS, 1263 N->getOperand(4)); 1264} 1265 1266SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) { 1267 assert(N->getOperand(0).getValueType() == MVT::ppcf128 && 1268 "Logic only correct for ppcf128!"); 1269 SDValue Lo, Hi; 1270 GetExpandedFloat(N->getOperand(0), Lo, Hi); 1271 // Round it the rest of the way (e.g. to f32) if needed. 1272 return DAG.getNode(ISD::FP_ROUND, N->getDebugLoc(), 1273 N->getValueType(0), Hi, N->getOperand(1)); 1274} 1275 1276SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { 1277 EVT RVT = N->getValueType(0); 1278 DebugLoc dl = N->getDebugLoc(); 1279 1280 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on 1281 // PPC (the libcall is not available). FIXME: Do this in a less hacky way. 1282 if (RVT == MVT::i32) { 1283 assert(N->getOperand(0).getValueType() == MVT::ppcf128 && 1284 "Logic only correct for ppcf128!"); 1285 SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, dl, MVT::ppcf128, 1286 N->getOperand(0), DAG.getValueType(MVT::f64)); 1287 Res = DAG.getNode(ISD::FP_ROUND, dl, MVT::f64, Res, 1288 DAG.getIntPtrConstant(1)); 1289 return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res); 1290 } 1291 1292 RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); 1293 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); 1294 return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false, dl); 1295} 1296 1297SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { 1298 EVT RVT = N->getValueType(0); 1299 DebugLoc dl = N->getDebugLoc(); 1300 1301 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on 1302 // PPC (the libcall is not available). FIXME: Do this in a less hacky way. 1303 if (RVT == MVT::i32) { 1304 assert(N->getOperand(0).getValueType() == MVT::ppcf128 && 1305 "Logic only correct for ppcf128!"); 1306 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0}; 1307 APFloat APF = APFloat(APInt(128, 2, TwoE31)); 1308 SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128); 1309 // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X 1310 // FIXME: generated code sucks. 1311 return DAG.getNode(ISD::SELECT_CC, dl, MVT::i32, N->getOperand(0), Tmp, 1312 DAG.getNode(ISD::ADD, dl, MVT::i32, 1313 DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, 1314 DAG.getNode(ISD::FSUB, dl, 1315 MVT::ppcf128, 1316 N->getOperand(0), 1317 Tmp)), 1318 DAG.getConstant(0x80000000, MVT::i32)), 1319 DAG.getNode(ISD::FP_TO_SINT, dl, 1320 MVT::i32, N->getOperand(0)), 1321 DAG.getCondCode(ISD::SETGE)); 1322 } 1323 1324 RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); 1325 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); 1326 return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false, dl); 1327} 1328 1329SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) { 1330 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 1331 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get(); 1332 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 1333 1334 // If ExpandSetCCOperands returned a scalar, we need to compare the result 1335 // against zero to select between true and false values. 1336 if (NewRHS.getNode() == 0) { 1337 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 1338 CCCode = ISD::SETNE; 1339 } 1340 1341 // Update N to have the operands specified. 1342 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 1343 N->getOperand(2), N->getOperand(3), 1344 DAG.getCondCode(CCCode)); 1345} 1346 1347SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) { 1348 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 1349 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); 1350 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 1351 1352 // If ExpandSetCCOperands returned a scalar, use it. 1353 if (NewRHS.getNode() == 0) { 1354 assert(NewLHS.getValueType() == N->getValueType(0) && 1355 "Unexpected setcc expansion!"); 1356 return NewLHS; 1357 } 1358 1359 // Otherwise, update N to have the operands specified. 1360 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 1361 DAG.getCondCode(CCCode)); 1362} 1363 1364SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) { 1365 if (ISD::isNormalStore(N)) 1366 return ExpandOp_NormalStore(N, OpNo); 1367 1368 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); 1369 assert(OpNo == 1 && "Can only expand the stored value so far"); 1370 StoreSDNode *ST = cast<StoreSDNode>(N); 1371 1372 SDValue Chain = ST->getChain(); 1373 SDValue Ptr = ST->getBasePtr(); 1374 1375 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ST->getValue().getValueType()); 1376 assert(NVT.isByteSized() && "Expanded type not byte sized!"); 1377 assert(ST->getMemoryVT().bitsLE(NVT) && "Float type not round?"); 1378 1379 SDValue Lo, Hi; 1380 GetExpandedOp(ST->getValue(), Lo, Hi); 1381 1382 return DAG.getTruncStore(Chain, N->getDebugLoc(), Hi, Ptr, 1383 ST->getSrcValue(), ST->getSrcValueOffset(), 1384 ST->getMemoryVT(), 1385 ST->isVolatile(), ST->getAlignment()); 1386} 1387