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