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