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