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