LLVM API Documentation
00001 //===-------- LegalizeFloatTypes.cpp - Legalization of float types --------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file is distributed under the University of Illinois Open Source 00006 // License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements float type expansion and softening for LegalizeTypes. 00011 // Softening is the act of turning a computation in an illegal floating point 00012 // type into a computation in an integer type of the same size; also known as 00013 // "soft float". For example, turning f32 arithmetic into operations using i32. 00014 // The resulting integer value is the same as what you would get by performing 00015 // the floating point operation and bitcasting the result to the integer type. 00016 // Expansion is the act of changing a computation in an illegal type to be a 00017 // computation in two identical registers of a smaller type. For example, 00018 // implementing ppcf128 arithmetic in two f64 registers. 00019 // 00020 //===----------------------------------------------------------------------===// 00021 00022 #include "LegalizeTypes.h" 00023 using namespace llvm; 00024 00025 /// GetFPLibCall - Return the right libcall for the given floating point type. 00026 static RTLIB::Libcall GetFPLibCall(MVT VT, 00027 RTLIB::Libcall Call_F32, 00028 RTLIB::Libcall Call_F64, 00029 RTLIB::Libcall Call_F80, 00030 RTLIB::Libcall Call_PPCF128) { 00031 return 00032 VT == MVT::f32 ? Call_F32 : 00033 VT == MVT::f64 ? Call_F64 : 00034 VT == MVT::f80 ? Call_F80 : 00035 VT == MVT::ppcf128 ? Call_PPCF128 : 00036 RTLIB::UNKNOWN_LIBCALL; 00037 } 00038 00039 //===----------------------------------------------------------------------===// 00040 // Result Float to Integer Conversion. 00041 //===----------------------------------------------------------------------===// 00042 00043 void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) { 00044 DEBUG(cerr << "Soften float result " << ResNo << ": "; N->dump(&DAG); 00045 cerr << "\n"); 00046 SDValue R = SDValue(); 00047 00048 switch (N->getOpcode()) { 00049 default: 00050 #ifndef NDEBUG 00051 cerr << "SoftenFloatResult #" << ResNo << ": "; 00052 N->dump(&DAG); cerr << "\n"; 00053 #endif 00054 assert(0 && "Do not know how to soften the result of this operator!"); 00055 abort(); 00056 00057 case ISD::BIT_CONVERT: R = SoftenFloatRes_BIT_CONVERT(N); break; 00058 case ISD::BUILD_PAIR: R = SoftenFloatRes_BUILD_PAIR(N); break; 00059 case ISD::ConstantFP: 00060 R = SoftenFloatRes_ConstantFP(cast<ConstantFPSDNode>(N)); 00061 break; 00062 case ISD::FABS: R = SoftenFloatRes_FABS(N); break; 00063 case ISD::FADD: R = SoftenFloatRes_FADD(N); break; 00064 case ISD::FCEIL: R = SoftenFloatRes_FCEIL(N); break; 00065 case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break; 00066 case ISD::FCOS: R = SoftenFloatRes_FCOS(N); break; 00067 case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break; 00068 case ISD::FEXP: R = SoftenFloatRes_FEXP(N); break; 00069 case ISD::FEXP2: R = SoftenFloatRes_FEXP2(N); break; 00070 case ISD::FFLOOR: R = SoftenFloatRes_FFLOOR(N); break; 00071 case ISD::FLOG: R = SoftenFloatRes_FLOG(N); break; 00072 case ISD::FLOG2: R = SoftenFloatRes_FLOG2(N); break; 00073 case ISD::FLOG10: R = SoftenFloatRes_FLOG10(N); break; 00074 case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break; 00075 case ISD::FNEARBYINT: R = SoftenFloatRes_FNEARBYINT(N); break; 00076 case ISD::FNEG: R = SoftenFloatRes_FNEG(N); break; 00077 case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break; 00078 case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break; 00079 case ISD::FPOW: R = SoftenFloatRes_FPOW(N); break; 00080 case ISD::FPOWI: R = SoftenFloatRes_FPOWI(N); break; 00081 case ISD::FRINT: R = SoftenFloatRes_FRINT(N); break; 00082 case ISD::FSIN: R = SoftenFloatRes_FSIN(N); break; 00083 case ISD::FSQRT: R = SoftenFloatRes_FSQRT(N); break; 00084 case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break; 00085 case ISD::FTRUNC: R = SoftenFloatRes_FTRUNC(N); break; 00086 case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break; 00087 case ISD::SELECT: R = SoftenFloatRes_SELECT(N); break; 00088 case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N); break; 00089 case ISD::SINT_TO_FP: 00090 case ISD::UINT_TO_FP: R = SoftenFloatRes_XINT_TO_FP(N); break; 00091 } 00092 00093 // If R is null, the sub-method took care of registering the result. 00094 if (R.getNode()) 00095 SetSoftenedFloat(SDValue(N, ResNo), R); 00096 } 00097 00098 SDValue DAGTypeLegalizer::SoftenFloatRes_BIT_CONVERT(SDNode *N) { 00099 return BitConvertToInteger(N->getOperand(0)); 00100 } 00101 00102 SDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) { 00103 // Convert the inputs to integers, and build a new pair out of them. 00104 return DAG.getNode(ISD::BUILD_PAIR, N->getDebugLoc(), 00105 TLI.getTypeToTransformTo(N->getValueType(0)), 00106 BitConvertToInteger(N->getOperand(0)), 00107 BitConvertToInteger(N->getOperand(1))); 00108 } 00109 00110 SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(ConstantFPSDNode *N) { 00111 return DAG.getConstant(N->getValueAPF().bitcastToAPInt(), 00112 TLI.getTypeToTransformTo(N->getValueType(0))); 00113 } 00114 00115 SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) { 00116 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00117 unsigned Size = NVT.getSizeInBits(); 00118 00119 // Mask = ~(1 << (Size-1)) 00120 SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1), 00121 NVT); 00122 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00123 return DAG.getNode(ISD::AND, N->getDebugLoc(), NVT, Op, Mask); 00124 } 00125 00126 SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) { 00127 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00128 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 00129 GetSoftenedFloat(N->getOperand(1)) }; 00130 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00131 RTLIB::ADD_F32, 00132 RTLIB::ADD_F64, 00133 RTLIB::ADD_F80, 00134 RTLIB::ADD_PPCF128), 00135 NVT, Ops, 2, false, N->getDebugLoc()); 00136 } 00137 00138 SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) { 00139 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00140 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00141 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00142 RTLIB::CEIL_F32, 00143 RTLIB::CEIL_F64, 00144 RTLIB::CEIL_F80, 00145 RTLIB::CEIL_PPCF128), 00146 NVT, &Op, 1, false, N->getDebugLoc()); 00147 } 00148 00149 SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { 00150 SDValue LHS = GetSoftenedFloat(N->getOperand(0)); 00151 SDValue RHS = BitConvertToInteger(N->getOperand(1)); 00152 DebugLoc dl = N->getDebugLoc(); 00153 00154 MVT LVT = LHS.getValueType(); 00155 MVT RVT = RHS.getValueType(); 00156 00157 unsigned LSize = LVT.getSizeInBits(); 00158 unsigned RSize = RVT.getSizeInBits(); 00159 00160 // First get the sign bit of second operand. 00161 SDValue SignBit = DAG.getNode(ISD::SHL, dl, RVT, DAG.getConstant(1, RVT), 00162 DAG.getConstant(RSize - 1, 00163 TLI.getShiftAmountTy())); 00164 SignBit = DAG.getNode(ISD::AND, dl, RVT, RHS, SignBit); 00165 00166 // Shift right or sign-extend it if the two operands have different types. 00167 int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits(); 00168 if (SizeDiff > 0) { 00169 SignBit = DAG.getNode(ISD::SRL, dl, RVT, SignBit, 00170 DAG.getConstant(SizeDiff, TLI.getShiftAmountTy())); 00171 SignBit = DAG.getNode(ISD::TRUNCATE, dl, LVT, SignBit); 00172 } else if (SizeDiff < 0) { 00173 SignBit = DAG.getNode(ISD::ANY_EXTEND, dl, LVT, SignBit); 00174 SignBit = DAG.getNode(ISD::SHL, dl, LVT, SignBit, 00175 DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy())); 00176 } 00177 00178 // Clear the sign bit of the first operand. 00179 SDValue Mask = DAG.getNode(ISD::SHL, dl, LVT, DAG.getConstant(1, LVT), 00180 DAG.getConstant(LSize - 1, 00181 TLI.getShiftAmountTy())); 00182 Mask = DAG.getNode(ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, LVT)); 00183 LHS = DAG.getNode(ISD::AND, dl, LVT, LHS, Mask); 00184 00185 // Or the value with the sign bit. 00186 return DAG.getNode(ISD::OR, dl, LVT, LHS, SignBit); 00187 } 00188 00189 SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) { 00190 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00191 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00192 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00193 RTLIB::COS_F32, 00194 RTLIB::COS_F64, 00195 RTLIB::COS_F80, 00196 RTLIB::COS_PPCF128), 00197 NVT, &Op, 1, false, N->getDebugLoc()); 00198 } 00199 00200 SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) { 00201 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00202 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 00203 GetSoftenedFloat(N->getOperand(1)) }; 00204 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00205 RTLIB::DIV_F32, 00206 RTLIB::DIV_F64, 00207 RTLIB::DIV_F80, 00208 RTLIB::DIV_PPCF128), 00209 NVT, Ops, 2, false, N->getDebugLoc()); 00210 } 00211 00212 SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) { 00213 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00214 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00215 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00216 RTLIB::EXP_F32, 00217 RTLIB::EXP_F64, 00218 RTLIB::EXP_F80, 00219 RTLIB::EXP_PPCF128), 00220 NVT, &Op, 1, false, N->getDebugLoc()); 00221 } 00222 00223 SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) { 00224 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00225 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00226 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00227 RTLIB::EXP2_F32, 00228 RTLIB::EXP2_F64, 00229 RTLIB::EXP2_F80, 00230 RTLIB::EXP2_PPCF128), 00231 NVT, &Op, 1, false, N->getDebugLoc()); 00232 } 00233 00234 SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) { 00235 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00236 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00237 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00238 RTLIB::FLOOR_F32, 00239 RTLIB::FLOOR_F64, 00240 RTLIB::FLOOR_F80, 00241 RTLIB::FLOOR_PPCF128), 00242 NVT, &Op, 1, false, N->getDebugLoc()); 00243 } 00244 00245 SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) { 00246 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00247 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00248 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00249 RTLIB::LOG_F32, 00250 RTLIB::LOG_F64, 00251 RTLIB::LOG_F80, 00252 RTLIB::LOG_PPCF128), 00253 NVT, &Op, 1, false, N->getDebugLoc()); 00254 } 00255 00256 SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) { 00257 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00258 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00259 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00260 RTLIB::LOG2_F32, 00261 RTLIB::LOG2_F64, 00262 RTLIB::LOG2_F80, 00263 RTLIB::LOG2_PPCF128), 00264 NVT, &Op, 1, false, N->getDebugLoc()); 00265 } 00266 00267 SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) { 00268 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00269 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00270 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00271 RTLIB::LOG10_F32, 00272 RTLIB::LOG10_F64, 00273 RTLIB::LOG10_F80, 00274 RTLIB::LOG10_PPCF128), 00275 NVT, &Op, 1, false, N->getDebugLoc()); 00276 } 00277 00278 SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { 00279 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00280 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 00281 GetSoftenedFloat(N->getOperand(1)) }; 00282 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00283 RTLIB::MUL_F32, 00284 RTLIB::MUL_F64, 00285 RTLIB::MUL_F80, 00286 RTLIB::MUL_PPCF128), 00287 NVT, Ops, 2, false, N->getDebugLoc()); 00288 } 00289 00290 SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) { 00291 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00292 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00293 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00294 RTLIB::NEARBYINT_F32, 00295 RTLIB::NEARBYINT_F64, 00296 RTLIB::NEARBYINT_F80, 00297 RTLIB::NEARBYINT_PPCF128), 00298 NVT, &Op, 1, false, N->getDebugLoc()); 00299 } 00300 00301 SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) { 00302 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00303 // Expand Y = FNEG(X) -> Y = SUB -0.0, X 00304 SDValue Ops[2] = { DAG.getConstantFP(-0.0, N->getValueType(0)), 00305 GetSoftenedFloat(N->getOperand(0)) }; 00306 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00307 RTLIB::SUB_F32, 00308 RTLIB::SUB_F64, 00309 RTLIB::SUB_F80, 00310 RTLIB::SUB_PPCF128), 00311 NVT, Ops, 2, false, N->getDebugLoc()); 00312 } 00313 00314 SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) { 00315 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00316 SDValue Op = N->getOperand(0); 00317 RTLIB::Libcall LC = RTLIB::getFPEXT(Op.getValueType(), N->getValueType(0)); 00318 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!"); 00319 return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc()); 00320 } 00321 00322 SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) { 00323 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00324 SDValue Op = N->getOperand(0); 00325 RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), N->getValueType(0)); 00326 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND!"); 00327 return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc()); 00328 } 00329 00330 SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) { 00331 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00332 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 00333 GetSoftenedFloat(N->getOperand(1)) }; 00334 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00335 RTLIB::POW_F32, 00336 RTLIB::POW_F64, 00337 RTLIB::POW_F80, 00338 RTLIB::POW_PPCF128), 00339 NVT, Ops, 2, false, N->getDebugLoc()); 00340 } 00341 00342 SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) { 00343 assert(N->getOperand(1).getValueType() == MVT::i32 && 00344 "Unsupported power type!"); 00345 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00346 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), N->getOperand(1) }; 00347 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00348 RTLIB::POWI_F32, 00349 RTLIB::POWI_F64, 00350 RTLIB::POWI_F80, 00351 RTLIB::POWI_PPCF128), 00352 NVT, Ops, 2, false, N->getDebugLoc()); 00353 } 00354 00355 SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) { 00356 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00357 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00358 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00359 RTLIB::RINT_F32, 00360 RTLIB::RINT_F64, 00361 RTLIB::RINT_F80, 00362 RTLIB::RINT_PPCF128), 00363 NVT, &Op, 1, false, N->getDebugLoc()); 00364 } 00365 00366 SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) { 00367 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00368 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00369 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00370 RTLIB::SIN_F32, 00371 RTLIB::SIN_F64, 00372 RTLIB::SIN_F80, 00373 RTLIB::SIN_PPCF128), 00374 NVT, &Op, 1, false, N->getDebugLoc()); 00375 } 00376 00377 SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) { 00378 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00379 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00380 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00381 RTLIB::SQRT_F32, 00382 RTLIB::SQRT_F64, 00383 RTLIB::SQRT_F80, 00384 RTLIB::SQRT_PPCF128), 00385 NVT, &Op, 1, false, N->getDebugLoc()); 00386 } 00387 00388 SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) { 00389 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00390 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 00391 GetSoftenedFloat(N->getOperand(1)) }; 00392 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00393 RTLIB::SUB_F32, 00394 RTLIB::SUB_F64, 00395 RTLIB::SUB_F80, 00396 RTLIB::SUB_PPCF128), 00397 NVT, Ops, 2, false, N->getDebugLoc()); 00398 } 00399 00400 SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) { 00401 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00402 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00403 return MakeLibCall(GetFPLibCall(N->getValueType(0), 00404 RTLIB::TRUNC_F32, 00405 RTLIB::TRUNC_F64, 00406 RTLIB::TRUNC_F80, 00407 RTLIB::TRUNC_PPCF128), 00408 NVT, &Op, 1, false, N->getDebugLoc()); 00409 } 00410 00411 SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { 00412 LoadSDNode *L = cast<LoadSDNode>(N); 00413 MVT VT = N->getValueType(0); 00414 MVT NVT = TLI.getTypeToTransformTo(VT); 00415 DebugLoc dl = N->getDebugLoc(); 00416 00417 SDValue NewL; 00418 if (L->getExtensionType() == ISD::NON_EXTLOAD) { 00419 NewL = DAG.getLoad(L->getAddressingMode(), dl, L->getExtensionType(), 00420 NVT, L->getChain(), L->getBasePtr(), L->getOffset(), 00421 L->getSrcValue(), L->getSrcValueOffset(), NVT, 00422 L->isVolatile(), L->getAlignment()); 00423 // Legalized the chain result - switch anything that used the old chain to 00424 // use the new one. 00425 ReplaceValueWith(SDValue(N, 1), NewL.getValue(1)); 00426 return NewL; 00427 } 00428 00429 // Do a non-extending load followed by FP_EXTEND. 00430 NewL = DAG.getLoad(L->getAddressingMode(), dl, ISD::NON_EXTLOAD, 00431 L->getMemoryVT(), L->getChain(), 00432 L->getBasePtr(), L->getOffset(), 00433 L->getSrcValue(), L->getSrcValueOffset(), 00434 L->getMemoryVT(), 00435 L->isVolatile(), L->getAlignment()); 00436 // Legalized the chain result - switch anything that used the old chain to 00437 // use the new one. 00438 ReplaceValueWith(SDValue(N, 1), NewL.getValue(1)); 00439 return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, dl, VT, NewL)); 00440 } 00441 00442 SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N) { 00443 SDValue LHS = GetSoftenedFloat(N->getOperand(1)); 00444 SDValue RHS = GetSoftenedFloat(N->getOperand(2)); 00445 return DAG.getNode(ISD::SELECT, N->getDebugLoc(), 00446 LHS.getValueType(), N->getOperand(0),LHS,RHS); 00447 } 00448 00449 SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N) { 00450 SDValue LHS = GetSoftenedFloat(N->getOperand(2)); 00451 SDValue RHS = GetSoftenedFloat(N->getOperand(3)); 00452 return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), 00453 LHS.getValueType(), N->getOperand(0), 00454 N->getOperand(1), LHS, RHS, N->getOperand(4)); 00455 } 00456 00457 SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) { 00458 bool Signed = N->getOpcode() == ISD::SINT_TO_FP; 00459 MVT SVT = N->getOperand(0).getValueType(); 00460 MVT RVT = N->getValueType(0); 00461 MVT NVT = MVT(); 00462 DebugLoc dl = N->getDebugLoc(); 00463 00464 // If the input is not legal, eg: i1 -> fp, then it needs to be promoted to 00465 // a larger type, eg: i8 -> fp. Even if it is legal, no libcall may exactly 00466 // match. Look for an appropriate libcall. 00467 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 00468 for (unsigned t = MVT::FIRST_INTEGER_VALUETYPE; 00469 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) { 00470 NVT = (MVT::SimpleValueType)t; 00471 // The source needs to big enough to hold the operand. 00472 if (NVT.bitsGE(SVT)) 00473 LC = Signed ? RTLIB::getSINTTOFP(NVT, RVT):RTLIB::getUINTTOFP (NVT, RVT); 00474 } 00475 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!"); 00476 00477 // Sign/zero extend the argument if the libcall takes a larger type. 00478 SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, 00479 NVT, N->getOperand(0)); 00480 return MakeLibCall(LC, TLI.getTypeToTransformTo(RVT), &Op, 1, false, dl); 00481 } 00482 00483 00484 //===----------------------------------------------------------------------===// 00485 // Operand Float to Integer Conversion.. 00486 //===----------------------------------------------------------------------===// 00487 00488 bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) { 00489 DEBUG(cerr << "Soften float operand " << OpNo << ": "; N->dump(&DAG); 00490 cerr << "\n"); 00491 SDValue Res = SDValue(); 00492 00493 switch (N->getOpcode()) { 00494 default: 00495 #ifndef NDEBUG 00496 cerr << "SoftenFloatOperand Op #" << OpNo << ": "; 00497 N->dump(&DAG); cerr << "\n"; 00498 #endif 00499 assert(0 && "Do not know how to soften this operator's operand!"); 00500 abort(); 00501 00502 case ISD::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break; 00503 case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(N); break; 00504 case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break; 00505 case ISD::FP_TO_SINT: Res = SoftenFloatOp_FP_TO_SINT(N); break; 00506 case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_UINT(N); break; 00507 case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break; 00508 case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break; 00509 case ISD::STORE: Res = SoftenFloatOp_STORE(N, OpNo); break; 00510 } 00511 00512 // If the result is null, the sub-method took care of registering results etc. 00513 if (!Res.getNode()) return false; 00514 00515 // If the result is N, the sub-method updated N in place. Tell the legalizer 00516 // core about this. 00517 if (Res.getNode() == N) 00518 return true; 00519 00520 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 00521 "Invalid operand expansion"); 00522 00523 ReplaceValueWith(SDValue(N, 0), Res); 00524 return false; 00525 } 00526 00527 /// SoftenSetCCOperands - Soften the operands of a comparison. This code is 00528 /// shared among BR_CC, SELECT_CC, and SETCC handlers. 00529 void DAGTypeLegalizer::SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, 00530 ISD::CondCode &CCCode, DebugLoc dl) { 00531 SDValue LHSInt = GetSoftenedFloat(NewLHS); 00532 SDValue RHSInt = GetSoftenedFloat(NewRHS); 00533 MVT VT = NewLHS.getValueType(); 00534 00535 assert((VT == MVT::f32 || VT == MVT::f64) && "Unsupported setcc type!"); 00536 00537 // Expand into one or more soft-fp libcall(s). 00538 RTLIB::Libcall LC1 = RTLIB::UNKNOWN_LIBCALL, LC2 = RTLIB::UNKNOWN_LIBCALL; 00539 switch (CCCode) { 00540 case ISD::SETEQ: 00541 case ISD::SETOEQ: 00542 LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64; 00543 break; 00544 case ISD::SETNE: 00545 case ISD::SETUNE: 00546 LC1 = (VT == MVT::f32) ? RTLIB::UNE_F32 : RTLIB::UNE_F64; 00547 break; 00548 case ISD::SETGE: 00549 case ISD::SETOGE: 00550 LC1 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64; 00551 break; 00552 case ISD::SETLT: 00553 case ISD::SETOLT: 00554 LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64; 00555 break; 00556 case ISD::SETLE: 00557 case ISD::SETOLE: 00558 LC1 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64; 00559 break; 00560 case ISD::SETGT: 00561 case ISD::SETOGT: 00562 LC1 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64; 00563 break; 00564 case ISD::SETUO: 00565 LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64; 00566 break; 00567 case ISD::SETO: 00568 LC1 = (VT == MVT::f32) ? RTLIB::O_F32 : RTLIB::O_F64; 00569 break; 00570 default: 00571 LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64; 00572 switch (CCCode) { 00573 case ISD::SETONE: 00574 // SETONE = SETOLT | SETOGT 00575 LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64; 00576 // Fallthrough 00577 case ISD::SETUGT: 00578 LC2 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64; 00579 break; 00580 case ISD::SETUGE: 00581 LC2 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64; 00582 break; 00583 case ISD::SETULT: 00584 LC2 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64; 00585 break; 00586 case ISD::SETULE: 00587 LC2 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64; 00588 break; 00589 case ISD::SETUEQ: 00590 LC2 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64; 00591 break; 00592 default: assert(false && "Do not know how to soften this setcc!"); 00593 } 00594 } 00595 00596 MVT RetVT = MVT::i32; // FIXME: is this the correct return type? 00597 SDValue Ops[2] = { LHSInt, RHSInt }; 00598 NewLHS = MakeLibCall(LC1, RetVT, Ops, 2, false/*sign irrelevant*/, dl); 00599 NewRHS = DAG.getConstant(0, RetVT); 00600 CCCode = TLI.getCmpLibcallCC(LC1); 00601 if (LC2 != RTLIB::UNKNOWN_LIBCALL) { 00602 SDValue Tmp = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(RetVT), 00603 NewLHS, NewRHS, DAG.getCondCode(CCCode)); 00604 NewLHS = MakeLibCall(LC2, RetVT, Ops, 2, false/*sign irrelevant*/, dl); 00605 NewLHS = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(RetVT), NewLHS, 00606 NewRHS, DAG.getCondCode(TLI.getCmpLibcallCC(LC2))); 00607 NewLHS = DAG.getNode(ISD::OR, dl, Tmp.getValueType(), Tmp, NewLHS); 00608 NewRHS = SDValue(); 00609 } 00610 } 00611 00612 SDValue DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) { 00613 return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), N->getValueType(0), 00614 GetSoftenedFloat(N->getOperand(0))); 00615 } 00616 00617 SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) { 00618 MVT SVT = N->getOperand(0).getValueType(); 00619 MVT RVT = N->getValueType(0); 00620 00621 RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, RVT); 00622 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall"); 00623 00624 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00625 return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc()); 00626 } 00627 00628 SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) { 00629 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); 00630 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get(); 00631 SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 00632 00633 // If SoftenSetCCOperands returned a scalar, we need to compare the result 00634 // against zero to select between true and false values. 00635 if (NewRHS.getNode() == 0) { 00636 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 00637 CCCode = ISD::SETNE; 00638 } 00639 00640 // Update N to have the operands specified. 00641 return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 00642 DAG.getCondCode(CCCode), NewLHS, NewRHS, 00643 N->getOperand(4)); 00644 } 00645 00646 SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode *N) { 00647 MVT RVT = N->getValueType(0); 00648 RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); 00649 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); 00650 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00651 return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc()); 00652 } 00653 00654 SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) { 00655 MVT RVT = N->getValueType(0); 00656 RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); 00657 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); 00658 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 00659 return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc()); 00660 } 00661 00662 SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) { 00663 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 00664 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get(); 00665 SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 00666 00667 // If SoftenSetCCOperands returned a scalar, we need to compare the result 00668 // against zero to select between true and false values. 00669 if (NewRHS.getNode() == 0) { 00670 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 00671 CCCode = ISD::SETNE; 00672 } 00673 00674 // Update N to have the operands specified. 00675 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 00676 N->getOperand(2), N->getOperand(3), 00677 DAG.getCondCode(CCCode)); 00678 } 00679 00680 SDValue DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) { 00681 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 00682 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); 00683 SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 00684 00685 // If SoftenSetCCOperands returned a scalar, use it. 00686 if (NewRHS.getNode() == 0) { 00687 assert(NewLHS.getValueType() == N->getValueType(0) && 00688 "Unexpected setcc expansion!"); 00689 return NewLHS; 00690 } 00691 00692 // Otherwise, update N to have the operands specified. 00693 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 00694 DAG.getCondCode(CCCode)); 00695 } 00696 00697 SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) { 00698 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); 00699 assert(OpNo == 1 && "Can only soften the stored value!"); 00700 StoreSDNode *ST = cast<StoreSDNode>(N); 00701 SDValue Val = ST->getValue(); 00702 DebugLoc dl = N->getDebugLoc(); 00703 00704 if (ST->isTruncatingStore()) 00705 // Do an FP_ROUND followed by a non-truncating store. 00706 Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, dl, ST->getMemoryVT(), 00707 Val, DAG.getIntPtrConstant(0))); 00708 else 00709 Val = GetSoftenedFloat(Val); 00710 00711 return DAG.getStore(ST->getChain(), dl, Val, ST->getBasePtr(), 00712 ST->getSrcValue(), ST->getSrcValueOffset(), 00713 ST->isVolatile(), ST->getAlignment()); 00714 } 00715 00716 00717 //===----------------------------------------------------------------------===// 00718 // Float Result Expansion 00719 //===----------------------------------------------------------------------===// 00720 00721 /// ExpandFloatResult - This method is called when the specified result of the 00722 /// specified node is found to need expansion. At this point, the node may also 00723 /// have invalid operands or may have other results that need promotion, we just 00724 /// know that (at least) one result needs expansion. 00725 void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { 00726 DEBUG(cerr << "Expand float result: "; N->dump(&DAG); cerr << "\n"); 00727 SDValue Lo, Hi; 00728 Lo = Hi = SDValue(); 00729 00730 // See if the target wants to custom expand this node. 00731 if (CustomLowerResults(N, N->getValueType(ResNo), true)) 00732 return; 00733 00734 switch (N->getOpcode()) { 00735 default: 00736 #ifndef NDEBUG 00737 cerr << "ExpandFloatResult #" << ResNo << ": "; 00738 N->dump(&DAG); cerr << "\n"; 00739 #endif 00740 assert(0 && "Do not know how to expand the result of this operator!"); 00741 abort(); 00742 00743 case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break; 00744 case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; 00745 case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; 00746 case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; 00747 00748 case ISD::BIT_CONVERT: ExpandRes_BIT_CONVERT(N, Lo, Hi); break; 00749 case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break; 00750 case ISD::EXTRACT_ELEMENT: ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break; 00751 case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; 00752 case ISD::VAARG: ExpandRes_VAARG(N, Lo, Hi); break; 00753 00754 case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break; 00755 case ISD::FABS: ExpandFloatRes_FABS(N, Lo, Hi); break; 00756 case ISD::FADD: ExpandFloatRes_FADD(N, Lo, Hi); break; 00757 case ISD::FCEIL: ExpandFloatRes_FCEIL(N, Lo, Hi); break; 00758 case ISD::FCOS: ExpandFloatRes_FCOS(N, Lo, Hi); break; 00759 case ISD::FDIV: ExpandFloatRes_FDIV(N, Lo, Hi); break; 00760 case ISD::FEXP: ExpandFloatRes_FEXP(N, Lo, Hi); break; 00761 case ISD::FEXP2: ExpandFloatRes_FEXP2(N, Lo, Hi); break; 00762 case ISD::FFLOOR: ExpandFloatRes_FFLOOR(N, Lo, Hi); break; 00763 case ISD::FLOG: ExpandFloatRes_FLOG(N, Lo, Hi); break; 00764 case ISD::FLOG2: ExpandFloatRes_FLOG2(N, Lo, Hi); break; 00765 case ISD::FLOG10: ExpandFloatRes_FLOG10(N, Lo, Hi); break; 00766 case ISD::FMUL: ExpandFloatRes_FMUL(N, Lo, Hi); break; 00767 case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT(N, Lo, Hi); break; 00768 case ISD::FNEG: ExpandFloatRes_FNEG(N, Lo, Hi); break; 00769 case ISD::FP_EXTEND: ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break; 00770 case ISD::FPOW: ExpandFloatRes_FPOW(N, Lo, Hi); break; 00771 case ISD::FPOWI: ExpandFloatRes_FPOWI(N, Lo, Hi); break; 00772 case ISD::FRINT: ExpandFloatRes_FRINT(N, Lo, Hi); break; 00773 case ISD::FSIN: ExpandFloatRes_FSIN(N, Lo, Hi); break; 00774 case ISD::FSQRT: ExpandFloatRes_FSQRT(N, Lo, Hi); break; 00775 case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break; 00776 case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break; 00777 case ISD::LOAD: ExpandFloatRes_LOAD(N, Lo, Hi); break; 00778 case ISD::SINT_TO_FP: 00779 case ISD::UINT_TO_FP: ExpandFloatRes_XINT_TO_FP(N, Lo, Hi); break; 00780 } 00781 00782 // If Lo/Hi is null, the sub-method took care of registering results etc. 00783 if (Lo.getNode()) 00784 SetExpandedFloat(SDValue(N, ResNo), Lo, Hi); 00785 } 00786 00787 void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo, 00788 SDValue &Hi) { 00789 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00790 assert(NVT.getSizeInBits() == integerPartWidth && 00791 "Do not know how to expand this float constant!"); 00792 APInt C = cast<ConstantFPSDNode>(N)->getValueAPF().bitcastToAPInt(); 00793 Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, 00794 &C.getRawData()[1])), NVT); 00795 Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, 00796 &C.getRawData()[0])), NVT); 00797 } 00798 00799 void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo, 00800 SDValue &Hi) { 00801 assert(N->getValueType(0) == MVT::ppcf128 && 00802 "Logic only correct for ppcf128!"); 00803 DebugLoc dl = N->getDebugLoc(); 00804 SDValue Tmp; 00805 GetExpandedFloat(N->getOperand(0), Lo, Tmp); 00806 Hi = DAG.getNode(ISD::FABS, dl, Tmp.getValueType(), Tmp); 00807 // Lo = Hi==fabs(Hi) ? Lo : -Lo; 00808 Lo = DAG.getNode(ISD::SELECT_CC, dl, Lo.getValueType(), Tmp, Hi, Lo, 00809 DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo), 00810 DAG.getCondCode(ISD::SETEQ)); 00811 } 00812 00813 void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDValue &Lo, 00814 SDValue &Hi) { 00815 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 00816 RTLIB::ADD_F32, RTLIB::ADD_F64, 00817 RTLIB::ADD_F80, RTLIB::ADD_PPCF128), 00818 N, false); 00819 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00820 "Call lowered wrongly!"); 00821 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 00822 } 00823 00824 void DAGTypeLegalizer::ExpandFloatRes_FCEIL(SDNode *N, 00825 SDValue &Lo, SDValue &Hi) { 00826 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 00827 RTLIB::CEIL_F32, RTLIB::CEIL_F64, 00828 RTLIB::CEIL_F80, RTLIB::CEIL_PPCF128), 00829 N, false); 00830 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00831 "Call lowered wrongly!"); 00832 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 00833 } 00834 00835 void DAGTypeLegalizer::ExpandFloatRes_FCOS(SDNode *N, 00836 SDValue &Lo, SDValue &Hi) { 00837 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 00838 RTLIB::COS_F32, RTLIB::COS_F64, 00839 RTLIB::COS_F80, RTLIB::COS_PPCF128), 00840 N, false); 00841 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00842 "Call lowered wrongly!"); 00843 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 00844 } 00845 00846 void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo, 00847 SDValue &Hi) { 00848 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 00849 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 00850 RTLIB::DIV_F32, 00851 RTLIB::DIV_F64, 00852 RTLIB::DIV_F80, 00853 RTLIB::DIV_PPCF128), 00854 N->getValueType(0), Ops, 2, false, 00855 N->getDebugLoc()); 00856 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00857 "Call lowered wrongly!"); 00858 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 00859 } 00860 00861 void DAGTypeLegalizer::ExpandFloatRes_FEXP(SDNode *N, 00862 SDValue &Lo, SDValue &Hi) { 00863 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 00864 RTLIB::EXP_F32, RTLIB::EXP_F64, 00865 RTLIB::EXP_F80, RTLIB::EXP_PPCF128), 00866 N, false); 00867 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00868 "Call lowered wrongly!"); 00869 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 00870 } 00871 00872 void DAGTypeLegalizer::ExpandFloatRes_FEXP2(SDNode *N, 00873 SDValue &Lo, SDValue &Hi) { 00874 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 00875 RTLIB::EXP2_F32, RTLIB::EXP2_F64, 00876 RTLIB::EXP2_F80, RTLIB::EXP2_PPCF128), 00877 N, false); 00878 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00879 "Call lowered wrongly!"); 00880 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 00881 } 00882 00883 void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(SDNode *N, 00884 SDValue &Lo, SDValue &Hi) { 00885 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 00886 RTLIB::FLOOR_F32,RTLIB::FLOOR_F64, 00887 RTLIB::FLOOR_F80,RTLIB::FLOOR_PPCF128), 00888 N, false); 00889 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00890 "Call lowered wrongly!"); 00891 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 00892 } 00893 00894 void DAGTypeLegalizer::ExpandFloatRes_FLOG(SDNode *N, 00895 SDValue &Lo, SDValue &Hi) { 00896 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 00897 RTLIB::LOG_F32, RTLIB::LOG_F64, 00898 RTLIB::LOG_F80, RTLIB::LOG_PPCF128), 00899 N, false); 00900 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00901 "Call lowered wrongly!"); 00902 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 00903 } 00904 00905 void DAGTypeLegalizer::ExpandFloatRes_FLOG2(SDNode *N, 00906 SDValue &Lo, SDValue &Hi) { 00907 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 00908 RTLIB::LOG2_F32, RTLIB::LOG2_F64, 00909 RTLIB::LOG2_F80, RTLIB::LOG2_PPCF128), 00910 N, false); 00911 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00912 "Call lowered wrongly!"); 00913 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 00914 } 00915 00916 void DAGTypeLegalizer::ExpandFloatRes_FLOG10(SDNode *N, 00917 SDValue &Lo, SDValue &Hi) { 00918 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 00919 RTLIB::LOG10_F32,RTLIB::LOG10_F64, 00920 RTLIB::LOG10_F80,RTLIB::LOG10_PPCF128), 00921 N, false); 00922 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00923 "Call lowered wrongly!"); 00924 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 00925 } 00926 00927 void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo, 00928 SDValue &Hi) { 00929 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 00930 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 00931 RTLIB::MUL_F32, 00932 RTLIB::MUL_F64, 00933 RTLIB::MUL_F80, 00934 RTLIB::MUL_PPCF128), 00935 N->getValueType(0), Ops, 2, false, 00936 N->getDebugLoc()); 00937 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00938 "Call lowered wrongly!"); 00939 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 00940 } 00941 00942 void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode *N, 00943 SDValue &Lo, SDValue &Hi) { 00944 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 00945 RTLIB::NEARBYINT_F32, 00946 RTLIB::NEARBYINT_F64, 00947 RTLIB::NEARBYINT_F80, 00948 RTLIB::NEARBYINT_PPCF128), 00949 N, false); 00950 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00951 "Call lowered wrongly!"); 00952 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 00953 } 00954 00955 void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo, 00956 SDValue &Hi) { 00957 DebugLoc dl = N->getDebugLoc(); 00958 GetExpandedFloat(N->getOperand(0), Lo, Hi); 00959 Lo = DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo); 00960 Hi = DAG.getNode(ISD::FNEG, dl, Hi.getValueType(), Hi); 00961 } 00962 00963 void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo, 00964 SDValue &Hi) { 00965 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 00966 Hi = DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), NVT, N->getOperand(0)); 00967 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); 00968 } 00969 00970 void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode *N, 00971 SDValue &Lo, SDValue &Hi) { 00972 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 00973 RTLIB::POW_F32, RTLIB::POW_F64, 00974 RTLIB::POW_F80, RTLIB::POW_PPCF128), 00975 N, false); 00976 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00977 "Call lowered wrongly!"); 00978 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 00979 } 00980 00981 void DAGTypeLegalizer::ExpandFloatRes_FPOWI(SDNode *N, 00982 SDValue &Lo, SDValue &Hi) { 00983 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 00984 RTLIB::POWI_F32, RTLIB::POWI_F64, 00985 RTLIB::POWI_F80, RTLIB::POWI_PPCF128), 00986 N, false); 00987 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00988 "Call lowered wrongly!"); 00989 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 00990 } 00991 00992 void DAGTypeLegalizer::ExpandFloatRes_FRINT(SDNode *N, 00993 SDValue &Lo, SDValue &Hi) { 00994 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 00995 RTLIB::RINT_F32, RTLIB::RINT_F64, 00996 RTLIB::RINT_F80, RTLIB::RINT_PPCF128), 00997 N, false); 00998 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 00999 "Call lowered wrongly!"); 01000 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 01001 } 01002 01003 void DAGTypeLegalizer::ExpandFloatRes_FSIN(SDNode *N, 01004 SDValue &Lo, SDValue &Hi) { 01005 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 01006 RTLIB::SIN_F32, RTLIB::SIN_F64, 01007 RTLIB::SIN_F80, RTLIB::SIN_PPCF128), 01008 N, false); 01009 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 01010 "Call lowered wrongly!"); 01011 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 01012 } 01013 01014 void DAGTypeLegalizer::ExpandFloatRes_FSQRT(SDNode *N, 01015 SDValue &Lo, SDValue &Hi) { 01016 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 01017 RTLIB::SQRT_F32, RTLIB::SQRT_F64, 01018 RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128), 01019 N, false); 01020 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 01021 "Call lowered wrongly!"); 01022 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 01023 } 01024 01025 void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo, 01026 SDValue &Hi) { 01027 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 01028 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 01029 RTLIB::SUB_F32, 01030 RTLIB::SUB_F64, 01031 RTLIB::SUB_F80, 01032 RTLIB::SUB_PPCF128), 01033 N->getValueType(0), Ops, 2, false, 01034 N->getDebugLoc()); 01035 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 01036 "Call lowered wrongly!"); 01037 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 01038 } 01039 01040 void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(SDNode *N, 01041 SDValue &Lo, SDValue &Hi) { 01042 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 01043 RTLIB::TRUNC_F32, RTLIB::TRUNC_F64, 01044 RTLIB::TRUNC_F80, RTLIB::TRUNC_PPCF128), 01045 N, false); 01046 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 01047 "Call lowered wrongly!"); 01048 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 01049 } 01050 01051 void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo, 01052 SDValue &Hi) { 01053 if (ISD::isNormalLoad(N)) { 01054 ExpandRes_NormalLoad(N, Lo, Hi); 01055 return; 01056 } 01057 01058 assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!"); 01059 LoadSDNode *LD = cast<LoadSDNode>(N); 01060 SDValue Chain = LD->getChain(); 01061 SDValue Ptr = LD->getBasePtr(); 01062 DebugLoc dl = N->getDebugLoc(); 01063 01064 MVT NVT = TLI.getTypeToTransformTo(LD->getValueType(0)); 01065 assert(NVT.isByteSized() && "Expanded type not byte sized!"); 01066 assert(LD->getMemoryVT().bitsLE(NVT) && "Float type not round?"); 01067 01068 Hi = DAG.getExtLoad(LD->getExtensionType(), dl, NVT, Chain, Ptr, 01069 LD->getSrcValue(), LD->getSrcValueOffset(), 01070 LD->getMemoryVT(), 01071 LD->isVolatile(), LD->getAlignment()); 01072 01073 // Remember the chain. 01074 Chain = Hi.getValue(1); 01075 01076 // The low part is zero. 01077 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); 01078 01079 // Modified the chain - switch anything that used the old chain to use the 01080 // new one. 01081 ReplaceValueWith(SDValue(LD, 1), Chain); 01082 } 01083 01084 void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, 01085 SDValue &Hi) { 01086 assert(N->getValueType(0) == MVT::ppcf128 && "Unsupported XINT_TO_FP!"); 01087 MVT VT = N->getValueType(0); 01088 MVT NVT = TLI.getTypeToTransformTo(VT); 01089 SDValue Src = N->getOperand(0); 01090 MVT SrcVT = Src.getValueType(); 01091 bool isSigned = N->getOpcode() == ISD::SINT_TO_FP; 01092 DebugLoc dl = N->getDebugLoc(); 01093 01094 // First do an SINT_TO_FP, whether the original was signed or unsigned. 01095 // When promoting partial word types to i32 we must honor the signedness, 01096 // though. 01097 if (SrcVT.bitsLE(MVT::i32)) { 01098 // The integer can be represented exactly in an f64. 01099 Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, 01100 MVT::i32, Src); 01101 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); 01102 Hi = DAG.getNode(ISD::SINT_TO_FP, dl, NVT, Src); 01103 } else { 01104 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 01105 if (SrcVT.bitsLE(MVT::i64)) { 01106 Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, 01107 MVT::i64, Src); 01108 LC = RTLIB::SINTTOFP_I64_PPCF128; 01109 } else if (SrcVT.bitsLE(MVT::i128)) { 01110 Src = DAG.getNode(ISD::SIGN_EXTEND, MVT::i128, Src); 01111 LC = RTLIB::SINTTOFP_I128_PPCF128; 01112 } 01113 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!"); 01114 01115 Hi = MakeLibCall(LC, VT, &Src, 1, true, dl); 01116 assert(Hi.getNode()->getOpcode() == ISD::BUILD_PAIR && 01117 "Call lowered wrongly!"); 01118 Lo = Hi.getOperand(0); Hi = Hi.getOperand(1); 01119 } 01120 01121 if (isSigned) 01122 return; 01123 01124 // Unsigned - fix up the SINT_TO_FP value just calculated. 01125 Hi = DAG.getNode(ISD::BUILD_PAIR, dl, VT, Lo, Hi); 01126 SrcVT = Src.getValueType(); 01127 01128 // x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128. 01129 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 }; 01130 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 }; 01131 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 }; 01132 const uint64_t *Parts = 0; 01133 01134 switch (SrcVT.getSimpleVT()) { 01135 default: 01136 assert(false && "Unsupported UINT_TO_FP!"); 01137 case MVT::i32: 01138 Parts = TwoE32; 01139 break; 01140 case MVT::i64: 01141 Parts = TwoE64; 01142 break; 01143 case MVT::i128: 01144 Parts = TwoE128; 01145 break; 01146 } 01147 01148 Lo = DAG.getNode(ISD::FADD, dl, VT, Hi, 01149 DAG.getConstantFP(APFloat(APInt(128, 2, Parts)), 01150 MVT::ppcf128)); 01151 Lo = DAG.getNode(ISD::SELECT_CC, dl, VT, Src, DAG.getConstant(0, SrcVT), 01152 Lo, Hi, DAG.getCondCode(ISD::SETLT)); 01153 Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Lo, DAG.getIntPtrConstant(1)); 01154 Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Lo, DAG.getIntPtrConstant(0)); 01155 } 01156 01157 01158 //===----------------------------------------------------------------------===// 01159 // Float Operand Expansion 01160 //===----------------------------------------------------------------------===// 01161 01162 /// ExpandFloatOperand - This method is called when the specified operand of the 01163 /// specified node is found to need expansion. At this point, all of the result 01164 /// types of the node are known to be legal, but other operands of the node may 01165 /// need promotion or expansion as well as the specified one. 01166 bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) { 01167 DEBUG(cerr << "Expand float operand: "; N->dump(&DAG); cerr << "\n"); 01168 SDValue Res = SDValue(); 01169 01170 if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) 01171 == TargetLowering::Custom) 01172 Res = TLI.LowerOperation(SDValue(N, 0), DAG); 01173 01174 if (Res.getNode() == 0) { 01175 switch (N->getOpcode()) { 01176 default: 01177 #ifndef NDEBUG 01178 cerr << "ExpandFloatOperand Op #" << OpNo << ": "; 01179 N->dump(&DAG); cerr << "\n"; 01180 #endif 01181 assert(0 && "Do not know how to expand this operator's operand!"); 01182 abort(); 01183 01184 case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break; 01185 case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; 01186 case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; 01187 01188 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(N); break; 01189 case ISD::FP_ROUND: Res = ExpandFloatOp_FP_ROUND(N); break; 01190 case ISD::FP_TO_SINT: Res = ExpandFloatOp_FP_TO_SINT(N); break; 01191 case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_UINT(N); break; 01192 case ISD::SELECT_CC: Res = ExpandFloatOp_SELECT_CC(N); break; 01193 case ISD::SETCC: Res = ExpandFloatOp_SETCC(N); break; 01194 case ISD::STORE: Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N), 01195 OpNo); break; 01196 } 01197 } 01198 01199 // If the result is null, the sub-method took care of registering results etc. 01200 if (!Res.getNode()) return false; 01201 01202 // If the result is N, the sub-method updated N in place. Tell the legalizer 01203 // core about this. 01204 if (Res.getNode() == N) 01205 return true; 01206 01207 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 01208 "Invalid operand expansion"); 01209 01210 ReplaceValueWith(SDValue(N, 0), Res); 01211 return false; 01212 } 01213 01214 /// FloatExpandSetCCOperands - Expand the operands of a comparison. This code 01215 /// is shared among BR_CC, SELECT_CC, and SETCC handlers. 01216 void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS, 01217 SDValue &NewRHS, 01218 ISD::CondCode &CCCode, 01219 DebugLoc dl) { 01220 SDValue LHSLo, LHSHi, RHSLo, RHSHi; 01221 GetExpandedFloat(NewLHS, LHSLo, LHSHi); 01222 GetExpandedFloat(NewRHS, RHSLo, RHSHi); 01223 01224 MVT VT = NewLHS.getValueType(); 01225 assert(VT == MVT::ppcf128 && "Unsupported setcc type!"); 01226 01227 // FIXME: This generated code sucks. We want to generate 01228 // FCMPU crN, hi1, hi2 01229 // BNE crN, L: 01230 // FCMPU crN, lo1, lo2 01231 // The following can be improved, but not that much. 01232 SDValue Tmp1, Tmp2, Tmp3; 01233 Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), 01234 LHSHi, RHSHi, ISD::SETOEQ); 01235 Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()), 01236 LHSLo, RHSLo, CCCode); 01237 Tmp3 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2); 01238 Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), 01239 LHSHi, RHSHi, ISD::SETUNE); 01240 Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), 01241 LHSHi, RHSHi, CCCode); 01242 Tmp1 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2); 01243 NewLHS = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp3); 01244 NewRHS = SDValue(); // LHS is the result, not a compare. 01245 } 01246 01247 SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) { 01248 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); 01249 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get(); 01250 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 01251 01252 // If ExpandSetCCOperands returned a scalar, we need to compare the result 01253 // against zero to select between true and false values. 01254 if (NewRHS.getNode() == 0) { 01255 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 01256 CCCode = ISD::SETNE; 01257 } 01258 01259 // Update N to have the operands specified. 01260 return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 01261 DAG.getCondCode(CCCode), NewLHS, NewRHS, 01262 N->getOperand(4)); 01263 } 01264 01265 SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) { 01266 assert(N->getOperand(0).getValueType() == MVT::ppcf128 && 01267 "Logic only correct for ppcf128!"); 01268 SDValue Lo, Hi; 01269 GetExpandedFloat(N->getOperand(0), Lo, Hi); 01270 // Round it the rest of the way (e.g. to f32) if needed. 01271 return DAG.getNode(ISD::FP_ROUND, N->getDebugLoc(), 01272 N->getValueType(0), Hi, N->getOperand(1)); 01273 } 01274 01275 SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { 01276 MVT RVT = N->getValueType(0); 01277 DebugLoc dl = N->getDebugLoc(); 01278 01279 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on 01280 // PPC (the libcall is not available). FIXME: Do this in a less hacky way. 01281 if (RVT == MVT::i32) { 01282 assert(N->getOperand(0).getValueType() == MVT::ppcf128 && 01283 "Logic only correct for ppcf128!"); 01284 SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, dl, MVT::ppcf128, 01285 N->getOperand(0), DAG.getValueType(MVT::f64)); 01286 Res = DAG.getNode(ISD::FP_ROUND, dl, MVT::f64, Res, 01287 DAG.getIntPtrConstant(1)); 01288 return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res); 01289 } 01290 01291 RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); 01292 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); 01293 return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false, dl); 01294 } 01295 01296 SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { 01297 MVT RVT = N->getValueType(0); 01298 DebugLoc dl = N->getDebugLoc(); 01299 01300 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on 01301 // PPC (the libcall is not available). FIXME: Do this in a less hacky way. 01302 if (RVT == MVT::i32) { 01303 assert(N->getOperand(0).getValueType() == MVT::ppcf128 && 01304 "Logic only correct for ppcf128!"); 01305 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0}; 01306 APFloat APF = APFloat(APInt(128, 2, TwoE31)); 01307 SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128); 01308 // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X 01309 // FIXME: generated code sucks. 01310 return DAG.getNode(ISD::SELECT_CC, dl, MVT::i32, N->getOperand(0), Tmp, 01311 DAG.getNode(ISD::ADD, dl, MVT::i32, 01312 DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, 01313 DAG.getNode(ISD::FSUB, dl, 01314 MVT::ppcf128, 01315 N->getOperand(0), 01316 Tmp)), 01317 DAG.getConstant(0x80000000, MVT::i32)), 01318 DAG.getNode(ISD::FP_TO_SINT, dl, 01319 MVT::i32, N->getOperand(0)), 01320 DAG.getCondCode(ISD::SETGE)); 01321 } 01322 01323 RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); 01324 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); 01325 return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false, dl); 01326 } 01327 01328 SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) { 01329 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 01330 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get(); 01331 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 01332 01333 // If ExpandSetCCOperands returned a scalar, we need to compare the result 01334 // against zero to select between true and false values. 01335 if (NewRHS.getNode() == 0) { 01336 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 01337 CCCode = ISD::SETNE; 01338 } 01339 01340 // Update N to have the operands specified. 01341 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 01342 N->getOperand(2), N->getOperand(3), 01343 DAG.getCondCode(CCCode)); 01344 } 01345 01346 SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) { 01347 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 01348 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); 01349 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 01350 01351 // If ExpandSetCCOperands returned a scalar, use it. 01352 if (NewRHS.getNode() == 0) { 01353 assert(NewLHS.getValueType() == N->getValueType(0) && 01354 "Unexpected setcc expansion!"); 01355 return NewLHS; 01356 } 01357 01358 // Otherwise, update N to have the operands specified. 01359 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 01360 DAG.getCondCode(CCCode)); 01361 } 01362 01363 SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) { 01364 if (ISD::isNormalStore(N)) 01365 return ExpandOp_NormalStore(N, OpNo); 01366 01367 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); 01368 assert(OpNo == 1 && "Can only expand the stored value so far"); 01369 StoreSDNode *ST = cast<StoreSDNode>(N); 01370 01371 SDValue Chain = ST->getChain(); 01372 SDValue Ptr = ST->getBasePtr(); 01373 01374 MVT NVT = TLI.getTypeToTransformTo(ST->getValue().getValueType()); 01375 assert(NVT.isByteSized() && "Expanded type not byte sized!"); 01376 assert(ST->getMemoryVT().bitsLE(NVT) && "Float type not round?"); 01377 01378 SDValue Lo, Hi; 01379 GetExpandedOp(ST->getValue(), Lo, Hi); 01380 01381 return DAG.getTruncStore(Chain, N->getDebugLoc(), Hi, Ptr, 01382 ST->getSrcValue(), ST->getSrcValueOffset(), 01383 ST->getMemoryVT(), 01384 ST->isVolatile(), ST->getAlignment()); 01385 }