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