LegalizeFloatTypes.cpp revision 1497b52861fa267815ae822ce247ca74746ef211
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. Tell the legalizer 511 // core about this. 512 if (Res.getNode() == N) 513 return true; 514 515 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 516 "Invalid operand expansion"); 517 518 ReplaceValueWith(SDValue(N, 0), Res); 519 return false; 520} 521 522/// SoftenSetCCOperands - Soften the operands of a comparison. This code is 523/// shared among BR_CC, SELECT_CC, and SETCC handlers. 524void DAGTypeLegalizer::SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, 525 ISD::CondCode &CCCode) { 526 SDValue LHSInt = GetSoftenedFloat(NewLHS); 527 SDValue RHSInt = GetSoftenedFloat(NewRHS); 528 MVT VT = NewLHS.getValueType(); 529 530 assert((VT == MVT::f32 || VT == MVT::f64) && "Unsupported setcc type!"); 531 532 // Expand into one or more soft-fp libcall(s). 533 RTLIB::Libcall LC1 = RTLIB::UNKNOWN_LIBCALL, LC2 = RTLIB::UNKNOWN_LIBCALL; 534 switch (CCCode) { 535 case ISD::SETEQ: 536 case ISD::SETOEQ: 537 LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64; 538 break; 539 case ISD::SETNE: 540 case ISD::SETUNE: 541 LC1 = (VT == MVT::f32) ? RTLIB::UNE_F32 : RTLIB::UNE_F64; 542 break; 543 case ISD::SETGE: 544 case ISD::SETOGE: 545 LC1 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64; 546 break; 547 case ISD::SETLT: 548 case ISD::SETOLT: 549 LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64; 550 break; 551 case ISD::SETLE: 552 case ISD::SETOLE: 553 LC1 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64; 554 break; 555 case ISD::SETGT: 556 case ISD::SETOGT: 557 LC1 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64; 558 break; 559 case ISD::SETUO: 560 LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64; 561 break; 562 case ISD::SETO: 563 LC1 = (VT == MVT::f32) ? RTLIB::O_F32 : RTLIB::O_F64; 564 break; 565 default: 566 LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64; 567 switch (CCCode) { 568 case ISD::SETONE: 569 // SETONE = SETOLT | SETOGT 570 LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64; 571 // Fallthrough 572 case ISD::SETUGT: 573 LC2 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64; 574 break; 575 case ISD::SETUGE: 576 LC2 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64; 577 break; 578 case ISD::SETULT: 579 LC2 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64; 580 break; 581 case ISD::SETULE: 582 LC2 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64; 583 break; 584 case ISD::SETUEQ: 585 LC2 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64; 586 break; 587 default: assert(false && "Do not know how to soften this setcc!"); 588 } 589 } 590 591 MVT RetVT = MVT::i32; // FIXME: is this the correct return type? 592 SDValue Ops[2] = { LHSInt, RHSInt }; 593 NewLHS = MakeLibCall(LC1, RetVT, Ops, 2, false/*sign irrelevant*/); 594 NewRHS = DAG.getConstant(0, RetVT); 595 CCCode = TLI.getCmpLibcallCC(LC1); 596 if (LC2 != RTLIB::UNKNOWN_LIBCALL) { 597 SDValue Tmp = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(RetVT), 598 NewLHS, NewRHS, DAG.getCondCode(CCCode)); 599 NewLHS = MakeLibCall(LC2, RetVT, Ops, 2, false/*sign irrelevant*/); 600 NewLHS = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(RetVT), NewLHS, 601 NewRHS, DAG.getCondCode(TLI.getCmpLibcallCC(LC2))); 602 NewLHS = DAG.getNode(ISD::OR, Tmp.getValueType(), Tmp, NewLHS); 603 NewRHS = SDValue(); 604 } 605} 606 607SDValue DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) { 608 return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), 609 GetSoftenedFloat(N->getOperand(0))); 610} 611 612SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) { 613 MVT SVT = N->getOperand(0).getValueType(); 614 MVT RVT = N->getValueType(0); 615 616 RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, RVT); 617 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall"); 618 619 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 620 return MakeLibCall(LC, RVT, &Op, 1, false); 621} 622 623SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) { 624 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); 625 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get(); 626 SoftenSetCCOperands(NewLHS, NewRHS, CCCode); 627 628 // If SoftenSetCCOperands returned a scalar, we need to compare the result 629 // against zero to select between true and false values. 630 if (NewRHS.getNode() == 0) { 631 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 632 CCCode = ISD::SETNE; 633 } 634 635 // Update N to have the operands specified. 636 return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 637 DAG.getCondCode(CCCode), NewLHS, NewRHS, 638 N->getOperand(4)); 639} 640 641SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode *N) { 642 MVT RVT = N->getValueType(0); 643 RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); 644 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); 645 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 646 return MakeLibCall(LC, RVT, &Op, 1, false); 647} 648 649SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) { 650 MVT RVT = N->getValueType(0); 651 RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); 652 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); 653 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 654 return MakeLibCall(LC, RVT, &Op, 1, false); 655} 656 657SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) { 658 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 659 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get(); 660 SoftenSetCCOperands(NewLHS, NewRHS, CCCode); 661 662 // If SoftenSetCCOperands returned a scalar, we need to compare the result 663 // against zero to select between true and false values. 664 if (NewRHS.getNode() == 0) { 665 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 666 CCCode = ISD::SETNE; 667 } 668 669 // Update N to have the operands specified. 670 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 671 N->getOperand(2), N->getOperand(3), 672 DAG.getCondCode(CCCode)); 673} 674 675SDValue DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) { 676 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 677 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); 678 SoftenSetCCOperands(NewLHS, NewRHS, CCCode); 679 680 // If SoftenSetCCOperands returned a scalar, use it. 681 if (NewRHS.getNode() == 0) { 682 assert(NewLHS.getValueType() == N->getValueType(0) && 683 "Unexpected setcc expansion!"); 684 return NewLHS; 685 } 686 687 // Otherwise, update N to have the operands specified. 688 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 689 DAG.getCondCode(CCCode)); 690} 691 692SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) { 693 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); 694 assert(OpNo == 1 && "Can only soften the stored value!"); 695 StoreSDNode *ST = cast<StoreSDNode>(N); 696 SDValue Val = ST->getValue(); 697 698 if (ST->isTruncatingStore()) 699 // Do an FP_ROUND followed by a non-truncating store. 700 Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, ST->getMemoryVT(), 701 Val, DAG.getIntPtrConstant(0))); 702 else 703 Val = GetSoftenedFloat(Val); 704 705 return DAG.getStore(ST->getChain(), Val, ST->getBasePtr(), 706 ST->getSrcValue(), ST->getSrcValueOffset(), 707 ST->isVolatile(), ST->getAlignment()); 708} 709 710 711//===----------------------------------------------------------------------===// 712// Float Result Expansion 713//===----------------------------------------------------------------------===// 714 715/// ExpandFloatResult - This method is called when the specified result of the 716/// specified node is found to need expansion. At this point, the node may also 717/// have invalid operands or may have other results that need promotion, we just 718/// know that (at least) one result needs expansion. 719void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { 720 DEBUG(cerr << "Expand float result: "; N->dump(&DAG); cerr << "\n"); 721 SDValue Lo, Hi; 722 Lo = Hi = SDValue(); 723 724 // See if the target wants to custom expand this node. 725 if (CustomLowerResults(N, N->getValueType(ResNo), true)) 726 return; 727 728 switch (N->getOpcode()) { 729 default: 730#ifndef NDEBUG 731 cerr << "ExpandFloatResult #" << ResNo << ": "; 732 N->dump(&DAG); cerr << "\n"; 733#endif 734 assert(0 && "Do not know how to expand the result of this operator!"); 735 abort(); 736 737 case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break; 738 case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; 739 case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; 740 case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; 741 742 case ISD::BIT_CONVERT: ExpandRes_BIT_CONVERT(N, Lo, Hi); break; 743 case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break; 744 case ISD::EXTRACT_ELEMENT: ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break; 745 case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; 746 case ISD::VAARG: ExpandRes_VAARG(N, Lo, Hi); break; 747 748 case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break; 749 case ISD::FABS: ExpandFloatRes_FABS(N, Lo, Hi); break; 750 case ISD::FADD: ExpandFloatRes_FADD(N, Lo, Hi); break; 751 case ISD::FCEIL: ExpandFloatRes_FCEIL(N, Lo, Hi); break; 752 case ISD::FCOS: ExpandFloatRes_FCOS(N, Lo, Hi); break; 753 case ISD::FDIV: ExpandFloatRes_FDIV(N, Lo, Hi); break; 754 case ISD::FEXP: ExpandFloatRes_FEXP(N, Lo, Hi); break; 755 case ISD::FEXP2: ExpandFloatRes_FEXP2(N, Lo, Hi); break; 756 case ISD::FFLOOR: ExpandFloatRes_FFLOOR(N, Lo, Hi); break; 757 case ISD::FLOG: ExpandFloatRes_FLOG(N, Lo, Hi); break; 758 case ISD::FLOG2: ExpandFloatRes_FLOG2(N, Lo, Hi); break; 759 case ISD::FLOG10: ExpandFloatRes_FLOG10(N, Lo, Hi); break; 760 case ISD::FMUL: ExpandFloatRes_FMUL(N, Lo, Hi); break; 761 case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT(N, Lo, Hi); break; 762 case ISD::FNEG: ExpandFloatRes_FNEG(N, Lo, Hi); break; 763 case ISD::FP_EXTEND: ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break; 764 case ISD::FPOW: ExpandFloatRes_FPOW(N, Lo, Hi); break; 765 case ISD::FPOWI: ExpandFloatRes_FPOWI(N, Lo, Hi); break; 766 case ISD::FRINT: ExpandFloatRes_FRINT(N, Lo, Hi); break; 767 case ISD::FSIN: ExpandFloatRes_FSIN(N, Lo, Hi); break; 768 case ISD::FSQRT: ExpandFloatRes_FSQRT(N, Lo, Hi); break; 769 case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break; 770 case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break; 771 case ISD::LOAD: ExpandFloatRes_LOAD(N, Lo, Hi); break; 772 case ISD::SINT_TO_FP: 773 case ISD::UINT_TO_FP: ExpandFloatRes_XINT_TO_FP(N, Lo, Hi); break; 774 } 775 776 // If Lo/Hi is null, the sub-method took care of registering results etc. 777 if (Lo.getNode()) 778 SetExpandedFloat(SDValue(N, ResNo), Lo, Hi); 779} 780 781void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo, 782 SDValue &Hi) { 783 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 784 assert(NVT.getSizeInBits() == integerPartWidth && 785 "Do not know how to expand this float constant!"); 786 APInt C = cast<ConstantFPSDNode>(N)->getValueAPF().bitcastToAPInt(); 787 Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, 788 &C.getRawData()[1])), NVT); 789 Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, 790 &C.getRawData()[0])), NVT); 791} 792 793void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo, 794 SDValue &Hi) { 795 assert(N->getValueType(0) == MVT::ppcf128 && 796 "Logic only correct for ppcf128!"); 797 SDValue Tmp; 798 GetExpandedFloat(N->getOperand(0), Lo, Tmp); 799 Hi = DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp); 800 // Lo = Hi==fabs(Hi) ? Lo : -Lo; 801 Lo = DAG.getNode(ISD::SELECT_CC, Lo.getValueType(), Tmp, Hi, Lo, 802 DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo), 803 DAG.getCondCode(ISD::SETEQ)); 804} 805 806void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDValue &Lo, 807 SDValue &Hi) { 808 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 809 RTLIB::ADD_F32, RTLIB::ADD_F64, 810 RTLIB::ADD_F80, RTLIB::ADD_PPCF128), 811 N, false); 812 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 813 "Call lowered wrongly!"); 814 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 815} 816 817void DAGTypeLegalizer::ExpandFloatRes_FCEIL(SDNode *N, 818 SDValue &Lo, SDValue &Hi) { 819 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 820 RTLIB::CEIL_F32, RTLIB::CEIL_F64, 821 RTLIB::CEIL_F80, RTLIB::CEIL_PPCF128), 822 N, false); 823 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 824 "Call lowered wrongly!"); 825 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 826} 827 828void DAGTypeLegalizer::ExpandFloatRes_FCOS(SDNode *N, 829 SDValue &Lo, SDValue &Hi) { 830 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 831 RTLIB::COS_F32, RTLIB::COS_F64, 832 RTLIB::COS_F80, RTLIB::COS_PPCF128), 833 N, false); 834 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 835 "Call lowered wrongly!"); 836 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 837} 838 839void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo, 840 SDValue &Hi) { 841 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 842 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 843 RTLIB::DIV_F32, 844 RTLIB::DIV_F64, 845 RTLIB::DIV_F80, 846 RTLIB::DIV_PPCF128), 847 N->getValueType(0), Ops, 2, false); 848 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 849 "Call lowered wrongly!"); 850 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 851} 852 853void DAGTypeLegalizer::ExpandFloatRes_FEXP(SDNode *N, 854 SDValue &Lo, SDValue &Hi) { 855 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 856 RTLIB::EXP_F32, RTLIB::EXP_F64, 857 RTLIB::EXP_F80, RTLIB::EXP_PPCF128), 858 N, false); 859 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 860 "Call lowered wrongly!"); 861 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 862} 863 864void DAGTypeLegalizer::ExpandFloatRes_FEXP2(SDNode *N, 865 SDValue &Lo, SDValue &Hi) { 866 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 867 RTLIB::EXP2_F32, RTLIB::EXP2_F64, 868 RTLIB::EXP2_F80, RTLIB::EXP2_PPCF128), 869 N, false); 870 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 871 "Call lowered wrongly!"); 872 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 873} 874 875void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(SDNode *N, 876 SDValue &Lo, SDValue &Hi) { 877 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 878 RTLIB::FLOOR_F32,RTLIB::FLOOR_F64, 879 RTLIB::FLOOR_F80,RTLIB::FLOOR_PPCF128), 880 N, false); 881 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 882 "Call lowered wrongly!"); 883 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 884} 885 886void DAGTypeLegalizer::ExpandFloatRes_FLOG(SDNode *N, 887 SDValue &Lo, SDValue &Hi) { 888 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 889 RTLIB::LOG_F32, RTLIB::LOG_F64, 890 RTLIB::LOG_F80, RTLIB::LOG_PPCF128), 891 N, false); 892 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 893 "Call lowered wrongly!"); 894 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 895} 896 897void DAGTypeLegalizer::ExpandFloatRes_FLOG2(SDNode *N, 898 SDValue &Lo, SDValue &Hi) { 899 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 900 RTLIB::LOG2_F32, RTLIB::LOG2_F64, 901 RTLIB::LOG2_F80, RTLIB::LOG2_PPCF128), 902 N, false); 903 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 904 "Call lowered wrongly!"); 905 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 906} 907 908void DAGTypeLegalizer::ExpandFloatRes_FLOG10(SDNode *N, 909 SDValue &Lo, SDValue &Hi) { 910 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 911 RTLIB::LOG10_F32,RTLIB::LOG10_F64, 912 RTLIB::LOG10_F80,RTLIB::LOG10_PPCF128), 913 N, false); 914 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 915 "Call lowered wrongly!"); 916 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 917} 918 919void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo, 920 SDValue &Hi) { 921 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 922 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 923 RTLIB::MUL_F32, 924 RTLIB::MUL_F64, 925 RTLIB::MUL_F80, 926 RTLIB::MUL_PPCF128), 927 N->getValueType(0), Ops, 2, false); 928 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 929 "Call lowered wrongly!"); 930 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 931} 932 933void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode *N, 934 SDValue &Lo, SDValue &Hi) { 935 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 936 RTLIB::NEARBYINT_F32, 937 RTLIB::NEARBYINT_F64, 938 RTLIB::NEARBYINT_F80, 939 RTLIB::NEARBYINT_PPCF128), 940 N, 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_FNEG(SDNode *N, SDValue &Lo, 947 SDValue &Hi) { 948 GetExpandedFloat(N->getOperand(0), Lo, Hi); 949 Lo = DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo); 950 Hi = DAG.getNode(ISD::FNEG, Hi.getValueType(), Hi); 951} 952 953void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo, 954 SDValue &Hi) { 955 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 956 Hi = DAG.getNode(ISD::FP_EXTEND, NVT, N->getOperand(0)); 957 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); 958} 959 960void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode *N, 961 SDValue &Lo, SDValue &Hi) { 962 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 963 RTLIB::POW_F32, RTLIB::POW_F64, 964 RTLIB::POW_F80, RTLIB::POW_PPCF128), 965 N, false); 966 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 967 "Call lowered wrongly!"); 968 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 969} 970 971void DAGTypeLegalizer::ExpandFloatRes_FPOWI(SDNode *N, 972 SDValue &Lo, SDValue &Hi) { 973 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 974 RTLIB::POWI_F32, RTLIB::POWI_F64, 975 RTLIB::POWI_F80, RTLIB::POWI_PPCF128), 976 N, false); 977 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 978 "Call lowered wrongly!"); 979 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 980} 981 982void DAGTypeLegalizer::ExpandFloatRes_FRINT(SDNode *N, 983 SDValue &Lo, SDValue &Hi) { 984 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 985 RTLIB::RINT_F32, RTLIB::RINT_F64, 986 RTLIB::RINT_F80, RTLIB::RINT_PPCF128), 987 N, false); 988 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 989 "Call lowered wrongly!"); 990 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 991} 992 993void DAGTypeLegalizer::ExpandFloatRes_FSIN(SDNode *N, 994 SDValue &Lo, SDValue &Hi) { 995 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 996 RTLIB::SIN_F32, RTLIB::SIN_F64, 997 RTLIB::SIN_F80, RTLIB::SIN_PPCF128), 998 N, false); 999 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 1000 "Call lowered wrongly!"); 1001 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 1002} 1003 1004void DAGTypeLegalizer::ExpandFloatRes_FSQRT(SDNode *N, 1005 SDValue &Lo, SDValue &Hi) { 1006 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 1007 RTLIB::SQRT_F32, RTLIB::SQRT_F64, 1008 RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128), 1009 N, false); 1010 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 1011 "Call lowered wrongly!"); 1012 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 1013} 1014 1015void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo, 1016 SDValue &Hi) { 1017 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 1018 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 1019 RTLIB::SUB_F32, 1020 RTLIB::SUB_F64, 1021 RTLIB::SUB_F80, 1022 RTLIB::SUB_PPCF128), 1023 N->getValueType(0), Ops, 2, false); 1024 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 1025 "Call lowered wrongly!"); 1026 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 1027} 1028 1029void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(SDNode *N, 1030 SDValue &Lo, SDValue &Hi) { 1031 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0), 1032 RTLIB::TRUNC_F32, RTLIB::TRUNC_F64, 1033 RTLIB::TRUNC_F80, RTLIB::TRUNC_PPCF128), 1034 N, false); 1035 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && 1036 "Call lowered wrongly!"); 1037 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 1038} 1039 1040void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo, 1041 SDValue &Hi) { 1042 if (ISD::isNormalLoad(N)) { 1043 ExpandRes_NormalLoad(N, Lo, Hi); 1044 return; 1045 } 1046 1047 assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!"); 1048 LoadSDNode *LD = cast<LoadSDNode>(N); 1049 SDValue Chain = LD->getChain(); 1050 SDValue Ptr = LD->getBasePtr(); 1051 1052 MVT NVT = TLI.getTypeToTransformTo(LD->getValueType(0)); 1053 assert(NVT.isByteSized() && "Expanded type not byte sized!"); 1054 assert(LD->getMemoryVT().bitsLE(NVT) && "Float type not round?"); 1055 1056 Hi = DAG.getExtLoad(LD->getExtensionType(), NVT, Chain, Ptr, 1057 LD->getSrcValue(), LD->getSrcValueOffset(), 1058 LD->getMemoryVT(), 1059 LD->isVolatile(), LD->getAlignment()); 1060 1061 // Remember the chain. 1062 Chain = Hi.getValue(1); 1063 1064 // The low part is zero. 1065 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); 1066 1067 // Modified the chain - switch anything that used the old chain to use the 1068 // new one. 1069 ReplaceValueWith(SDValue(LD, 1), Chain); 1070} 1071 1072void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, 1073 SDValue &Hi) { 1074 assert(N->getValueType(0) == MVT::ppcf128 && "Unsupported XINT_TO_FP!"); 1075 MVT VT = N->getValueType(0); 1076 MVT NVT = TLI.getTypeToTransformTo(VT); 1077 SDValue Src = N->getOperand(0); 1078 MVT SrcVT = Src.getValueType(); 1079 bool isSigned = N->getOpcode() == ISD::SINT_TO_FP; 1080 1081 // First do an SINT_TO_FP, whether the original was signed or unsigned. 1082 // When promoting partial word types to i32 we must honor the signedness, 1083 // though. 1084 if (SrcVT.bitsLE(MVT::i32)) { 1085 // The integer can be represented exactly in an f64. 1086 Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, 1087 MVT::i32, Src); 1088 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); 1089 Hi = DAG.getNode(ISD::SINT_TO_FP, NVT, Src); 1090 } else { 1091 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 1092 if (SrcVT.bitsLE(MVT::i64)) { 1093 Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, 1094 MVT::i64, Src); 1095 LC = RTLIB::SINTTOFP_I64_PPCF128; 1096 } else if (SrcVT.bitsLE(MVT::i128)) { 1097 Src = DAG.getNode(ISD::SIGN_EXTEND, MVT::i128, Src); 1098 LC = RTLIB::SINTTOFP_I128_PPCF128; 1099 } 1100 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!"); 1101 1102 Hi = MakeLibCall(LC, VT, &Src, 1, true); 1103 assert(Hi.getNode()->getOpcode() == ISD::BUILD_PAIR && 1104 "Call lowered wrongly!"); 1105 Lo = Hi.getOperand(0); Hi = Hi.getOperand(1); 1106 } 1107 1108 if (isSigned) 1109 return; 1110 1111 // Unsigned - fix up the SINT_TO_FP value just calculated. 1112 Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi); 1113 SrcVT = Src.getValueType(); 1114 1115 // x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128. 1116 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 }; 1117 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 }; 1118 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 }; 1119 const uint64_t *Parts = 0; 1120 1121 switch (SrcVT.getSimpleVT()) { 1122 default: 1123 assert(false && "Unsupported UINT_TO_FP!"); 1124 case MVT::i32: 1125 Parts = TwoE32; 1126 break; 1127 case MVT::i64: 1128 Parts = TwoE64; 1129 break; 1130 case MVT::i128: 1131 Parts = TwoE128; 1132 break; 1133 } 1134 1135 Lo = DAG.getNode(ISD::FADD, VT, Hi, 1136 DAG.getConstantFP(APFloat(APInt(128, 2, Parts)), 1137 MVT::ppcf128)); 1138 Lo = DAG.getNode(ISD::SELECT_CC, VT, Src, DAG.getConstant(0, SrcVT), Lo, Hi, 1139 DAG.getCondCode(ISD::SETLT)); 1140 Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, DAG.getIntPtrConstant(1)); 1141 Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, DAG.getIntPtrConstant(0)); 1142} 1143 1144 1145//===----------------------------------------------------------------------===// 1146// Float Operand Expansion 1147//===----------------------------------------------------------------------===// 1148 1149/// ExpandFloatOperand - This method is called when the specified operand of the 1150/// specified node is found to need expansion. At this point, all of the result 1151/// types of the node are known to be legal, but other operands of the node may 1152/// need promotion or expansion as well as the specified one. 1153bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) { 1154 DEBUG(cerr << "Expand float operand: "; N->dump(&DAG); cerr << "\n"); 1155 SDValue Res = SDValue(); 1156 1157 if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) 1158 == TargetLowering::Custom) 1159 Res = TLI.LowerOperation(SDValue(N, 0), DAG); 1160 1161 if (Res.getNode() == 0) { 1162 switch (N->getOpcode()) { 1163 default: 1164 #ifndef NDEBUG 1165 cerr << "ExpandFloatOperand Op #" << OpNo << ": "; 1166 N->dump(&DAG); cerr << "\n"; 1167 #endif 1168 assert(0 && "Do not know how to expand this operator's operand!"); 1169 abort(); 1170 1171 case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break; 1172 case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; 1173 case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; 1174 1175 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(N); break; 1176 case ISD::FP_ROUND: Res = ExpandFloatOp_FP_ROUND(N); break; 1177 case ISD::FP_TO_SINT: Res = ExpandFloatOp_FP_TO_SINT(N); break; 1178 case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_UINT(N); break; 1179 case ISD::SELECT_CC: Res = ExpandFloatOp_SELECT_CC(N); break; 1180 case ISD::SETCC: Res = ExpandFloatOp_SETCC(N); break; 1181 case ISD::STORE: Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N), 1182 OpNo); break; 1183 } 1184 } 1185 1186 // If the result is null, the sub-method took care of registering results etc. 1187 if (!Res.getNode()) return false; 1188 1189 // If the result is N, the sub-method updated N in place. Tell the legalizer 1190 // core about this. 1191 if (Res.getNode() == N) 1192 return true; 1193 1194 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 1195 "Invalid operand expansion"); 1196 1197 ReplaceValueWith(SDValue(N, 0), Res); 1198 return false; 1199} 1200 1201/// FloatExpandSetCCOperands - Expand the operands of a comparison. This code 1202/// is shared among BR_CC, SELECT_CC, and SETCC handlers. 1203void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS, 1204 SDValue &NewRHS, 1205 ISD::CondCode &CCCode) { 1206 SDValue LHSLo, LHSHi, RHSLo, RHSHi; 1207 GetExpandedFloat(NewLHS, LHSLo, LHSHi); 1208 GetExpandedFloat(NewRHS, RHSLo, RHSHi); 1209 1210 MVT VT = NewLHS.getValueType(); 1211 assert(VT == MVT::ppcf128 && "Unsupported setcc type!"); 1212 1213 // FIXME: This generated code sucks. We want to generate 1214 // FCMPU crN, hi1, hi2 1215 // BNE crN, L: 1216 // FCMPU crN, lo1, lo2 1217 // The following can be improved, but not that much. 1218 SDValue Tmp1, Tmp2, Tmp3; 1219 Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()), 1220 LHSHi, RHSHi, ISD::SETOEQ); 1221 Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo.getValueType()), 1222 LHSLo, RHSLo, CCCode); 1223 Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); 1224 Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()), 1225 LHSHi, RHSHi, ISD::SETUNE); 1226 Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()), 1227 LHSHi, RHSHi, CCCode); 1228 Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); 1229 NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3); 1230 NewRHS = SDValue(); // LHS is the result, not a compare. 1231} 1232 1233SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) { 1234 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); 1235 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get(); 1236 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode); 1237 1238 // If ExpandSetCCOperands returned a scalar, we need to compare the result 1239 // against zero to select between true and false values. 1240 if (NewRHS.getNode() == 0) { 1241 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 1242 CCCode = ISD::SETNE; 1243 } 1244 1245 // Update N to have the operands specified. 1246 return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 1247 DAG.getCondCode(CCCode), NewLHS, NewRHS, 1248 N->getOperand(4)); 1249} 1250 1251SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) { 1252 assert(N->getOperand(0).getValueType() == MVT::ppcf128 && 1253 "Logic only correct for ppcf128!"); 1254 SDValue Lo, Hi; 1255 GetExpandedFloat(N->getOperand(0), Lo, Hi); 1256 // Round it the rest of the way (e.g. to f32) if needed. 1257 return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Hi, N->getOperand(1)); 1258} 1259 1260SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { 1261 MVT RVT = N->getValueType(0); 1262 1263 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on 1264 // PPC (the libcall is not available). FIXME: Do this in a less hacky way. 1265 if (RVT == MVT::i32) { 1266 assert(N->getOperand(0).getValueType() == MVT::ppcf128 && 1267 "Logic only correct for ppcf128!"); 1268 SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, MVT::ppcf128, 1269 N->getOperand(0), DAG.getValueType(MVT::f64)); 1270 Res = DAG.getNode(ISD::FP_ROUND, MVT::f64, Res, DAG.getIntPtrConstant(1)); 1271 return DAG.getNode(ISD::FP_TO_SINT, MVT::i32, Res); 1272 } 1273 1274 RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); 1275 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); 1276 return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false); 1277} 1278 1279SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { 1280 MVT RVT = N->getValueType(0); 1281 1282 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on 1283 // PPC (the libcall is not available). FIXME: Do this in a less hacky way. 1284 if (RVT == MVT::i32) { 1285 assert(N->getOperand(0).getValueType() == MVT::ppcf128 && 1286 "Logic only correct for ppcf128!"); 1287 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0}; 1288 APFloat APF = APFloat(APInt(128, 2, TwoE31)); 1289 SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128); 1290 // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X 1291 // FIXME: generated code sucks. 1292 return DAG.getNode(ISD::SELECT_CC, MVT::i32, N->getOperand(0), Tmp, 1293 DAG.getNode(ISD::ADD, MVT::i32, 1294 DAG.getNode(ISD::FP_TO_SINT, MVT::i32, 1295 DAG.getNode(ISD::FSUB, 1296 MVT::ppcf128, 1297 N->getOperand(0), 1298 Tmp)), 1299 DAG.getConstant(0x80000000, MVT::i32)), 1300 DAG.getNode(ISD::FP_TO_SINT, MVT::i32, N->getOperand(0)), 1301 DAG.getCondCode(ISD::SETGE)); 1302 } 1303 1304 RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); 1305 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); 1306 return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false); 1307} 1308 1309SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) { 1310 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 1311 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get(); 1312 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode); 1313 1314 // If ExpandSetCCOperands returned a scalar, we need to compare the result 1315 // against zero to select between true and false values. 1316 if (NewRHS.getNode() == 0) { 1317 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 1318 CCCode = ISD::SETNE; 1319 } 1320 1321 // Update N to have the operands specified. 1322 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 1323 N->getOperand(2), N->getOperand(3), 1324 DAG.getCondCode(CCCode)); 1325} 1326 1327SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) { 1328 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 1329 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); 1330 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode); 1331 1332 // If ExpandSetCCOperands returned a scalar, use it. 1333 if (NewRHS.getNode() == 0) { 1334 assert(NewLHS.getValueType() == N->getValueType(0) && 1335 "Unexpected setcc expansion!"); 1336 return NewLHS; 1337 } 1338 1339 // Otherwise, update N to have the operands specified. 1340 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 1341 DAG.getCondCode(CCCode)); 1342} 1343 1344SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) { 1345 if (ISD::isNormalStore(N)) 1346 return ExpandOp_NormalStore(N, OpNo); 1347 1348 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); 1349 assert(OpNo == 1 && "Can only expand the stored value so far"); 1350 StoreSDNode *ST = cast<StoreSDNode>(N); 1351 1352 SDValue Chain = ST->getChain(); 1353 SDValue Ptr = ST->getBasePtr(); 1354 1355 MVT NVT = TLI.getTypeToTransformTo(ST->getValue().getValueType()); 1356 assert(NVT.isByteSized() && "Expanded type not byte sized!"); 1357 assert(ST->getMemoryVT().bitsLE(NVT) && "Float type not round?"); 1358 1359 SDValue Lo, Hi; 1360 GetExpandedOp(ST->getValue(), Lo, Hi); 1361 1362 return DAG.getTruncStore(Chain, Hi, Ptr, 1363 ST->getSrcValue(), ST->getSrcValueOffset(), 1364 ST->getMemoryVT(), 1365 ST->isVolatile(), ST->getAlignment()); 1366} 1367