LegalizeFloatTypes.cpp revision e2fbf68c95cf19db979a7a5a55b3e433d0231334
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::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break; 65 case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break; 66 case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break; 67 case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break; 68 case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break; 69 case ISD::FPOW: R = SoftenFloatRes_FPOW(N); break; 70 case ISD::FPOWI: R = SoftenFloatRes_FPOWI(N); break; 71 case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break; 72 case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break; 73 case ISD::SELECT: R = SoftenFloatRes_SELECT(N); break; 74 case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N); break; 75 case ISD::SINT_TO_FP: R = SoftenFloatRes_SINT_TO_FP(N); break; 76 case ISD::UINT_TO_FP: R = SoftenFloatRes_UINT_TO_FP(N); break; 77 } 78 79 // If R is null, the sub-method took care of registering the result. 80 if (R.getNode()) 81 SetSoftenedFloat(SDValue(N, ResNo), R); 82} 83 84SDValue DAGTypeLegalizer::SoftenFloatRes_BIT_CONVERT(SDNode *N) { 85 return BitConvertToInteger(N->getOperand(0)); 86} 87 88SDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) { 89 // Convert the inputs to integers, and build a new pair out of them. 90 return DAG.getNode(ISD::BUILD_PAIR, 91 TLI.getTypeToTransformTo(N->getValueType(0)), 92 BitConvertToInteger(N->getOperand(0)), 93 BitConvertToInteger(N->getOperand(1))); 94} 95 96SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(ConstantFPSDNode *N) { 97 return DAG.getConstant(N->getValueAPF().bitcastToAPInt(), 98 TLI.getTypeToTransformTo(N->getValueType(0))); 99} 100 101SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) { 102 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 103 unsigned Size = NVT.getSizeInBits(); 104 105 // Mask = ~(1 << (Size-1)) 106 SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1), 107 NVT); 108 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 109 return DAG.getNode(ISD::AND, NVT, Op, Mask); 110} 111 112SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) { 113 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 114 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 115 GetSoftenedFloat(N->getOperand(1)) }; 116 return MakeLibCall(GetFPLibCall(N->getValueType(0), 117 RTLIB::ADD_F32, 118 RTLIB::ADD_F64, 119 RTLIB::ADD_F80, 120 RTLIB::ADD_PPCF128), 121 NVT, Ops, 2, false); 122} 123 124SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { 125 SDValue LHS = GetSoftenedFloat(N->getOperand(0)); 126 SDValue RHS = BitConvertToInteger(N->getOperand(1)); 127 128 MVT LVT = LHS.getValueType(); 129 MVT RVT = RHS.getValueType(); 130 131 unsigned LSize = LVT.getSizeInBits(); 132 unsigned RSize = RVT.getSizeInBits(); 133 134 // First get the sign bit of second operand. 135 SDValue SignBit = DAG.getNode(ISD::SHL, RVT, DAG.getConstant(1, RVT), 136 DAG.getConstant(RSize - 1, 137 TLI.getShiftAmountTy())); 138 SignBit = DAG.getNode(ISD::AND, RVT, RHS, SignBit); 139 140 // Shift right or sign-extend it if the two operands have different types. 141 int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits(); 142 if (SizeDiff > 0) { 143 SignBit = DAG.getNode(ISD::SRL, RVT, SignBit, 144 DAG.getConstant(SizeDiff, TLI.getShiftAmountTy())); 145 SignBit = DAG.getNode(ISD::TRUNCATE, LVT, SignBit); 146 } else if (SizeDiff < 0) { 147 SignBit = DAG.getNode(ISD::ANY_EXTEND, LVT, SignBit); 148 SignBit = DAG.getNode(ISD::SHL, LVT, SignBit, 149 DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy())); 150 } 151 152 // Clear the sign bit of the first operand. 153 SDValue Mask = DAG.getNode(ISD::SHL, LVT, DAG.getConstant(1, LVT), 154 DAG.getConstant(LSize - 1, 155 TLI.getShiftAmountTy())); 156 Mask = DAG.getNode(ISD::SUB, LVT, Mask, DAG.getConstant(1, LVT)); 157 LHS = DAG.getNode(ISD::AND, LVT, LHS, Mask); 158 159 // Or the value with the sign bit. 160 return DAG.getNode(ISD::OR, LVT, LHS, SignBit); 161} 162 163SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) { 164 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 165 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 166 GetSoftenedFloat(N->getOperand(1)) }; 167 return MakeLibCall(GetFPLibCall(N->getValueType(0), 168 RTLIB::DIV_F32, 169 RTLIB::DIV_F64, 170 RTLIB::DIV_F80, 171 RTLIB::DIV_PPCF128), 172 NVT, Ops, 2, false); 173} 174 175SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { 176 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 177 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 178 GetSoftenedFloat(N->getOperand(1)) }; 179 return MakeLibCall(GetFPLibCall(N->getValueType(0), 180 RTLIB::MUL_F32, 181 RTLIB::MUL_F64, 182 RTLIB::MUL_F80, 183 RTLIB::MUL_PPCF128), 184 NVT, Ops, 2, false); 185} 186 187SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) { 188 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 189 SDValue Op = N->getOperand(0); 190 RTLIB::Libcall LC = RTLIB::getFPEXT(Op.getValueType(), N->getValueType(0)); 191 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!"); 192 return MakeLibCall(LC, NVT, &Op, 1, false); 193} 194 195SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) { 196 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 197 SDValue Op = N->getOperand(0); 198 RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), N->getValueType(0)); 199 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND!"); 200 return MakeLibCall(LC, NVT, &Op, 1, false); 201} 202 203SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) { 204 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 205 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 206 GetSoftenedFloat(N->getOperand(1)) }; 207 return MakeLibCall(GetFPLibCall(N->getValueType(0), 208 RTLIB::POW_F32, 209 RTLIB::POW_F64, 210 RTLIB::POW_F80, 211 RTLIB::POW_PPCF128), 212 NVT, Ops, 2, false); 213} 214 215SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) { 216 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 217 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), N->getOperand(1) }; 218 return MakeLibCall(GetFPLibCall(N->getValueType(0), 219 RTLIB::POWI_F32, 220 RTLIB::POWI_F64, 221 RTLIB::POWI_F80, 222 RTLIB::POWI_PPCF128), 223 NVT, Ops, 2, false); 224} 225 226SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) { 227 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 228 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), 229 GetSoftenedFloat(N->getOperand(1)) }; 230 return MakeLibCall(GetFPLibCall(N->getValueType(0), 231 RTLIB::SUB_F32, 232 RTLIB::SUB_F64, 233 RTLIB::SUB_F80, 234 RTLIB::SUB_PPCF128), 235 NVT, Ops, 2, false); 236} 237 238SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { 239 LoadSDNode *L = cast<LoadSDNode>(N); 240 MVT VT = N->getValueType(0); 241 MVT NVT = TLI.getTypeToTransformTo(VT); 242 243 SDValue NewL; 244 if (L->getExtensionType() == ISD::NON_EXTLOAD) { 245 NewL = DAG.getLoad(L->getAddressingMode(), L->getExtensionType(), 246 NVT, L->getChain(), L->getBasePtr(), L->getOffset(), 247 L->getSrcValue(), L->getSrcValueOffset(), NVT, 248 L->isVolatile(), L->getAlignment()); 249 // Legalized the chain result - switch anything that used the old chain to 250 // use the new one. 251 ReplaceValueWith(SDValue(N, 1), NewL.getValue(1)); 252 return NewL; 253 } 254 255 // Do a non-extending load followed by FP_EXTEND. 256 NewL = DAG.getLoad(L->getAddressingMode(), ISD::NON_EXTLOAD, 257 L->getMemoryVT(), L->getChain(), 258 L->getBasePtr(), L->getOffset(), 259 L->getSrcValue(), L->getSrcValueOffset(), 260 L->getMemoryVT(), 261 L->isVolatile(), L->getAlignment()); 262 // Legalized the chain result - switch anything that used the old chain to 263 // use the new one. 264 ReplaceValueWith(SDValue(N, 1), NewL.getValue(1)); 265 return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, VT, NewL)); 266} 267 268SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N) { 269 SDValue LHS = GetSoftenedFloat(N->getOperand(1)); 270 SDValue RHS = GetSoftenedFloat(N->getOperand(2)); 271 return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS); 272} 273 274SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N) { 275 SDValue LHS = GetSoftenedFloat(N->getOperand(2)); 276 SDValue RHS = GetSoftenedFloat(N->getOperand(3)); 277 return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0), 278 N->getOperand(1), LHS, RHS, N->getOperand(4)); 279} 280 281SDValue DAGTypeLegalizer::SoftenFloatRes_SINT_TO_FP(SDNode *N) { 282 SDValue Op = N->getOperand(0); 283 MVT RVT = N->getValueType(0); 284 RTLIB::Libcall LC = RTLIB::getSINTTOFP(Op.getValueType(), RVT); 285 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SINT_TO_FP!"); 286 return MakeLibCall(LC, TLI.getTypeToTransformTo(RVT), &Op, 1, false); 287} 288 289SDValue DAGTypeLegalizer::SoftenFloatRes_UINT_TO_FP(SDNode *N) { 290 SDValue Op = N->getOperand(0); 291 MVT RVT = N->getValueType(0); 292 RTLIB::Libcall LC = RTLIB::getUINTTOFP(Op.getValueType(), RVT); 293 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UINT_TO_FP!"); 294 return MakeLibCall(LC, TLI.getTypeToTransformTo(RVT), &Op, 1, false); 295} 296 297 298//===----------------------------------------------------------------------===// 299// Operand Float to Integer Conversion.. 300//===----------------------------------------------------------------------===// 301 302bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) { 303 DEBUG(cerr << "Soften float operand " << OpNo << ": "; N->dump(&DAG); 304 cerr << "\n"); 305 SDValue Res = SDValue(); 306 307 switch (N->getOpcode()) { 308 default: 309#ifndef NDEBUG 310 cerr << "SoftenFloatOperand Op #" << OpNo << ": "; 311 N->dump(&DAG); cerr << "\n"; 312#endif 313 assert(0 && "Do not know how to soften this operator's operand!"); 314 abort(); 315 316 case ISD::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break; 317 case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(N); break; 318 case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break; 319 case ISD::FP_TO_SINT: Res = SoftenFloatOp_FP_TO_SINT(N); break; 320 case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_UINT(N); break; 321 case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break; 322 case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break; 323 case ISD::STORE: Res = SoftenFloatOp_STORE(N, OpNo); break; 324 } 325 326 // If the result is null, the sub-method took care of registering results etc. 327 if (!Res.getNode()) return false; 328 329 // If the result is N, the sub-method updated N in place. Check to see if any 330 // operands are new, and if so, mark them. 331 if (Res.getNode() == N) { 332 // Mark N as new and remark N and its operands. This allows us to correctly 333 // revisit N if it needs another step of promotion and allows us to visit 334 // any new operands to N. 335 ReanalyzeNode(N); 336 return true; 337 } 338 339 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 340 "Invalid operand expansion"); 341 342 ReplaceValueWith(SDValue(N, 0), Res); 343 return false; 344} 345 346/// SoftenSetCCOperands - Soften the operands of a comparison. This code is 347/// shared among BR_CC, SELECT_CC, and SETCC handlers. 348void DAGTypeLegalizer::SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, 349 ISD::CondCode &CCCode) { 350 SDValue LHSInt = GetSoftenedFloat(NewLHS); 351 SDValue RHSInt = GetSoftenedFloat(NewRHS); 352 MVT VT = NewLHS.getValueType(); 353 354 assert((VT == MVT::f32 || VT == MVT::f64) && "Unsupported setcc type!"); 355 356 // Expand into one or more soft-fp libcall(s). 357 RTLIB::Libcall LC1 = RTLIB::UNKNOWN_LIBCALL, LC2 = RTLIB::UNKNOWN_LIBCALL; 358 switch (CCCode) { 359 case ISD::SETEQ: 360 case ISD::SETOEQ: 361 LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64; 362 break; 363 case ISD::SETNE: 364 case ISD::SETUNE: 365 LC1 = (VT == MVT::f32) ? RTLIB::UNE_F32 : RTLIB::UNE_F64; 366 break; 367 case ISD::SETGE: 368 case ISD::SETOGE: 369 LC1 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64; 370 break; 371 case ISD::SETLT: 372 case ISD::SETOLT: 373 LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64; 374 break; 375 case ISD::SETLE: 376 case ISD::SETOLE: 377 LC1 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64; 378 break; 379 case ISD::SETGT: 380 case ISD::SETOGT: 381 LC1 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64; 382 break; 383 case ISD::SETUO: 384 LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64; 385 break; 386 case ISD::SETO: 387 LC1 = (VT == MVT::f32) ? RTLIB::O_F32 : RTLIB::O_F64; 388 break; 389 default: 390 LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64; 391 switch (CCCode) { 392 case ISD::SETONE: 393 // SETONE = SETOLT | SETOGT 394 LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64; 395 // Fallthrough 396 case ISD::SETUGT: 397 LC2 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64; 398 break; 399 case ISD::SETUGE: 400 LC2 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64; 401 break; 402 case ISD::SETULT: 403 LC2 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64; 404 break; 405 case ISD::SETULE: 406 LC2 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64; 407 break; 408 case ISD::SETUEQ: 409 LC2 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64; 410 break; 411 default: assert(false && "Do not know how to soften this setcc!"); 412 } 413 } 414 415 MVT RetVT = MVT::i32; // FIXME: is this the correct return type? 416 SDValue Ops[2] = { LHSInt, RHSInt }; 417 NewLHS = MakeLibCall(LC1, RetVT, Ops, 2, false/*sign irrelevant*/); 418 NewRHS = DAG.getConstant(0, RetVT); 419 CCCode = TLI.getCmpLibcallCC(LC1); 420 if (LC2 != RTLIB::UNKNOWN_LIBCALL) { 421 SDValue Tmp = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(NewLHS), 422 NewLHS, NewRHS, DAG.getCondCode(CCCode)); 423 NewLHS = MakeLibCall(LC2, RetVT, Ops, 2, false/*sign irrelevant*/); 424 NewLHS = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(NewLHS), NewLHS, 425 NewRHS, DAG.getCondCode(TLI.getCmpLibcallCC(LC2))); 426 NewLHS = DAG.getNode(ISD::OR, Tmp.getValueType(), Tmp, NewLHS); 427 NewRHS = SDValue(); 428 } 429} 430 431SDValue DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) { 432 return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), 433 GetSoftenedFloat(N->getOperand(0))); 434} 435 436SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) { 437 MVT SVT = N->getOperand(0).getValueType(); 438 MVT RVT = N->getValueType(0); 439 440 RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, RVT); 441 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall"); 442 443 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 444 return MakeLibCall(LC, RVT, &Op, 1, false); 445} 446 447SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) { 448 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); 449 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get(); 450 SoftenSetCCOperands(NewLHS, NewRHS, CCCode); 451 452 // If SoftenSetCCOperands returned a scalar, we need to compare the result 453 // against zero to select between true and false values. 454 if (NewRHS.getNode() == 0) { 455 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 456 CCCode = ISD::SETNE; 457 } 458 459 // Update N to have the operands specified. 460 return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 461 DAG.getCondCode(CCCode), NewLHS, NewRHS, 462 N->getOperand(4)); 463} 464 465SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode *N) { 466 MVT RVT = N->getValueType(0); 467 RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); 468 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); 469 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 470 return MakeLibCall(LC, RVT, &Op, 1, false); 471} 472 473SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) { 474 MVT RVT = N->getValueType(0); 475 RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); 476 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); 477 SDValue Op = GetSoftenedFloat(N->getOperand(0)); 478 return MakeLibCall(LC, RVT, &Op, 1, false); 479} 480 481SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) { 482 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 483 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get(); 484 SoftenSetCCOperands(NewLHS, NewRHS, CCCode); 485 486 // If SoftenSetCCOperands returned a scalar, we need to compare the result 487 // against zero to select between true and false values. 488 if (NewRHS.getNode() == 0) { 489 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 490 CCCode = ISD::SETNE; 491 } 492 493 // Update N to have the operands specified. 494 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 495 N->getOperand(2), N->getOperand(3), 496 DAG.getCondCode(CCCode)); 497} 498 499SDValue DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) { 500 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 501 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); 502 SoftenSetCCOperands(NewLHS, NewRHS, CCCode); 503 504 // If SoftenSetCCOperands returned a scalar, use it. 505 if (NewRHS.getNode() == 0) { 506 assert(NewLHS.getValueType() == N->getValueType(0) && 507 "Unexpected setcc expansion!"); 508 return NewLHS; 509 } 510 511 // Otherwise, update N to have the operands specified. 512 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 513 DAG.getCondCode(CCCode)); 514} 515 516SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) { 517 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); 518 assert(OpNo == 1 && "Can only soften the stored value!"); 519 StoreSDNode *ST = cast<StoreSDNode>(N); 520 SDValue Val = ST->getValue(); 521 522 if (ST->isTruncatingStore()) 523 // Do an FP_ROUND followed by a non-truncating store. 524 Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, ST->getMemoryVT(), 525 Val, DAG.getIntPtrConstant(0))); 526 else 527 Val = GetSoftenedFloat(Val); 528 529 return DAG.getStore(ST->getChain(), Val, ST->getBasePtr(), 530 ST->getSrcValue(), ST->getSrcValueOffset(), 531 ST->isVolatile(), ST->getAlignment()); 532} 533 534 535//===----------------------------------------------------------------------===// 536// Float Result Expansion 537//===----------------------------------------------------------------------===// 538 539/// ExpandFloatResult - This method is called when the specified result of the 540/// specified node is found to need expansion. At this point, the node may also 541/// have invalid operands or may have other results that need promotion, we just 542/// know that (at least) one result needs expansion. 543void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) { 544 DEBUG(cerr << "Expand float result: "; N->dump(&DAG); cerr << "\n"); 545 SDValue Lo, Hi; 546 Lo = Hi = SDValue(); 547 548 // See if the target wants to custom expand this node. 549 if (TLI.getOperationAction(N->getOpcode(), N->getValueType(ResNo)) == 550 TargetLowering::Custom) { 551 // If the target wants to, allow it to lower this itself. 552 if (SDNode *P = TLI.ReplaceNodeResults(N, DAG)) { 553 // Everything that once used N now uses P. We are guaranteed that the 554 // result value types of N and the result value types of P match. 555 ReplaceNodeWith(N, P); 556 return; 557 } 558 } 559 560 switch (N->getOpcode()) { 561 default: 562#ifndef NDEBUG 563 cerr << "ExpandFloatResult #" << ResNo << ": "; 564 N->dump(&DAG); cerr << "\n"; 565#endif 566 assert(0 && "Do not know how to expand the result of this operator!"); 567 abort(); 568 569 case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break; 570 case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break; 571 case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break; 572 case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break; 573 574 case ISD::BIT_CONVERT: ExpandRes_BIT_CONVERT(N, Lo, Hi); break; 575 case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break; 576 case ISD::EXTRACT_ELEMENT: ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break; 577 case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break; 578 579 case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break; 580 case ISD::FABS: ExpandFloatRes_FABS(N, Lo, Hi); break; 581 case ISD::FADD: ExpandFloatRes_FADD(N, Lo, Hi); break; 582 case ISD::FDIV: ExpandFloatRes_FDIV(N, Lo, Hi); break; 583 case ISD::FMUL: ExpandFloatRes_FMUL(N, Lo, Hi); break; 584 case ISD::FNEG: ExpandFloatRes_FNEG(N, Lo, Hi); break; 585 case ISD::FP_EXTEND: ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break; 586 case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break; 587 case ISD::LOAD: ExpandFloatRes_LOAD(N, Lo, Hi); break; 588 case ISD::SINT_TO_FP: 589 case ISD::UINT_TO_FP: ExpandFloatRes_XINT_TO_FP(N, Lo, Hi); break; 590 } 591 592 // If Lo/Hi is null, the sub-method took care of registering results etc. 593 if (Lo.getNode()) 594 SetExpandedFloat(SDValue(N, ResNo), Lo, Hi); 595} 596 597void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo, 598 SDValue &Hi) { 599 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 600 assert(NVT.getSizeInBits() == integerPartWidth && 601 "Do not know how to expand this float constant!"); 602 APInt C = cast<ConstantFPSDNode>(N)->getValueAPF().bitcastToAPInt(); 603 Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, 604 &C.getRawData()[1])), NVT); 605 Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1, 606 &C.getRawData()[0])), NVT); 607} 608 609void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDValue &Lo, 610 SDValue &Hi) { 611 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 612 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 613 RTLIB::ADD_F32, 614 RTLIB::ADD_F64, 615 RTLIB::ADD_F80, 616 RTLIB::ADD_PPCF128), 617 N->getValueType(0), Ops, 2, 618 false); 619 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); 620 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 621} 622 623void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo, 624 SDValue &Hi) { 625 assert(N->getValueType(0) == MVT::ppcf128 && 626 "Logic only correct for ppcf128!"); 627 SDValue Tmp; 628 GetExpandedFloat(N->getOperand(0), Lo, Tmp); 629 Hi = DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp); 630 // Lo = Hi==fabs(Hi) ? Lo : -Lo; 631 Lo = DAG.getNode(ISD::SELECT_CC, Lo.getValueType(), Tmp, Hi, Lo, 632 DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo), 633 DAG.getCondCode(ISD::SETEQ)); 634} 635 636void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo, 637 SDValue &Hi) { 638 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 639 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 640 RTLIB::DIV_F32, 641 RTLIB::DIV_F64, 642 RTLIB::DIV_F80, 643 RTLIB::DIV_PPCF128), 644 N->getValueType(0), Ops, 2, 645 false); 646 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); 647 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 648} 649 650void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo, 651 SDValue &Hi) { 652 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 653 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 654 RTLIB::MUL_F32, 655 RTLIB::MUL_F64, 656 RTLIB::MUL_F80, 657 RTLIB::MUL_PPCF128), 658 N->getValueType(0), Ops, 2, 659 false); 660 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); 661 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 662} 663 664void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo, 665 SDValue &Hi) { 666 GetExpandedFloat(N->getOperand(0), Lo, Hi); 667 Lo = DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo); 668 Hi = DAG.getNode(ISD::FNEG, Hi.getValueType(), Hi); 669} 670 671void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo, 672 SDValue &Hi) { 673 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); 674 Hi = DAG.getNode(ISD::FP_EXTEND, NVT, N->getOperand(0)); 675 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); 676} 677 678void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo, 679 SDValue &Hi) { 680 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; 681 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0), 682 RTLIB::SUB_F32, 683 RTLIB::SUB_F64, 684 RTLIB::SUB_F80, 685 RTLIB::SUB_PPCF128), 686 N->getValueType(0), Ops, 2, 687 false); 688 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); 689 Lo = Call.getOperand(0); Hi = Call.getOperand(1); 690} 691 692void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo, 693 SDValue &Hi) { 694 if (ISD::isNormalLoad(N)) { 695 ExpandRes_NormalLoad(N, Lo, Hi); 696 return; 697 } 698 699 assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!"); 700 LoadSDNode *LD = cast<LoadSDNode>(N); 701 SDValue Chain = LD->getChain(); 702 SDValue Ptr = LD->getBasePtr(); 703 704 MVT NVT = TLI.getTypeToTransformTo(LD->getValueType(0)); 705 assert(NVT.isByteSized() && "Expanded type not byte sized!"); 706 assert(LD->getMemoryVT().bitsLE(NVT) && "Float type not round?"); 707 708 Lo = DAG.getExtLoad(LD->getExtensionType(), NVT, Chain, Ptr, 709 LD->getSrcValue(), LD->getSrcValueOffset(), 710 LD->getMemoryVT(), 711 LD->isVolatile(), LD->getAlignment()); 712 713 // Remember the chain. 714 Chain = Lo.getValue(1); 715 716 // The high part is undefined. 717 Hi = DAG.getNode(ISD::UNDEF, NVT); 718 719 // Modified the chain - switch anything that used the old chain to use the 720 // new one. 721 ReplaceValueWith(SDValue(LD, 1), Chain); 722} 723 724void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, 725 SDValue &Hi) { 726 assert(N->getValueType(0) == MVT::ppcf128 && "Unsupported XINT_TO_FP!"); 727 MVT VT = N->getValueType(0); 728 MVT NVT = TLI.getTypeToTransformTo(VT); 729 SDValue Src = N->getOperand(0); 730 MVT SrcVT = Src.getValueType(); 731 732 // First do an SINT_TO_FP, whether the original was signed or unsigned. 733 if (SrcVT.bitsLE(MVT::i32)) { 734 // The integer can be represented exactly in an f64. 735 Src = DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Src); 736 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); 737 Hi = DAG.getNode(ISD::SINT_TO_FP, NVT, Src); 738 } else { 739 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 740 if (SrcVT.bitsLE(MVT::i64)) { 741 Src = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Src); 742 LC = RTLIB::SINTTOFP_I64_PPCF128; 743 } else if (SrcVT.bitsLE(MVT::i128)) { 744 Src = DAG.getNode(ISD::SIGN_EXTEND, MVT::i128, Src); 745 LC = RTLIB::SINTTOFP_I128_PPCF128; 746 } 747 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!"); 748 749 Hi = MakeLibCall(LC, VT, &Src, 1, true); 750 assert(Hi.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); 751 Lo = Hi.getOperand(0); Hi = Hi.getOperand(1); 752 } 753 754 if (N->getOpcode() == ISD::SINT_TO_FP) 755 return; 756 757 // Unsigned - fix up the SINT_TO_FP value just calculated. 758 Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi); 759 SrcVT = Src.getValueType(); 760 761 // x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128. 762 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 }; 763 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 }; 764 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 }; 765 const uint64_t *Parts = 0; 766 767 switch (SrcVT.getSimpleVT()) { 768 default: 769 assert(false && "Unsupported UINT_TO_FP!"); 770 case MVT::i32: 771 Parts = TwoE32; 772 case MVT::i64: 773 Parts = TwoE64; 774 case MVT::i128: 775 Parts = TwoE128; 776 } 777 778 Lo = DAG.getNode(ISD::FADD, VT, Hi, 779 DAG.getConstantFP(APFloat(APInt(128, 2, Parts)), 780 MVT::ppcf128)); 781 Lo = DAG.getNode(ISD::SELECT_CC, VT, Src, DAG.getConstant(0, SrcVT), Lo, Hi, 782 DAG.getCondCode(ISD::SETLT)); 783 Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, DAG.getIntPtrConstant(1)); 784 Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, DAG.getIntPtrConstant(0)); 785} 786 787 788//===----------------------------------------------------------------------===// 789// Float Operand Expansion 790//===----------------------------------------------------------------------===// 791 792/// ExpandFloatOperand - This method is called when the specified operand of the 793/// specified node is found to need expansion. At this point, all of the result 794/// types of the node are known to be legal, but other operands of the node may 795/// need promotion or expansion as well as the specified one. 796bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) { 797 DEBUG(cerr << "Expand float operand: "; N->dump(&DAG); cerr << "\n"); 798 SDValue Res = SDValue(); 799 800 if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType()) 801 == TargetLowering::Custom) 802 Res = TLI.LowerOperation(SDValue(N, OpNo), DAG); 803 804 if (Res.getNode() == 0) { 805 switch (N->getOpcode()) { 806 default: 807 #ifndef NDEBUG 808 cerr << "ExpandFloatOperand Op #" << OpNo << ": "; 809 N->dump(&DAG); cerr << "\n"; 810 #endif 811 assert(0 && "Do not know how to expand this operator's operand!"); 812 abort(); 813 814 case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break; 815 case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; 816 case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; 817 818 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(N); break; 819 case ISD::FP_ROUND: Res = ExpandFloatOp_FP_ROUND(N); break; 820 case ISD::FP_TO_SINT: Res = ExpandFloatOp_FP_TO_SINT(N); break; 821 case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_UINT(N); break; 822 case ISD::SELECT_CC: Res = ExpandFloatOp_SELECT_CC(N); break; 823 case ISD::SETCC: Res = ExpandFloatOp_SETCC(N); break; 824 case ISD::STORE: Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N), 825 OpNo); break; 826 } 827 } 828 829 // If the result is null, the sub-method took care of registering results etc. 830 if (!Res.getNode()) return false; 831 // If the result is N, the sub-method updated N in place. Check to see if any 832 // operands are new, and if so, mark them. 833 if (Res.getNode() == N) { 834 // Mark N as new and remark N and its operands. This allows us to correctly 835 // revisit N if it needs another step of expansion and allows us to visit 836 // any new operands to N. 837 ReanalyzeNode(N); 838 return true; 839 } 840 841 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 && 842 "Invalid operand expansion"); 843 844 ReplaceValueWith(SDValue(N, 0), Res); 845 return false; 846} 847 848/// FloatExpandSetCCOperands - Expand the operands of a comparison. This code 849/// is shared among BR_CC, SELECT_CC, and SETCC handlers. 850void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS, 851 SDValue &NewRHS, 852 ISD::CondCode &CCCode) { 853 SDValue LHSLo, LHSHi, RHSLo, RHSHi; 854 GetExpandedFloat(NewLHS, LHSLo, LHSHi); 855 GetExpandedFloat(NewRHS, RHSLo, RHSHi); 856 857 MVT VT = NewLHS.getValueType(); 858 assert(VT == MVT::ppcf128 && "Unsupported setcc type!"); 859 860 // FIXME: This generated code sucks. We want to generate 861 // FCMP crN, hi1, hi2 862 // BNE crN, L: 863 // FCMP crN, lo1, lo2 864 // The following can be improved, but not that much. 865 SDValue Tmp1, Tmp2, Tmp3; 866 Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, ISD::SETEQ); 867 Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, CCCode); 868 Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); 869 Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, ISD::SETNE); 870 Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, CCCode); 871 Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); 872 NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3); 873 NewRHS = SDValue(); // LHS is the result, not a compare. 874} 875 876SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) { 877 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); 878 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get(); 879 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode); 880 881 // If ExpandSetCCOperands returned a scalar, we need to compare the result 882 // against zero to select between true and false values. 883 if (NewRHS.getNode() == 0) { 884 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 885 CCCode = ISD::SETNE; 886 } 887 888 // Update N to have the operands specified. 889 return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), 890 DAG.getCondCode(CCCode), NewLHS, NewRHS, 891 N->getOperand(4)); 892} 893 894SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) { 895 assert(N->getOperand(0).getValueType() == MVT::ppcf128 && 896 "Logic only correct for ppcf128!"); 897 SDValue Lo, Hi; 898 GetExpandedFloat(N->getOperand(0), Lo, Hi); 899 // Round it the rest of the way (e.g. to f32) if needed. 900 return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Hi, N->getOperand(1)); 901} 902 903SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { 904 MVT RVT = N->getValueType(0); 905 RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); 906 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); 907 return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false); 908} 909 910SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { 911 MVT RVT = N->getValueType(0); 912 RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); 913 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); 914 return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false); 915} 916 917SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) { 918 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 919 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get(); 920 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode); 921 922 // If ExpandSetCCOperands returned a scalar, we need to compare the result 923 // against zero to select between true and false values. 924 if (NewRHS.getNode() == 0) { 925 NewRHS = DAG.getConstant(0, NewLHS.getValueType()); 926 CCCode = ISD::SETNE; 927 } 928 929 // Update N to have the operands specified. 930 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 931 N->getOperand(2), N->getOperand(3), 932 DAG.getCondCode(CCCode)); 933} 934 935SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) { 936 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); 937 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get(); 938 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode); 939 940 // If ExpandSetCCOperands returned a scalar, use it. 941 if (NewRHS.getNode() == 0) { 942 assert(NewLHS.getValueType() == N->getValueType(0) && 943 "Unexpected setcc expansion!"); 944 return NewLHS; 945 } 946 947 // Otherwise, update N to have the operands specified. 948 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS, 949 DAG.getCondCode(CCCode)); 950} 951 952SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) { 953 if (ISD::isNormalStore(N)) 954 return ExpandOp_NormalStore(N, OpNo); 955 956 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!"); 957 assert(OpNo == 1 && "Can only expand the stored value so far"); 958 StoreSDNode *ST = cast<StoreSDNode>(N); 959 960 SDValue Chain = ST->getChain(); 961 SDValue Ptr = ST->getBasePtr(); 962 963 MVT NVT = TLI.getTypeToTransformTo(ST->getValue().getValueType()); 964 assert(NVT.isByteSized() && "Expanded type not byte sized!"); 965 assert(ST->getMemoryVT().bitsLE(NVT) && "Float type not round?"); 966 967 SDValue Lo, Hi; 968 GetExpandedOp(ST->getValue(), Lo, Hi); 969 970 return DAG.getTruncStore(Chain, Lo, Ptr, 971 ST->getSrcValue(), ST->getSrcValueOffset(), 972 ST->getMemoryVT(), 973 ST->isVolatile(), ST->getAlignment()); 974} 975