LegalizeFloatTypes.cpp revision 8f17a36d3107bdc4ffed53ce782c1724ef6460e7
1//===-------- LegalizeFloatTypes.cpp - Legalization of float types --------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements float type expansion and softening for LegalizeTypes. 11// Softening is the act of turning a computation in an illegal floating point 12// type into a computation in an integer type of the same size; also known as 13// "soft float". For example, turning f32 arithmetic into operations using i32. 14// The resulting integer value is the same as what you would get by performing 15// the floating point operation and bitcasting the result to the integer type. 16// Expansion is the act of changing a computation in an illegal type to be a 17// computation in two identical registers of a smaller type. For example, 18// implementing ppcf128 arithmetic in two f64 registers. 19// 20//===----------------------------------------------------------------------===// 21 22#include "LegalizeTypes.h" 23#include "llvm/Support/ErrorHandling.h" 24#include "llvm/Support/raw_ostream.h" 25using namespace llvm; 26 27/// GetFPLibCall - Return the right libcall for the given floating point type. 28static RTLIB::Libcall GetFPLibCall(EVT VT, 29 RTLIB::Libcall Call_F32, 30 RTLIB::Libcall Call_F64, 31 RTLIB::Libcall Call_F80, 32 RTLIB::Libcall Call_PPCF128) { 33 return 34 VT == MVT::f32 ? Call_F32 : 35 VT == MVT::f64 ? Call_F64 : 36 VT == MVT::f80 ? Call_F80 : 37 VT == MVT::ppcf128 ? Call_PPCF128 : 38 RTLIB::UNKNOWN_LIBCALL; 39} 40 41//===----------------------------------------------------------------------===// 42// Result Float to Integer Conversion. 43//===----------------------------------------------------------------------===// 44 45void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) { 46 DEBUG(errs() << "Soften float result " << ResNo << ": "; N->dump(&DAG); 47 errs() << "\n"); 48 SDValue R = SDValue(); 49 50 switch (N->getOpcode()) { 51 default: 52#ifndef NDEBUG 53 errs() << "SoftenFloatResult #" << ResNo << ": "; 54 N->dump(&DAG); errs() << "\n"; 55#endif 56 llvm_unreachable("Do not know how to soften the result of this operator!"); 57 58 case ISD::BIT_CONVERT: R = SoftenFloatRes_BIT_CONVERT(N); break; 59 case ISD::BUILD_PAIR: R = SoftenFloatRes_BUILD_PAIR(N); break; 60 case ISD::ConstantFP: 61 R = SoftenFloatRes_ConstantFP(cast<ConstantFPSDNode>(N)); 62 break; 63 case ISD::EXTRACT_VECTOR_ELT: 64 R = SoftenFloatRes_EXTRACT_VECTOR_ELT(N); break; 65 case ISD::FABS: R = SoftenFloatRes_FABS(N); break; 66 case ISD::FADD: R = SoftenFloatRes_FADD(N); break; 67 case ISD::FCEIL: R = SoftenFloatRes_FCEIL(N); break; 68 case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break; 69 case ISD::FCOS: R = SoftenFloatRes_FCOS(N); break; 70 case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break; 71 case ISD::FEXP: R = SoftenFloatRes_FEXP(N); break; 72 case ISD::FEXP2: R = SoftenFloatRes_FEXP2(N); break; 73 case ISD::FFLOOR: R = SoftenFloatRes_FFLOOR(N); break; 74 case ISD::FLOG: R = SoftenFloatRes_FLOG(N); break; 75 case ISD::FLOG2: R = SoftenFloatRes_FLOG2(N); break; 76 case ISD::FLOG10: R = SoftenFloatRes_FLOG10(N); break; 77 case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break; 78 case ISD::FNEARBYINT: R = SoftenFloatRes_FNEARBYINT(N); break; 79 case ISD::FNEG: R = SoftenFloatRes_FNEG(N); break; 80 case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break; 81 case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break; 82 case ISD::FPOW: R = SoftenFloatRes_FPOW(N); break; 83 case ISD::FPOWI: R = SoftenFloatRes_FPOWI(N); break; 84 case ISD::FREM: R = SoftenFloatRes_FREM(N); break; 85 case ISD::FRINT: R = SoftenFloatRes_FRINT(N); break; 86 case ISD::FSIN: R = SoftenFloatRes_FSIN(N); break; 87 case ISD::FSQRT: R = SoftenFloatRes_FSQRT(N); break; 88 case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break; 89 case ISD::FTRUNC: R = SoftenFloatRes_FTRUNC(N); break; 90 case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break; 91 case ISD::SELECT: R = SoftenFloatRes_SELECT(N); break; 92 case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N); break; 93 case ISD::SINT_TO_FP: 94 case ISD::UINT_TO_FP: R = SoftenFloatRes_XINT_TO_FP(N); break; 95 case ISD::UNDEF: R = SoftenFloatRes_UNDEF(N); break; 96 case ISD::VAARG: R = SoftenFloatRes_VAARG(N); break; 97 } 98 99 // If R is null, the sub-method took care of registering the result. 100 if (R.getNode()) 101 SetSoftenedFloat(SDValue(N, ResNo), R); 102} 103 104SDValue DAGTypeLegalizer::SoftenFloatRes_BIT_CONVERT(SDNode *N) { 105 return BitConvertToInteger(N->getOperand(0)); 106} 107 108SDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) { 109 // Convert the inputs to integers, and build a new pair out of them. 110 return DAG.getNode(ISD::BUILD_PAIR, N->getDebugLoc(), 111 TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)), 112 BitConvertToInteger(N->getOperand(0)), 113 BitConvertToInteger(N->getOperand(1))); 114} 115 116SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(ConstantFPSDNode *N) { 117 return DAG.getConstant(N->getValueAPF().bitcastToAPInt(), 118 TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0))); 119} 120 121SDValue DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode *N) { 122 SDValue NewOp = BitConvertVectorToIntegerVector(N->getOperand(0)); 123 return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N->getDebugLoc(), 124 NewOp.getValueType().getVectorElementType(), 125 NewOp, N->getOperand(1)); 126} 127 128SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) { 129 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 130 unsigned Size = NVT.getSizeInBits(); 131 132 // Mask = ~(1 << (Size-1)) 133 SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1), 134 NVT); 135 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 136 return DAG.getNode(ISD::AND, N->getDebugLoc(), NVT, Op, Mask); 137} 138 139SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) { 140 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 141 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 142 GetSoftenedFloat(N->getOperand(1)) }; 143 return MakeLibCall(GetFPLibCall(N->getValueType(0), 144 RTLIB::ADD_F32, 145 RTLIB::ADD_F64, 146 RTLIB::ADD_F80, 147 RTLIB::ADD_PPCF128), 148 NVT, Ops, 2, false, N->getDebugLoc()); 149} 150 151SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) { 152 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 153 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 154 return MakeLibCall(GetFPLibCall(N->getValueType(0), 155 RTLIB::CEIL_F32, 156 RTLIB::CEIL_F64, 157 RTLIB::CEIL_F80, 158 RTLIB::CEIL_PPCF128), 159 NVT, &Op, 1, false, N->getDebugLoc()); 160} 161 162SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { 163 SDValue LHS = GetSoftenedFloat(N->getOperand(0)); 164 SDValue RHS = BitConvertToInteger(N->getOperand(1)); 165 DebugLoc dl = N->getDebugLoc(); 166 167 EVT LVT = LHS.getValueType(); 168 EVT RVT = RHS.getValueType(); 169 170 unsigned LSize = LVT.getSizeInBits(); 171 unsigned RSize = RVT.getSizeInBits(); 172 173 // First get the sign bit of second operand. 174 SDValue SignBit = DAG.getNode(ISD::SHL, dl, RVT, DAG.getConstant(1, RVT), 175 DAG.getConstant(RSize - 1, 176 TLI.getShiftAmountTy())); 177 SignBit = DAG.getNode(ISD::AND, dl, RVT, RHS, SignBit); 178 179 // Shift right or sign-extend it if the two operands have different types. 180 int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits(); 181 if (SizeDiff > 0) { 182 SignBit = DAG.getNode(ISD::SRL, dl, RVT, SignBit, 183 DAG.getConstant(SizeDiff, TLI.getShiftAmountTy())); 184 SignBit = DAG.getNode(ISD::TRUNCATE, dl, LVT, SignBit); 185 } else if (SizeDiff < 0) { 186 SignBit = DAG.getNode(ISD::ANY_EXTEND, dl, LVT, SignBit); 187 SignBit = DAG.getNode(ISD::SHL, dl, LVT, SignBit, 188 DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy())); 189 } 190 191 // Clear the sign bit of the first operand. 192 SDValue Mask = DAG.getNode(ISD::SHL, dl, LVT, DAG.getConstant(1, LVT), 193 DAG.getConstant(LSize - 1, 194 TLI.getShiftAmountTy())); 195 Mask = DAG.getNode(ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, LVT)); 196 LHS = DAG.getNode(ISD::AND, dl, LVT, LHS, Mask); 197 198 // Or the value with the sign bit. 199 return DAG.getNode(ISD::OR, dl, LVT, LHS, SignBit); 200} 201 202SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) { 203 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 204 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 205 return MakeLibCall(GetFPLibCall(N->getValueType(0), 206 RTLIB::COS_F32, 207 RTLIB::COS_F64, 208 RTLIB::COS_F80, 209 RTLIB::COS_PPCF128), 210 NVT, &Op, 1, false, N->getDebugLoc()); 211} 212 213SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) { 214 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 215 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 216 GetSoftenedFloat(N->getOperand(1)) }; 217 return MakeLibCall(GetFPLibCall(N->getValueType(0), 218 RTLIB::DIV_F32, 219 RTLIB::DIV_F64, 220 RTLIB::DIV_F80, 221 RTLIB::DIV_PPCF128), 222 NVT, Ops, 2, false, N->getDebugLoc()); 223} 224 225SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) { 226 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 227 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 228 return MakeLibCall(GetFPLibCall(N->getValueType(0), 229 RTLIB::EXP_F32, 230 RTLIB::EXP_F64, 231 RTLIB::EXP_F80, 232 RTLIB::EXP_PPCF128), 233 NVT, &Op, 1, false, N->getDebugLoc()); 234} 235 236SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) { 237 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 238 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 239 return MakeLibCall(GetFPLibCall(N->getValueType(0), 240 RTLIB::EXP2_F32, 241 RTLIB::EXP2_F64, 242 RTLIB::EXP2_F80, 243 RTLIB::EXP2_PPCF128), 244 NVT, &Op, 1, false, N->getDebugLoc()); 245} 246 247SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) { 248 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 249 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 250 return MakeLibCall(GetFPLibCall(N->getValueType(0), 251 RTLIB::FLOOR_F32, 252 RTLIB::FLOOR_F64, 253 RTLIB::FLOOR_F80, 254 RTLIB::FLOOR_PPCF128), 255 NVT, &Op, 1, false, N->getDebugLoc()); 256} 257 258SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) { 259 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 260 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 261 return MakeLibCall(GetFPLibCall(N->getValueType(0), 262 RTLIB::LOG_F32, 263 RTLIB::LOG_F64, 264 RTLIB::LOG_F80, 265 RTLIB::LOG_PPCF128), 266 NVT, &Op, 1, false, N->getDebugLoc()); 267} 268 269SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) { 270 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 271 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 272 return MakeLibCall(GetFPLibCall(N->getValueType(0), 273 RTLIB::LOG2_F32, 274 RTLIB::LOG2_F64, 275 RTLIB::LOG2_F80, 276 RTLIB::LOG2_PPCF128), 277 NVT, &Op, 1, false, N->getDebugLoc()); 278} 279 280SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) { 281 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 282 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 283 return MakeLibCall(GetFPLibCall(N->getValueType(0), 284 RTLIB::LOG10_F32, 285 RTLIB::LOG10_F64, 286 RTLIB::LOG10_F80, 287 RTLIB::LOG10_PPCF128), 288 NVT, &Op, 1, false, N->getDebugLoc()); 289} 290 291SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { 292 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 293 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 294 GetSoftenedFloat(N->getOperand(1)) }; 295 return MakeLibCall(GetFPLibCall(N->getValueType(0), 296 RTLIB::MUL_F32, 297 RTLIB::MUL_F64, 298 RTLIB::MUL_F80, 299 RTLIB::MUL_PPCF128), 300 NVT, Ops, 2, false, N->getDebugLoc()); 301} 302 303SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) { 304 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 305 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 306 return MakeLibCall(GetFPLibCall(N->getValueType(0), 307 RTLIB::NEARBYINT_F32, 308 RTLIB::NEARBYINT_F64, 309 RTLIB::NEARBYINT_F80, 310 RTLIB::NEARBYINT_PPCF128), 311 NVT, &Op, 1, false, N->getDebugLoc()); 312} 313 314SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) { 315 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 316 // Expand Y = FNEG(X) -> Y = SUB -0.0, X 317 SDValue Ops[2] = { DAG.getConstantFP(-0.0, N->getValueType(0)), 318 GetSoftenedFloat(N->getOperand(0)) }; 319 return MakeLibCall(GetFPLibCall(N->getValueType(0), 320 RTLIB::SUB_F32, 321 RTLIB::SUB_F64, 322 RTLIB::SUB_F80, 323 RTLIB::SUB_PPCF128), 324 NVT, Ops, 2, false, N->getDebugLoc()); 325} 326 327SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) { 328 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 329 SDValue Op = N->getOperand(0); 330 RTLIB::Libcall LC = RTLIB::getFPEXT(Op.getValueType(), N->getValueType(0)); 331 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!"); 332 return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc()); 333} 334 335SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) { 336 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 337 SDValue Op = N->getOperand(0); 338 RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), N->getValueType(0)); 339 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND!"); 340 return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc()); 341} 342 343SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) { 344 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 345 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 346 GetSoftenedFloat(N->getOperand(1)) }; 347 return MakeLibCall(GetFPLibCall(N->getValueType(0), 348 RTLIB::POW_F32, 349 RTLIB::POW_F64, 350 RTLIB::POW_F80, 351 RTLIB::POW_PPCF128), 352 NVT, Ops, 2, false, N->getDebugLoc()); 353} 354 355SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) { 356 assert(N->getOperand(1).getValueType() == MVT::i32 && 357 "Unsupported power type!"); 358 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 359 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), N->getOperand(1) }; 360 return MakeLibCall(GetFPLibCall(N->getValueType(0), 361 RTLIB::POWI_F32, 362 RTLIB::POWI_F64, 363 RTLIB::POWI_F80, 364 RTLIB::POWI_PPCF128), 365 NVT, Ops, 2, false, N->getDebugLoc()); 366} 367 368SDValue DAGTypeLegalizer::SoftenFloatRes_FREM(SDNode *N) { 369 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 370 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 371 GetSoftenedFloat(N->getOperand(1)) }; 372 return MakeLibCall(GetFPLibCall(N->getValueType(0), 373 RTLIB::REM_F32, 374 RTLIB::REM_F64, 375 RTLIB::REM_F80, 376 RTLIB::REM_PPCF128), 377 NVT, Ops, 2, false, N->getDebugLoc()); 378} 379 380SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) { 381 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 382 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 383 return MakeLibCall(GetFPLibCall(N->getValueType(0), 384 RTLIB::RINT_F32, 385 RTLIB::RINT_F64, 386 RTLIB::RINT_F80, 387 RTLIB::RINT_PPCF128), 388 NVT, &Op, 1, false, N->getDebugLoc()); 389} 390 391SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) { 392 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 393 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 394 return MakeLibCall(GetFPLibCall(N->getValueType(0), 395 RTLIB::SIN_F32, 396 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 // Use the target specific return value for comparions lib calls. 641 EVT RetVT = TLI.getCmpLibcallReturnType(); 642 SDValue Ops[2] = { LHSInt, RHSInt }; 643 NewLHS = MakeLibCall(LC1, RetVT, Ops, 2, false/*sign irrelevant*/, dl); 644 NewRHS = DAG.getConstant(0, RetVT); 645 CCCode = TLI.getCmpLibcallCC(LC1); 646 if (LC2 != RTLIB::UNKNOWN_LIBCALL) { 647 SDValue Tmp = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(RetVT), 648 NewLHS, NewRHS, DAG.getCondCode(CCCode)); 649 NewLHS = MakeLibCall(LC2, RetVT, Ops, 2, false/*sign irrelevant*/, dl); 650 NewLHS = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(RetVT), NewLHS, 651 NewRHS, DAG.getCondCode(TLI.getCmpLibcallCC(LC2))); 652 NewLHS = DAG.getNode(ISD::OR, dl, Tmp.getValueType(), Tmp, NewLHS); 653 NewRHS = SDValue(); 654 } 655} 656 657SDValue DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) { 658 return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), N->getValueType(0), 659 GetSoftenedFloat(N->getOperand(0))); 660} 661 662SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) { 663 EVT SVT = N->getOperand(0).getValueType(); 664 EVT RVT = N->getValueType(0); 665 666 RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, RVT); 667 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall"); 668 669 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 670 return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc()); 671} 672 673SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) { 674 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); 675 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get(); 676 SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 677 678 // If SoftenSetCCOperands returned a scalar, we need to compare the result 679 // against zero to select between true and false values. 680 if (NewRHS.getNode() == 0) { 681 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 682 CCCode = ISD::SETNE; 683 } 684 685 // Update N to have the operands specified. 686 return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 687 DAG.getCondCode(CCCode), NewLHS, NewRHS, 688 N->getOperand(4)); 689} 690 691SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode *N) { 692 EVT RVT = N->getValueType(0); 693 RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); 694 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); 695 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 696 return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc()); 697} 698 699SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) { 700 EVT RVT = N->getValueType(0); 701 RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); 702 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); 703 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 704 return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc()); 705} 706 707SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) { 708 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 709 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get(); 710 SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 711 712 // If SoftenSetCCOperands returned a scalar, we need to compare the result 713 // against zero to select between true and false values. 714 if (NewRHS.getNode() == 0) { 715 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 716 CCCode = ISD::SETNE; 717 } 718 719 // Update N to have the operands specified. 720 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 721 N->getOperand(2), N->getOperand(3), 722 DAG.getCondCode(CCCode)); 723} 724 725SDValue DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) { 726 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 727 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); 728 SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 729 730 // If SoftenSetCCOperands returned a scalar, use it. 731 if (NewRHS.getNode() == 0) { 732 assert(NewLHS.getValueType() == N->getValueType(0) && 733 "Unexpected setcc expansion!"); 734 return NewLHS; 735 } 736 737 // Otherwise, update N to have the operands specified. 738 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 739 DAG.getCondCode(CCCode)); 740} 741 742SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) { 743 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); 744 assert(OpNo == 1 && "Can only soften the stored value!"); 745 StoreSDNode *ST = cast<StoreSDNode>(N); 746 SDValue Val = ST->getValue(); 747 DebugLoc dl = N->getDebugLoc(); 748 749 if (ST->isTruncatingStore()) 750 // Do an FP_ROUND followed by a non-truncating store. 751 Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, dl, ST->getMemoryVT(), 752 Val, DAG.getIntPtrConstant(0))); 753 else 754 Val = GetSoftenedFloat(Val); 755 756 return DAG.getStore(ST->getChain(), dl, Val, ST->getBasePtr(), 757 ST->getSrcValue(), ST->getSrcValueOffset(), 758 ST->isVolatile(), ST->getAlignment()); 759} 760 761 762//===----------------------------------------------------------------------===// 763// Float Result Expansion 764//===----------------------------------------------------------------------===// 765 766/// ExpandFloatResult - This method is called when the specified result of the 767/// specified node is found to need expansion. At this point, the node may also 768/// have invalid operands or may have other results that need promotion, we just 769/// know that (at least) one result needs expansion. 770void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { 771 DEBUG(errs() << "Expand float result: "; N->dump(&DAG); errs() << "\n"); 772 SDValue Lo, Hi; 773 Lo = Hi = SDValue(); 774 775 // See if the target wants to custom expand this node. 776 if (CustomLowerNode(N, N->getValueType(ResNo), true)) 777 return; 778 779 switch (N->getOpcode()) { 780 default: 781#ifndef NDEBUG 782 errs() << "ExpandFloatResult #" << ResNo << ": "; 783 N->dump(&DAG); errs() << "\n"; 784#endif 785 llvm_unreachable("Do not know how to expand the result of this operator!"); 786 787 case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break; 788 case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; 789 case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; 790 case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; 791 792 case ISD::BIT_CONVERT: ExpandRes_BIT_CONVERT(N, Lo, Hi); break; 793 case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break; 794 case ISD::EXTRACT_ELEMENT: ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break; 795 case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; 796 case ISD::VAARG: ExpandRes_VAARG(N, Lo, Hi); break; 797 798 case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break; 799 case ISD::FABS: ExpandFloatRes_FABS(N, Lo, Hi); break; 800 case ISD::FADD: ExpandFloatRes_FADD(N, Lo, Hi); break; 801 case ISD::FCEIL: ExpandFloatRes_FCEIL(N, Lo, Hi); break; 802 case ISD::FCOS: ExpandFloatRes_FCOS(N, Lo, Hi); break; 803 case ISD::FDIV: ExpandFloatRes_FDIV(N, Lo, Hi); break; 804 case ISD::FEXP: ExpandFloatRes_FEXP(N, Lo, Hi); break; 805 case ISD::FEXP2: ExpandFloatRes_FEXP2(N, Lo, Hi); break; 806 case ISD::FFLOOR: ExpandFloatRes_FFLOOR(N, Lo, Hi); break; 807 case ISD::FLOG: ExpandFloatRes_FLOG(N, Lo, Hi); break; 808 case ISD::FLOG2: ExpandFloatRes_FLOG2(N, Lo, Hi); break; 809 case ISD::FLOG10: ExpandFloatRes_FLOG10(N, Lo, Hi); break; 810 case ISD::FMUL: ExpandFloatRes_FMUL(N, Lo, Hi); break; 811 case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT(N, Lo, Hi); break; 812 case ISD::FNEG: ExpandFloatRes_FNEG(N, Lo, Hi); break; 813 case ISD::FP_EXTEND: ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break; 814 case ISD::FPOW: ExpandFloatRes_FPOW(N, Lo, Hi); break; 815 case ISD::FPOWI: ExpandFloatRes_FPOWI(N, Lo, Hi); break; 816 case ISD::FRINT: ExpandFloatRes_FRINT(N, Lo, Hi); break; 817 case ISD::FSIN: ExpandFloatRes_FSIN(N, Lo, Hi); break; 818 case ISD::FSQRT: ExpandFloatRes_FSQRT(N, Lo, Hi); break; 819 case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break; 820 case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break; 821 case ISD::LOAD: ExpandFloatRes_LOAD(N, Lo, Hi); break; 822 case ISD::SINT_TO_FP: 823 case ISD::UINT_TO_FP: ExpandFloatRes_XINT_TO_FP(N, Lo, Hi); break; 824 } 825 826 // If Lo/Hi is null, the sub-method took care of registering results etc. 827 if (Lo.getNode()) 828 SetExpandedFloat(SDValue(N, ResNo), Lo, Hi); 829} 830 831void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo, 832 SDValue &Hi) { 833 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 834 assert(NVT.getSizeInBits() == integerPartWidth && 835 "Do not know how to expand this float constant!"); 836 APInt C = cast<ConstantFPSDNode>(N)->getValueAPF().bitcastToAPInt(); 837 Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, 838 &C.getRawData()[1])), NVT); 839 Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, 840 &C.getRawData()[0])), NVT); 841} 842 843void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo, 844 SDValue &Hi) { 845 assert(N->getValueType(0) == MVT::ppcf128 && 846 "Logic only correct for ppcf128!"); 847 DebugLoc dl = N->getDebugLoc(); 848 SDValue Tmp; 849 GetExpandedFloat(N->getOperand(0), Lo, Tmp); 850 Hi = DAG.getNode(ISD::FABS, dl, Tmp.getValueType(), Tmp); 851 // Lo = Hi==fabs(Hi) ? Lo : -Lo; 852 Lo = DAG.getNode(ISD::SELECT_CC, dl, Lo.getValueType(), Tmp, Hi, Lo, 853 DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo), 854 DAG.getCondCode(ISD::SETEQ)); 855} 856 857void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDValue &Lo, 858 SDValue &Hi) { 859 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 860 RTLIB::ADD_F32, RTLIB::ADD_F64, 861 RTLIB::ADD_F80, RTLIB::ADD_PPCF128), 862 N, false); 863 GetPairElements(Call, Lo, Hi); 864} 865 866void DAGTypeLegalizer::ExpandFloatRes_FCEIL(SDNode *N, 867 SDValue &Lo, SDValue &Hi) { 868 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 869 RTLIB::CEIL_F32, RTLIB::CEIL_F64, 870 RTLIB::CEIL_F80, RTLIB::CEIL_PPCF128), 871 N, false); 872 GetPairElements(Call, Lo, Hi); 873} 874 875void DAGTypeLegalizer::ExpandFloatRes_FCOS(SDNode *N, 876 SDValue &Lo, SDValue &Hi) { 877 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 878 RTLIB::COS_F32, RTLIB::COS_F64, 879 RTLIB::COS_F80, RTLIB::COS_PPCF128), 880 N, false); 881 GetPairElements(Call, Lo, Hi); 882} 883 884void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo, 885 SDValue &Hi) { 886 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 887 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 888 RTLIB::DIV_F32, 889 RTLIB::DIV_F64, 890 RTLIB::DIV_F80, 891 RTLIB::DIV_PPCF128), 892 N->getValueType(0), Ops, 2, false, 893 N->getDebugLoc()); 894 GetPairElements(Call, Lo, Hi); 895} 896 897void DAGTypeLegalizer::ExpandFloatRes_FEXP(SDNode *N, 898 SDValue &Lo, SDValue &Hi) { 899 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 900 RTLIB::EXP_F32, RTLIB::EXP_F64, 901 RTLIB::EXP_F80, RTLIB::EXP_PPCF128), 902 N, false); 903 GetPairElements(Call, Lo, Hi); 904} 905 906void DAGTypeLegalizer::ExpandFloatRes_FEXP2(SDNode *N, 907 SDValue &Lo, SDValue &Hi) { 908 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 909 RTLIB::EXP2_F32, RTLIB::EXP2_F64, 910 RTLIB::EXP2_F80, RTLIB::EXP2_PPCF128), 911 N, false); 912 GetPairElements(Call, Lo, Hi); 913} 914 915void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(SDNode *N, 916 SDValue &Lo, SDValue &Hi) { 917 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 918 RTLIB::FLOOR_F32,RTLIB::FLOOR_F64, 919 RTLIB::FLOOR_F80,RTLIB::FLOOR_PPCF128), 920 N, false); 921 GetPairElements(Call, Lo, Hi); 922} 923 924void DAGTypeLegalizer::ExpandFloatRes_FLOG(SDNode *N, 925 SDValue &Lo, SDValue &Hi) { 926 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 927 RTLIB::LOG_F32, RTLIB::LOG_F64, 928 RTLIB::LOG_F80, RTLIB::LOG_PPCF128), 929 N, false); 930 GetPairElements(Call, Lo, Hi); 931} 932 933void DAGTypeLegalizer::ExpandFloatRes_FLOG2(SDNode *N, 934 SDValue &Lo, SDValue &Hi) { 935 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 936 RTLIB::LOG2_F32, RTLIB::LOG2_F64, 937 RTLIB::LOG2_F80, RTLIB::LOG2_PPCF128), 938 N, false); 939 GetPairElements(Call, Lo, Hi); 940} 941 942void DAGTypeLegalizer::ExpandFloatRes_FLOG10(SDNode *N, 943 SDValue &Lo, SDValue &Hi) { 944 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 945 RTLIB::LOG10_F32,RTLIB::LOG10_F64, 946 RTLIB::LOG10_F80,RTLIB::LOG10_PPCF128), 947 N, false); 948 GetPairElements(Call, Lo, Hi); 949} 950 951void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo, 952 SDValue &Hi) { 953 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 954 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 955 RTLIB::MUL_F32, 956 RTLIB::MUL_F64, 957 RTLIB::MUL_F80, 958 RTLIB::MUL_PPCF128), 959 N->getValueType(0), Ops, 2, false, 960 N->getDebugLoc()); 961 GetPairElements(Call, Lo, Hi); 962} 963 964void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode *N, 965 SDValue &Lo, SDValue &Hi) { 966 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 967 RTLIB::NEARBYINT_F32, 968 RTLIB::NEARBYINT_F64, 969 RTLIB::NEARBYINT_F80, 970 RTLIB::NEARBYINT_PPCF128), 971 N, false); 972 GetPairElements(Call, Lo, Hi); 973} 974 975void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo, 976 SDValue &Hi) { 977 DebugLoc dl = N->getDebugLoc(); 978 GetExpandedFloat(N->getOperand(0), Lo, Hi); 979 Lo = DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo); 980 Hi = DAG.getNode(ISD::FNEG, dl, Hi.getValueType(), Hi); 981} 982 983void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo, 984 SDValue &Hi) { 985 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), N->getValueType(0)); 986 Hi = DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), NVT, N->getOperand(0)); 987 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); 988} 989 990void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode *N, 991 SDValue &Lo, SDValue &Hi) { 992 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 993 RTLIB::POW_F32, RTLIB::POW_F64, 994 RTLIB::POW_F80, RTLIB::POW_PPCF128), 995 N, false); 996 GetPairElements(Call, Lo, Hi); 997} 998 999void DAGTypeLegalizer::ExpandFloatRes_FPOWI(SDNode *N, 1000 SDValue &Lo, SDValue &Hi) { 1001 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 1002 RTLIB::POWI_F32, RTLIB::POWI_F64, 1003 RTLIB::POWI_F80, RTLIB::POWI_PPCF128), 1004 N, false); 1005 GetPairElements(Call, Lo, Hi); 1006} 1007 1008void DAGTypeLegalizer::ExpandFloatRes_FRINT(SDNode *N, 1009 SDValue &Lo, SDValue &Hi) { 1010 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 1011 RTLIB::RINT_F32, RTLIB::RINT_F64, 1012 RTLIB::RINT_F80, RTLIB::RINT_PPCF128), 1013 N, false); 1014 GetPairElements(Call, Lo, Hi); 1015} 1016 1017void DAGTypeLegalizer::ExpandFloatRes_FSIN(SDNode *N, 1018 SDValue &Lo, SDValue &Hi) { 1019 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 1020 RTLIB::SIN_F32, RTLIB::SIN_F64, 1021 RTLIB::SIN_F80, RTLIB::SIN_PPCF128), 1022 N, false); 1023 GetPairElements(Call, Lo, Hi); 1024} 1025 1026void DAGTypeLegalizer::ExpandFloatRes_FSQRT(SDNode *N, 1027 SDValue &Lo, SDValue &Hi) { 1028 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 1029 RTLIB::SQRT_F32, RTLIB::SQRT_F64, 1030 RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128), 1031 N, false); 1032 GetPairElements(Call, Lo, Hi); 1033} 1034 1035void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo, 1036 SDValue &Hi) { 1037 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 1038 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 1039 RTLIB::SUB_F32, 1040 RTLIB::SUB_F64, 1041 RTLIB::SUB_F80, 1042 RTLIB::SUB_PPCF128), 1043 N->getValueType(0), Ops, 2, false, 1044 N->getDebugLoc()); 1045 GetPairElements(Call, Lo, Hi); 1046} 1047 1048void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(SDNode *N, 1049 SDValue &Lo, SDValue &Hi) { 1050 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 1051 RTLIB::TRUNC_F32, RTLIB::TRUNC_F64, 1052 RTLIB::TRUNC_F80, RTLIB::TRUNC_PPCF128), 1053 N, false); 1054 GetPairElements(Call, Lo, Hi); 1055} 1056 1057void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo, 1058 SDValue &Hi) { 1059 if (ISD::isNormalLoad(N)) { 1060 ExpandRes_NormalLoad(N, Lo, Hi); 1061 return; 1062 } 1063 1064 assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!"); 1065 LoadSDNode *LD = cast<LoadSDNode>(N); 1066 SDValue Chain = LD->getChain(); 1067 SDValue Ptr = LD->getBasePtr(); 1068 DebugLoc dl = N->getDebugLoc(); 1069 1070 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), LD->getValueType(0)); 1071 assert(NVT.isByteSized() && "Expanded type not byte sized!"); 1072 assert(LD->getMemoryVT().bitsLE(NVT) && "Float type not round?"); 1073 1074 Hi = DAG.getExtLoad(LD->getExtensionType(), dl, NVT, Chain, Ptr, 1075 LD->getSrcValue(), LD->getSrcValueOffset(), 1076 LD->getMemoryVT(), 1077 LD->isVolatile(), LD->getAlignment()); 1078 1079 // Remember the chain. 1080 Chain = Hi.getValue(1); 1081 1082 // The low part is zero. 1083 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); 1084 1085 // Modified the chain - switch anything that used the old chain to use the 1086 // new one. 1087 ReplaceValueWith(SDValue(LD, 1), Chain); 1088} 1089 1090void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, 1091 SDValue &Hi) { 1092 assert(N->getValueType(0) == MVT::ppcf128 && "Unsupported XINT_TO_FP!"); 1093 EVT VT = N->getValueType(0); 1094 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), VT); 1095 SDValue Src = N->getOperand(0); 1096 EVT SrcVT = Src.getValueType(); 1097 bool isSigned = N->getOpcode() == ISD::SINT_TO_FP; 1098 DebugLoc dl = N->getDebugLoc(); 1099 1100 // First do an SINT_TO_FP, whether the original was signed or unsigned. 1101 // When promoting partial word types to i32 we must honor the signedness, 1102 // though. 1103 if (SrcVT.bitsLE(MVT::i32)) { 1104 // The integer can be represented exactly in an f64. 1105 Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, 1106 MVT::i32, Src); 1107 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); 1108 Hi = DAG.getNode(ISD::SINT_TO_FP, dl, NVT, Src); 1109 } else { 1110 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 1111 if (SrcVT.bitsLE(MVT::i64)) { 1112 Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, 1113 MVT::i64, Src); 1114 LC = RTLIB::SINTTOFP_I64_PPCF128; 1115 } else if (SrcVT.bitsLE(MVT::i128)) { 1116 Src = DAG.getNode(ISD::SIGN_EXTEND, dl, MVT::i128, Src); 1117 LC = RTLIB::SINTTOFP_I128_PPCF128; 1118 } 1119 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!"); 1120 1121 Hi = MakeLibCall(LC, VT, &Src, 1, true, dl); 1122 GetPairElements(Hi, Lo, Hi); 1123 } 1124 1125 if (isSigned) 1126 return; 1127 1128 // Unsigned - fix up the SINT_TO_FP value just calculated. 1129 Hi = DAG.getNode(ISD::BUILD_PAIR, dl, VT, Lo, Hi); 1130 SrcVT = Src.getValueType(); 1131 1132 // x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128. 1133 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 }; 1134 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 }; 1135 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 }; 1136 const uint64_t *Parts = 0; 1137 1138 switch (SrcVT.getSimpleVT().SimpleTy) { 1139 default: 1140 assert(false && "Unsupported UINT_TO_FP!"); 1141 case MVT::i32: 1142 Parts = TwoE32; 1143 break; 1144 case MVT::i64: 1145 Parts = TwoE64; 1146 break; 1147 case MVT::i128: 1148 Parts = TwoE128; 1149 break; 1150 } 1151 1152 Lo = DAG.getNode(ISD::FADD, dl, VT, Hi, 1153 DAG.getConstantFP(APFloat(APInt(128, 2, Parts)), 1154 MVT::ppcf128)); 1155 Lo = DAG.getNode(ISD::SELECT_CC, dl, VT, Src, DAG.getConstant(0, SrcVT), 1156 Lo, Hi, DAG.getCondCode(ISD::SETLT)); 1157 GetPairElements(Lo, Lo, Hi); 1158} 1159 1160 1161//===----------------------------------------------------------------------===// 1162// Float Operand Expansion 1163//===----------------------------------------------------------------------===// 1164 1165/// ExpandFloatOperand - This method is called when the specified operand of the 1166/// specified node is found to need expansion. At this point, all of the result 1167/// types of the node are known to be legal, but other operands of the node may 1168/// need promotion or expansion as well as the specified one. 1169bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) { 1170 DEBUG(errs() << "Expand float operand: "; N->dump(&DAG); errs() << "\n"); 1171 SDValue Res = SDValue(); 1172 1173 if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) 1174 == TargetLowering::Custom) 1175 Res = TLI.LowerOperation(SDValue(N, 0), DAG); 1176 1177 if (Res.getNode() == 0) { 1178 switch (N->getOpcode()) { 1179 default: 1180 #ifndef NDEBUG 1181 errs() << "ExpandFloatOperand Op #" << OpNo << ": "; 1182 N->dump(&DAG); errs() << "\n"; 1183 #endif 1184 llvm_unreachable("Do not know how to expand this operator's operand!"); 1185 1186 case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break; 1187 case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; 1188 case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; 1189 1190 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(N); break; 1191 case ISD::FP_ROUND: Res = ExpandFloatOp_FP_ROUND(N); break; 1192 case ISD::FP_TO_SINT: Res = ExpandFloatOp_FP_TO_SINT(N); break; 1193 case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_UINT(N); break; 1194 case ISD::SELECT_CC: Res = ExpandFloatOp_SELECT_CC(N); break; 1195 case ISD::SETCC: Res = ExpandFloatOp_SETCC(N); break; 1196 case ISD::STORE: Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N), 1197 OpNo); break; 1198 } 1199 } 1200 1201 // If the result is null, the sub-method took care of registering results etc. 1202 if (!Res.getNode()) return false; 1203 1204 // If the result is N, the sub-method updated N in place. Tell the legalizer 1205 // core about this. 1206 if (Res.getNode() == N) 1207 return true; 1208 1209 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 1210 "Invalid operand expansion"); 1211 1212 ReplaceValueWith(SDValue(N, 0), Res); 1213 return false; 1214} 1215 1216/// FloatExpandSetCCOperands - Expand the operands of a comparison. This code 1217/// is shared among BR_CC, SELECT_CC, and SETCC handlers. 1218void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS, 1219 SDValue &NewRHS, 1220 ISD::CondCode &CCCode, 1221 DebugLoc dl) { 1222 SDValue LHSLo, LHSHi, RHSLo, RHSHi; 1223 GetExpandedFloat(NewLHS, LHSLo, LHSHi); 1224 GetExpandedFloat(NewRHS, RHSLo, RHSHi); 1225 1226 EVT VT = NewLHS.getValueType(); 1227 assert(VT == MVT::ppcf128 && "Unsupported setcc type!"); 1228 1229 // FIXME: This generated code sucks. We want to generate 1230 // FCMPU crN, hi1, hi2 1231 // BNE crN, L: 1232 // FCMPU crN, lo1, lo2 1233 // The following can be improved, but not that much. 1234 SDValue Tmp1, Tmp2, Tmp3; 1235 Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), 1236 LHSHi, RHSHi, ISD::SETOEQ); 1237 Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()), 1238 LHSLo, RHSLo, CCCode); 1239 Tmp3 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2); 1240 Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), 1241 LHSHi, RHSHi, ISD::SETUNE); 1242 Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), 1243 LHSHi, RHSHi, CCCode); 1244 Tmp1 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2); 1245 NewLHS = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp3); 1246 NewRHS = SDValue(); // LHS is the result, not a compare. 1247} 1248 1249SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) { 1250 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); 1251 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get(); 1252 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 1253 1254 // If ExpandSetCCOperands returned a scalar, we need to compare the result 1255 // against zero to select between true and false values. 1256 if (NewRHS.getNode() == 0) { 1257 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 1258 CCCode = ISD::SETNE; 1259 } 1260 1261 // Update N to have the operands specified. 1262 return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 1263 DAG.getCondCode(CCCode), NewLHS, NewRHS, 1264 N->getOperand(4)); 1265} 1266 1267SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) { 1268 assert(N->getOperand(0).getValueType() == MVT::ppcf128 && 1269 "Logic only correct for ppcf128!"); 1270 SDValue Lo, Hi; 1271 GetExpandedFloat(N->getOperand(0), Lo, Hi); 1272 // Round it the rest of the way (e.g. to f32) if needed. 1273 return DAG.getNode(ISD::FP_ROUND, N->getDebugLoc(), 1274 N->getValueType(0), Hi, N->getOperand(1)); 1275} 1276 1277SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { 1278 EVT RVT = N->getValueType(0); 1279 DebugLoc dl = N->getDebugLoc(); 1280 1281 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on 1282 // PPC (the libcall is not available). FIXME: Do this in a less hacky way. 1283 if (RVT == MVT::i32) { 1284 assert(N->getOperand(0).getValueType() == MVT::ppcf128 && 1285 "Logic only correct for ppcf128!"); 1286 SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, dl, MVT::ppcf128, 1287 N->getOperand(0), DAG.getValueType(MVT::f64)); 1288 Res = DAG.getNode(ISD::FP_ROUND, dl, MVT::f64, Res, 1289 DAG.getIntPtrConstant(1)); 1290 return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res); 1291 } 1292 1293 RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); 1294 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); 1295 return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false, dl); 1296} 1297 1298SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { 1299 EVT RVT = N->getValueType(0); 1300 DebugLoc dl = N->getDebugLoc(); 1301 1302 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on 1303 // PPC (the libcall is not available). FIXME: Do this in a less hacky way. 1304 if (RVT == MVT::i32) { 1305 assert(N->getOperand(0).getValueType() == MVT::ppcf128 && 1306 "Logic only correct for ppcf128!"); 1307 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0}; 1308 APFloat APF = APFloat(APInt(128, 2, TwoE31)); 1309 SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128); 1310 // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X 1311 // FIXME: generated code sucks. 1312 return DAG.getNode(ISD::SELECT_CC, dl, MVT::i32, N->getOperand(0), Tmp, 1313 DAG.getNode(ISD::ADD, dl, MVT::i32, 1314 DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, 1315 DAG.getNode(ISD::FSUB, dl, 1316 MVT::ppcf128, 1317 N->getOperand(0), 1318 Tmp)), 1319 DAG.getConstant(0x80000000, MVT::i32)), 1320 DAG.getNode(ISD::FP_TO_SINT, dl, 1321 MVT::i32, N->getOperand(0)), 1322 DAG.getCondCode(ISD::SETGE)); 1323 } 1324 1325 RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); 1326 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); 1327 return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false, dl); 1328} 1329 1330SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) { 1331 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 1332 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get(); 1333 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 1334 1335 // If ExpandSetCCOperands returned a scalar, we need to compare the result 1336 // against zero to select between true and false values. 1337 if (NewRHS.getNode() == 0) { 1338 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 1339 CCCode = ISD::SETNE; 1340 } 1341 1342 // Update N to have the operands specified. 1343 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 1344 N->getOperand(2), N->getOperand(3), 1345 DAG.getCondCode(CCCode)); 1346} 1347 1348SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) { 1349 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 1350 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); 1351 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); 1352 1353 // If ExpandSetCCOperands returned a scalar, use it. 1354 if (NewRHS.getNode() == 0) { 1355 assert(NewLHS.getValueType() == N->getValueType(0) && 1356 "Unexpected setcc expansion!"); 1357 return NewLHS; 1358 } 1359 1360 // Otherwise, update N to have the operands specified. 1361 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 1362 DAG.getCondCode(CCCode)); 1363} 1364 1365SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) { 1366 if (ISD::isNormalStore(N)) 1367 return ExpandOp_NormalStore(N, OpNo); 1368 1369 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); 1370 assert(OpNo == 1 && "Can only expand the stored value so far"); 1371 StoreSDNode *ST = cast<StoreSDNode>(N); 1372 1373 SDValue Chain = ST->getChain(); 1374 SDValue Ptr = ST->getBasePtr(); 1375 1376 EVT NVT = TLI.getTypeToTransformTo(*DAG.getContext(), ST->getValue().getValueType()); 1377 assert(NVT.isByteSized() && "Expanded type not byte sized!"); 1378 assert(ST->getMemoryVT().bitsLE(NVT) && "Float type not round?"); 1379 1380 SDValue Lo, Hi; 1381 GetExpandedOp(ST->getValue(), Lo, Hi); 1382 1383 return DAG.getTruncStore(Chain, N->getDebugLoc(), Hi, Ptr, 1384 ST->getSrcValue(), ST->getSrcValueOffset(), 1385 ST->getMemoryVT(), 1386 ST->isVolatile(), ST->getAlignment()); 1387} 1388