1 //===-------- LegalizeFloatTypes.cpp - Legalization of float types --------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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.
20 //===----------------------------------------------------------------------===//
22 #include "LegalizeTypes.h"
25 /// GetFPLibCall - Return the right libcall for the given floating point type.
26 static 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) {
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;
39 //===----------------------------------------------------------------------===//
40 // Result Float to Integer Conversion.
41 //===----------------------------------------------------------------------===//
43 void DAGTypeLegalizer::SoftenFloatResult(SDNode *N, unsigned ResNo) {
44 DEBUG(cerr << "Soften float result " << ResNo << ": "; N->dump(&DAG);
46 SDValue R = SDValue();
48 switch (N->getOpcode()) {
51 cerr << "SoftenFloatResult #" << ResNo << ": ";
52 N->dump(&DAG); cerr << "\n";
54 assert(0 && "Do not know how to soften the result of this operator!");
57 case ISD::BIT_CONVERT: R = SoftenFloatRes_BIT_CONVERT(N); break;
58 case ISD::BUILD_PAIR: R = SoftenFloatRes_BUILD_PAIR(N); break;
60 R = SoftenFloatRes_ConstantFP(cast<ConstantFPSDNode>(N));
62 case ISD::FABS: R = SoftenFloatRes_FABS(N); break;
63 case ISD::FADD: R = SoftenFloatRes_FADD(N); break;
64 case ISD::FCEIL: R = SoftenFloatRes_FCEIL(N); break;
65 case ISD::FCOPYSIGN: R = SoftenFloatRes_FCOPYSIGN(N); break;
66 case ISD::FCOS: R = SoftenFloatRes_FCOS(N); break;
67 case ISD::FDIV: R = SoftenFloatRes_FDIV(N); break;
68 case ISD::FEXP: R = SoftenFloatRes_FEXP(N); break;
69 case ISD::FEXP2: R = SoftenFloatRes_FEXP2(N); break;
70 case ISD::FFLOOR: R = SoftenFloatRes_FFLOOR(N); break;
71 case ISD::FLOG: R = SoftenFloatRes_FLOG(N); break;
72 case ISD::FLOG2: R = SoftenFloatRes_FLOG2(N); break;
73 case ISD::FLOG10: R = SoftenFloatRes_FLOG10(N); break;
74 case ISD::FMUL: R = SoftenFloatRes_FMUL(N); break;
75 case ISD::FNEARBYINT: R = SoftenFloatRes_FNEARBYINT(N); break;
76 case ISD::FNEG: R = SoftenFloatRes_FNEG(N); break;
77 case ISD::FP_EXTEND: R = SoftenFloatRes_FP_EXTEND(N); break;
78 case ISD::FP_ROUND: R = SoftenFloatRes_FP_ROUND(N); break;
79 case ISD::FPOW: R = SoftenFloatRes_FPOW(N); break;
80 case ISD::FPOWI: R = SoftenFloatRes_FPOWI(N); break;
81 case ISD::FRINT: R = SoftenFloatRes_FRINT(N); break;
82 case ISD::FSIN: R = SoftenFloatRes_FSIN(N); break;
83 case ISD::FSQRT: R = SoftenFloatRes_FSQRT(N); break;
84 case ISD::FSUB: R = SoftenFloatRes_FSUB(N); break;
85 case ISD::FTRUNC: R = SoftenFloatRes_FTRUNC(N); break;
86 case ISD::LOAD: R = SoftenFloatRes_LOAD(N); break;
87 case ISD::SELECT: R = SoftenFloatRes_SELECT(N); break;
88 case ISD::SELECT_CC: R = SoftenFloatRes_SELECT_CC(N); break;
90 case ISD::UINT_TO_FP: R = SoftenFloatRes_XINT_TO_FP(N); break;
93 // If R is null, the sub-method took care of registering the result.
95 SetSoftenedFloat(SDValue(N, ResNo), R);
98 SDValue DAGTypeLegalizer::SoftenFloatRes_BIT_CONVERT(SDNode *N) {
99 return BitConvertToInteger(N->getOperand(0));
102 SDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) {
103 // Convert the inputs to integers, and build a new pair out of them.
104 return DAG.getNode(ISD::BUILD_PAIR,
105 TLI.getTypeToTransformTo(N->getValueType(0)),
106 BitConvertToInteger(N->getOperand(0)),
107 BitConvertToInteger(N->getOperand(1)));
110 SDValue DAGTypeLegalizer::SoftenFloatRes_ConstantFP(ConstantFPSDNode *N) {
111 return DAG.getConstant(N->getValueAPF().bitcastToAPInt(),
112 TLI.getTypeToTransformTo(N->getValueType(0)));
115 SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) {
116 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
117 unsigned Size = NVT.getSizeInBits();
119 // Mask = ~(1 << (Size-1))
120 SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1),
122 SDValue Op = GetSoftenedFloat(N->getOperand(0));
123 return DAG.getNode(ISD::AND, NVT, Op, Mask);
126 SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) {
127 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
128 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
129 GetSoftenedFloat(N->getOperand(1)) };
130 return MakeLibCall(GetFPLibCall(N->getValueType(0),
138 SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) {
139 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
140 SDValue Op = GetSoftenedFloat(N->getOperand(0));
141 return MakeLibCall(GetFPLibCall(N->getValueType(0),
145 RTLIB::CEIL_PPCF128),
149 SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) {
150 SDValue LHS = GetSoftenedFloat(N->getOperand(0));
151 SDValue RHS = BitConvertToInteger(N->getOperand(1));
153 MVT LVT = LHS.getValueType();
154 MVT RVT = RHS.getValueType();
156 unsigned LSize = LVT.getSizeInBits();
157 unsigned RSize = RVT.getSizeInBits();
159 // First get the sign bit of second operand.
160 SDValue SignBit = DAG.getNode(ISD::SHL, RVT, DAG.getConstant(1, RVT),
161 DAG.getConstant(RSize - 1,
162 TLI.getShiftAmountTy()));
163 SignBit = DAG.getNode(ISD::AND, RVT, RHS, SignBit);
165 // Shift right or sign-extend it if the two operands have different types.
166 int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits();
168 SignBit = DAG.getNode(ISD::SRL, RVT, SignBit,
169 DAG.getConstant(SizeDiff, TLI.getShiftAmountTy()));
170 SignBit = DAG.getNode(ISD::TRUNCATE, LVT, SignBit);
171 } else if (SizeDiff < 0) {
172 SignBit = DAG.getNode(ISD::ANY_EXTEND, LVT, SignBit);
173 SignBit = DAG.getNode(ISD::SHL, LVT, SignBit,
174 DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy()));
177 // Clear the sign bit of the first operand.
178 SDValue Mask = DAG.getNode(ISD::SHL, LVT, DAG.getConstant(1, LVT),
179 DAG.getConstant(LSize - 1,
180 TLI.getShiftAmountTy()));
181 Mask = DAG.getNode(ISD::SUB, LVT, Mask, DAG.getConstant(1, LVT));
182 LHS = DAG.getNode(ISD::AND, LVT, LHS, Mask);
184 // Or the value with the sign bit.
185 return DAG.getNode(ISD::OR, LVT, LHS, SignBit);
188 SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) {
189 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
190 SDValue Op = GetSoftenedFloat(N->getOperand(0));
191 return MakeLibCall(GetFPLibCall(N->getValueType(0),
199 SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) {
200 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
201 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
202 GetSoftenedFloat(N->getOperand(1)) };
203 return MakeLibCall(GetFPLibCall(N->getValueType(0),
211 SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) {
212 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
213 SDValue Op = GetSoftenedFloat(N->getOperand(0));
214 return MakeLibCall(GetFPLibCall(N->getValueType(0),
222 SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) {
223 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
224 SDValue Op = GetSoftenedFloat(N->getOperand(0));
225 return MakeLibCall(GetFPLibCall(N->getValueType(0),
229 RTLIB::EXP2_PPCF128),
233 SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) {
234 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
235 SDValue Op = GetSoftenedFloat(N->getOperand(0));
236 return MakeLibCall(GetFPLibCall(N->getValueType(0),
240 RTLIB::FLOOR_PPCF128),
244 SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) {
245 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
246 SDValue Op = GetSoftenedFloat(N->getOperand(0));
247 return MakeLibCall(GetFPLibCall(N->getValueType(0),
255 SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) {
256 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
257 SDValue Op = GetSoftenedFloat(N->getOperand(0));
258 return MakeLibCall(GetFPLibCall(N->getValueType(0),
262 RTLIB::LOG2_PPCF128),
266 SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) {
267 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
268 SDValue Op = GetSoftenedFloat(N->getOperand(0));
269 return MakeLibCall(GetFPLibCall(N->getValueType(0),
273 RTLIB::LOG10_PPCF128),
277 SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) {
278 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
279 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
280 GetSoftenedFloat(N->getOperand(1)) };
281 return MakeLibCall(GetFPLibCall(N->getValueType(0),
289 SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) {
290 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
291 SDValue Op = GetSoftenedFloat(N->getOperand(0));
292 return MakeLibCall(GetFPLibCall(N->getValueType(0),
293 RTLIB::NEARBYINT_F32,
294 RTLIB::NEARBYINT_F64,
295 RTLIB::NEARBYINT_F80,
296 RTLIB::NEARBYINT_PPCF128),
300 SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) {
301 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
302 // Expand Y = FNEG(X) -> Y = SUB -0.0, X
303 SDValue Ops[2] = { DAG.getConstantFP(-0.0, N->getValueType(0)),
304 GetSoftenedFloat(N->getOperand(0)) };
305 return MakeLibCall(GetFPLibCall(N->getValueType(0),
313 SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) {
314 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
315 SDValue Op = N->getOperand(0);
316 RTLIB::Libcall LC = RTLIB::getFPEXT(Op.getValueType(), N->getValueType(0));
317 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!");
318 return MakeLibCall(LC, NVT, &Op, 1, false);
321 SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) {
322 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
323 SDValue Op = N->getOperand(0);
324 RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), N->getValueType(0));
325 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND!");
326 return MakeLibCall(LC, NVT, &Op, 1, false);
329 SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) {
330 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
331 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
332 GetSoftenedFloat(N->getOperand(1)) };
333 return MakeLibCall(GetFPLibCall(N->getValueType(0),
341 SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) {
342 assert(N->getOperand(1).getValueType() == MVT::i32 &&
343 "Unsupported power type!");
344 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
345 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)), N->getOperand(1) };
346 return MakeLibCall(GetFPLibCall(N->getValueType(0),
350 RTLIB::POWI_PPCF128),
354 SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) {
355 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
356 SDValue Op = GetSoftenedFloat(N->getOperand(0));
357 return MakeLibCall(GetFPLibCall(N->getValueType(0),
361 RTLIB::RINT_PPCF128),
365 SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) {
366 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
367 SDValue Op = GetSoftenedFloat(N->getOperand(0));
368 return MakeLibCall(GetFPLibCall(N->getValueType(0),
376 SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) {
377 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
378 SDValue Op = GetSoftenedFloat(N->getOperand(0));
379 return MakeLibCall(GetFPLibCall(N->getValueType(0),
383 RTLIB::SQRT_PPCF128),
387 SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) {
388 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
389 SDValue Ops[2] = { GetSoftenedFloat(N->getOperand(0)),
390 GetSoftenedFloat(N->getOperand(1)) };
391 return MakeLibCall(GetFPLibCall(N->getValueType(0),
399 SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) {
400 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
401 SDValue Op = GetSoftenedFloat(N->getOperand(0));
402 return MakeLibCall(GetFPLibCall(N->getValueType(0),
406 RTLIB::TRUNC_PPCF128),
410 SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) {
411 LoadSDNode *L = cast<LoadSDNode>(N);
412 MVT VT = N->getValueType(0);
413 MVT NVT = TLI.getTypeToTransformTo(VT);
416 if (L->getExtensionType() == ISD::NON_EXTLOAD) {
417 NewL = DAG.getLoad(L->getAddressingMode(), L->getExtensionType(),
418 NVT, L->getChain(), L->getBasePtr(), L->getOffset(),
419 L->getSrcValue(), L->getSrcValueOffset(), NVT,
420 L->isVolatile(), L->getAlignment());
421 // Legalized the chain result - switch anything that used the old chain to
423 ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
427 // Do a non-extending load followed by FP_EXTEND.
428 NewL = DAG.getLoad(L->getAddressingMode(), ISD::NON_EXTLOAD,
429 L->getMemoryVT(), L->getChain(),
430 L->getBasePtr(), L->getOffset(),
431 L->getSrcValue(), L->getSrcValueOffset(),
433 L->isVolatile(), L->getAlignment());
434 // Legalized the chain result - switch anything that used the old chain to
436 ReplaceValueWith(SDValue(N, 1), NewL.getValue(1));
437 return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, VT, NewL));
440 SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N) {
441 SDValue LHS = GetSoftenedFloat(N->getOperand(1));
442 SDValue RHS = GetSoftenedFloat(N->getOperand(2));
443 return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS);
446 SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N) {
447 SDValue LHS = GetSoftenedFloat(N->getOperand(2));
448 SDValue RHS = GetSoftenedFloat(N->getOperand(3));
449 return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0),
450 N->getOperand(1), LHS, RHS, N->getOperand(4));
453 SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) {
454 bool Signed = N->getOpcode() == ISD::SINT_TO_FP;
455 MVT SVT = N->getOperand(0).getValueType();
456 MVT RVT = N->getValueType(0);
459 // If the input is not legal, eg: i1 -> fp, then it needs to be promoted to
460 // a larger type, eg: i8 -> fp. Even if it is legal, no libcall may exactly
461 // match. Look for an appropriate libcall.
462 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
463 for (unsigned t = MVT::FIRST_INTEGER_VALUETYPE;
464 t <= MVT::LAST_INTEGER_VALUETYPE && LC == RTLIB::UNKNOWN_LIBCALL; ++t) {
465 NVT = (MVT::SimpleValueType)t;
466 // The source needs to big enough to hold the operand.
468 LC = Signed ? RTLIB::getSINTTOFP(NVT, RVT):RTLIB::getUINTTOFP (NVT, RVT);
470 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!");
472 // Sign/zero extend the argument if the libcall takes a larger type.
473 SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
474 NVT, N->getOperand(0));
475 return MakeLibCall(LC, TLI.getTypeToTransformTo(RVT), &Op, 1, false);
479 //===----------------------------------------------------------------------===//
480 // Operand Float to Integer Conversion..
481 //===----------------------------------------------------------------------===//
483 bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) {
484 DEBUG(cerr << "Soften float operand " << OpNo << ": "; N->dump(&DAG);
486 SDValue Res = SDValue();
488 switch (N->getOpcode()) {
491 cerr << "SoftenFloatOperand Op #" << OpNo << ": ";
492 N->dump(&DAG); cerr << "\n";
494 assert(0 && "Do not know how to soften this operator's operand!");
497 case ISD::BIT_CONVERT: Res = SoftenFloatOp_BIT_CONVERT(N); break;
498 case ISD::BR_CC: Res = SoftenFloatOp_BR_CC(N); break;
499 case ISD::FP_ROUND: Res = SoftenFloatOp_FP_ROUND(N); break;
500 case ISD::FP_TO_SINT: Res = SoftenFloatOp_FP_TO_SINT(N); break;
501 case ISD::FP_TO_UINT: Res = SoftenFloatOp_FP_TO_UINT(N); break;
502 case ISD::SELECT_CC: Res = SoftenFloatOp_SELECT_CC(N); break;
503 case ISD::SETCC: Res = SoftenFloatOp_SETCC(N); break;
504 case ISD::STORE: Res = SoftenFloatOp_STORE(N, OpNo); break;
507 // If the result is null, the sub-method took care of registering results etc.
508 if (!Res.getNode()) return false;
510 // If the result is N, the sub-method updated N in place. Tell the legalizer
512 if (Res.getNode() == N)
515 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
516 "Invalid operand expansion");
518 ReplaceValueWith(SDValue(N, 0), Res);
522 /// SoftenSetCCOperands - Soften the operands of a comparison. This code is
523 /// shared among BR_CC, SELECT_CC, and SETCC handlers.
524 void DAGTypeLegalizer::SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS,
525 ISD::CondCode &CCCode) {
526 SDValue LHSInt = GetSoftenedFloat(NewLHS);
527 SDValue RHSInt = GetSoftenedFloat(NewRHS);
528 MVT VT = NewLHS.getValueType();
530 assert((VT == MVT::f32 || VT == MVT::f64) && "Unsupported setcc type!");
532 // Expand into one or more soft-fp libcall(s).
533 RTLIB::Libcall LC1 = RTLIB::UNKNOWN_LIBCALL, LC2 = RTLIB::UNKNOWN_LIBCALL;
537 LC1 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64;
541 LC1 = (VT == MVT::f32) ? RTLIB::UNE_F32 : RTLIB::UNE_F64;
545 LC1 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64;
549 LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
553 LC1 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64;
557 LC1 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64;
560 LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64;
563 LC1 = (VT == MVT::f32) ? RTLIB::O_F32 : RTLIB::O_F64;
566 LC1 = (VT == MVT::f32) ? RTLIB::UO_F32 : RTLIB::UO_F64;
569 // SETONE = SETOLT | SETOGT
570 LC1 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
573 LC2 = (VT == MVT::f32) ? RTLIB::OGT_F32 : RTLIB::OGT_F64;
576 LC2 = (VT == MVT::f32) ? RTLIB::OGE_F32 : RTLIB::OGE_F64;
579 LC2 = (VT == MVT::f32) ? RTLIB::OLT_F32 : RTLIB::OLT_F64;
582 LC2 = (VT == MVT::f32) ? RTLIB::OLE_F32 : RTLIB::OLE_F64;
585 LC2 = (VT == MVT::f32) ? RTLIB::OEQ_F32 : RTLIB::OEQ_F64;
587 default: assert(false && "Do not know how to soften this setcc!");
591 MVT RetVT = MVT::i32; // FIXME: is this the correct return type?
592 SDValue Ops[2] = { LHSInt, RHSInt };
593 NewLHS = MakeLibCall(LC1, RetVT, Ops, 2, false/*sign irrelevant*/);
594 NewRHS = DAG.getConstant(0, RetVT);
595 CCCode = TLI.getCmpLibcallCC(LC1);
596 if (LC2 != RTLIB::UNKNOWN_LIBCALL) {
597 SDValue Tmp = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(RetVT),
598 NewLHS, NewRHS, DAG.getCondCode(CCCode));
599 NewLHS = MakeLibCall(LC2, RetVT, Ops, 2, false/*sign irrelevant*/);
600 NewLHS = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(RetVT), NewLHS,
601 NewRHS, DAG.getCondCode(TLI.getCmpLibcallCC(LC2)));
602 NewLHS = DAG.getNode(ISD::OR, Tmp.getValueType(), Tmp, NewLHS);
607 SDValue DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) {
608 return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0),
609 GetSoftenedFloat(N->getOperand(0)));
612 SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) {
613 MVT SVT = N->getOperand(0).getValueType();
614 MVT RVT = N->getValueType(0);
616 RTLIB::Libcall LC = RTLIB::getFPROUND(SVT, RVT);
617 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall");
619 SDValue Op = GetSoftenedFloat(N->getOperand(0));
620 return MakeLibCall(LC, RVT, &Op, 1, false);
623 SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) {
624 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
625 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
626 SoftenSetCCOperands(NewLHS, NewRHS, CCCode);
628 // If SoftenSetCCOperands returned a scalar, we need to compare the result
629 // against zero to select between true and false values.
630 if (NewRHS.getNode() == 0) {
631 NewRHS = DAG.getConstant(0, NewLHS.getValueType());
635 // Update N to have the operands specified.
636 return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
637 DAG.getCondCode(CCCode), NewLHS, NewRHS,
641 SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode *N) {
642 MVT RVT = N->getValueType(0);
643 RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT);
644 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!");
645 SDValue Op = GetSoftenedFloat(N->getOperand(0));
646 return MakeLibCall(LC, RVT, &Op, 1, false);
649 SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) {
650 MVT RVT = N->getValueType(0);
651 RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT);
652 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!");
653 SDValue Op = GetSoftenedFloat(N->getOperand(0));
654 return MakeLibCall(LC, RVT, &Op, 1, false);
657 SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) {
658 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
659 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
660 SoftenSetCCOperands(NewLHS, NewRHS, CCCode);
662 // If SoftenSetCCOperands returned a scalar, we need to compare the result
663 // against zero to select between true and false values.
664 if (NewRHS.getNode() == 0) {
665 NewRHS = DAG.getConstant(0, NewLHS.getValueType());
669 // Update N to have the operands specified.
670 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
671 N->getOperand(2), N->getOperand(3),
672 DAG.getCondCode(CCCode));
675 SDValue DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) {
676 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
677 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
678 SoftenSetCCOperands(NewLHS, NewRHS, CCCode);
680 // If SoftenSetCCOperands returned a scalar, use it.
681 if (NewRHS.getNode() == 0) {
682 assert(NewLHS.getValueType() == N->getValueType(0) &&
683 "Unexpected setcc expansion!");
687 // Otherwise, update N to have the operands specified.
688 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
689 DAG.getCondCode(CCCode));
692 SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) {
693 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
694 assert(OpNo == 1 && "Can only soften the stored value!");
695 StoreSDNode *ST = cast<StoreSDNode>(N);
696 SDValue Val = ST->getValue();
698 if (ST->isTruncatingStore())
699 // Do an FP_ROUND followed by a non-truncating store.
700 Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, ST->getMemoryVT(),
701 Val, DAG.getIntPtrConstant(0)));
703 Val = GetSoftenedFloat(Val);
705 return DAG.getStore(ST->getChain(), Val, ST->getBasePtr(),
706 ST->getSrcValue(), ST->getSrcValueOffset(),
707 ST->isVolatile(), ST->getAlignment());
711 //===----------------------------------------------------------------------===//
712 // Float Result Expansion
713 //===----------------------------------------------------------------------===//
715 /// ExpandFloatResult - This method is called when the specified result of the
716 /// specified node is found to need expansion. At this point, the node may also
717 /// have invalid operands or may have other results that need promotion, we just
718 /// know that (at least) one result needs expansion.
719 void DAGTypeLegalizer::ExpandFloatResult(SDNode *N, unsigned ResNo) {
720 DEBUG(cerr << "Expand float result: "; N->dump(&DAG); cerr << "\n");
724 // See if the target wants to custom expand this node.
725 if (CustomLowerResults(N, ResNo))
728 switch (N->getOpcode()) {
731 cerr << "ExpandFloatResult #" << ResNo << ": ";
732 N->dump(&DAG); cerr << "\n";
734 assert(0 && "Do not know how to expand the result of this operator!");
737 case ISD::MERGE_VALUES: SplitRes_MERGE_VALUES(N, Lo, Hi); break;
738 case ISD::UNDEF: SplitRes_UNDEF(N, Lo, Hi); break;
739 case ISD::SELECT: SplitRes_SELECT(N, Lo, Hi); break;
740 case ISD::SELECT_CC: SplitRes_SELECT_CC(N, Lo, Hi); break;
742 case ISD::BIT_CONVERT: ExpandRes_BIT_CONVERT(N, Lo, Hi); break;
743 case ISD::BUILD_PAIR: ExpandRes_BUILD_PAIR(N, Lo, Hi); break;
744 case ISD::EXTRACT_ELEMENT: ExpandRes_EXTRACT_ELEMENT(N, Lo, Hi); break;
745 case ISD::EXTRACT_VECTOR_ELT: ExpandRes_EXTRACT_VECTOR_ELT(N, Lo, Hi); break;
746 case ISD::VAARG: ExpandRes_VAARG(N, Lo, Hi); break;
748 case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break;
749 case ISD::FABS: ExpandFloatRes_FABS(N, Lo, Hi); break;
750 case ISD::FADD: ExpandFloatRes_FADD(N, Lo, Hi); break;
751 case ISD::FCEIL: ExpandFloatRes_FCEIL(N, Lo, Hi); break;
752 case ISD::FCOS: ExpandFloatRes_FCOS(N, Lo, Hi); break;
753 case ISD::FDIV: ExpandFloatRes_FDIV(N, Lo, Hi); break;
754 case ISD::FEXP: ExpandFloatRes_FEXP(N, Lo, Hi); break;
755 case ISD::FEXP2: ExpandFloatRes_FEXP2(N, Lo, Hi); break;
756 case ISD::FFLOOR: ExpandFloatRes_FFLOOR(N, Lo, Hi); break;
757 case ISD::FLOG: ExpandFloatRes_FLOG(N, Lo, Hi); break;
758 case ISD::FLOG2: ExpandFloatRes_FLOG2(N, Lo, Hi); break;
759 case ISD::FLOG10: ExpandFloatRes_FLOG10(N, Lo, Hi); break;
760 case ISD::FMUL: ExpandFloatRes_FMUL(N, Lo, Hi); break;
761 case ISD::FNEARBYINT: ExpandFloatRes_FNEARBYINT(N, Lo, Hi); break;
762 case ISD::FNEG: ExpandFloatRes_FNEG(N, Lo, Hi); break;
763 case ISD::FP_EXTEND: ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break;
764 case ISD::FPOW: ExpandFloatRes_FPOW(N, Lo, Hi); break;
765 case ISD::FPOWI: ExpandFloatRes_FPOWI(N, Lo, Hi); break;
766 case ISD::FRINT: ExpandFloatRes_FRINT(N, Lo, Hi); break;
767 case ISD::FSIN: ExpandFloatRes_FSIN(N, Lo, Hi); break;
768 case ISD::FSQRT: ExpandFloatRes_FSQRT(N, Lo, Hi); break;
769 case ISD::FSUB: ExpandFloatRes_FSUB(N, Lo, Hi); break;
770 case ISD::FTRUNC: ExpandFloatRes_FTRUNC(N, Lo, Hi); break;
771 case ISD::LOAD: ExpandFloatRes_LOAD(N, Lo, Hi); break;
772 case ISD::SINT_TO_FP:
773 case ISD::UINT_TO_FP: ExpandFloatRes_XINT_TO_FP(N, Lo, Hi); break;
776 // If Lo/Hi is null, the sub-method took care of registering results etc.
778 SetExpandedFloat(SDValue(N, ResNo), Lo, Hi);
781 void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo,
783 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
784 assert(NVT.getSizeInBits() == integerPartWidth &&
785 "Do not know how to expand this float constant!");
786 APInt C = cast<ConstantFPSDNode>(N)->getValueAPF().bitcastToAPInt();
787 Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1,
788 &C.getRawData()[1])), NVT);
789 Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1,
790 &C.getRawData()[0])), NVT);
793 void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo,
795 assert(N->getValueType(0) == MVT::ppcf128 &&
796 "Logic only correct for ppcf128!");
798 GetExpandedFloat(N->getOperand(0), Lo, Tmp);
799 Hi = DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp);
800 // Lo = Hi==fabs(Hi) ? Lo : -Lo;
801 Lo = DAG.getNode(ISD::SELECT_CC, Lo.getValueType(), Tmp, Hi, Lo,
802 DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo),
803 DAG.getCondCode(ISD::SETEQ));
806 void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDValue &Lo,
808 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
809 RTLIB::ADD_F32, RTLIB::ADD_F64,
810 RTLIB::ADD_F80, RTLIB::ADD_PPCF128),
812 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
813 "Call lowered wrongly!");
814 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
817 void DAGTypeLegalizer::ExpandFloatRes_FCEIL(SDNode *N,
818 SDValue &Lo, SDValue &Hi) {
819 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
820 RTLIB::CEIL_F32, RTLIB::CEIL_F64,
821 RTLIB::CEIL_F80, RTLIB::CEIL_PPCF128),
823 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
824 "Call lowered wrongly!");
825 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
828 void DAGTypeLegalizer::ExpandFloatRes_FCOS(SDNode *N,
829 SDValue &Lo, SDValue &Hi) {
830 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
831 RTLIB::COS_F32, RTLIB::COS_F64,
832 RTLIB::COS_F80, RTLIB::COS_PPCF128),
834 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
835 "Call lowered wrongly!");
836 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
839 void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo,
841 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
842 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0),
847 N->getValueType(0), Ops, 2, false);
848 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
849 "Call lowered wrongly!");
850 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
853 void DAGTypeLegalizer::ExpandFloatRes_FEXP(SDNode *N,
854 SDValue &Lo, SDValue &Hi) {
855 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
856 RTLIB::EXP_F32, RTLIB::EXP_F64,
857 RTLIB::EXP_F80, RTLIB::EXP_PPCF128),
859 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
860 "Call lowered wrongly!");
861 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
864 void DAGTypeLegalizer::ExpandFloatRes_FEXP2(SDNode *N,
865 SDValue &Lo, SDValue &Hi) {
866 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
867 RTLIB::EXP2_F32, RTLIB::EXP2_F64,
868 RTLIB::EXP2_F80, RTLIB::EXP2_PPCF128),
870 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
871 "Call lowered wrongly!");
872 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
875 void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(SDNode *N,
876 SDValue &Lo, SDValue &Hi) {
877 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
878 RTLIB::FLOOR_F32,RTLIB::FLOOR_F64,
879 RTLIB::FLOOR_F80,RTLIB::FLOOR_PPCF128),
881 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
882 "Call lowered wrongly!");
883 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
886 void DAGTypeLegalizer::ExpandFloatRes_FLOG(SDNode *N,
887 SDValue &Lo, SDValue &Hi) {
888 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
889 RTLIB::LOG_F32, RTLIB::LOG_F64,
890 RTLIB::LOG_F80, RTLIB::LOG_PPCF128),
892 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
893 "Call lowered wrongly!");
894 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
897 void DAGTypeLegalizer::ExpandFloatRes_FLOG2(SDNode *N,
898 SDValue &Lo, SDValue &Hi) {
899 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
900 RTLIB::LOG2_F32, RTLIB::LOG2_F64,
901 RTLIB::LOG2_F80, RTLIB::LOG2_PPCF128),
903 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
904 "Call lowered wrongly!");
905 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
908 void DAGTypeLegalizer::ExpandFloatRes_FLOG10(SDNode *N,
909 SDValue &Lo, SDValue &Hi) {
910 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
911 RTLIB::LOG10_F32,RTLIB::LOG10_F64,
912 RTLIB::LOG10_F80,RTLIB::LOG10_PPCF128),
914 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
915 "Call lowered wrongly!");
916 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
919 void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo,
921 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
922 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0),
927 N->getValueType(0), Ops, 2, false);
928 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
929 "Call lowered wrongly!");
930 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
933 void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode *N,
934 SDValue &Lo, SDValue &Hi) {
935 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
936 RTLIB::NEARBYINT_F32,
937 RTLIB::NEARBYINT_F64,
938 RTLIB::NEARBYINT_F80,
939 RTLIB::NEARBYINT_PPCF128),
941 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
942 "Call lowered wrongly!");
943 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
946 void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo,
948 GetExpandedFloat(N->getOperand(0), Lo, Hi);
949 Lo = DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo);
950 Hi = DAG.getNode(ISD::FNEG, Hi.getValueType(), Hi);
953 void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo,
955 MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
956 Hi = DAG.getNode(ISD::FP_EXTEND, NVT, N->getOperand(0));
957 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT);
960 void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode *N,
961 SDValue &Lo, SDValue &Hi) {
962 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
963 RTLIB::POW_F32, RTLIB::POW_F64,
964 RTLIB::POW_F80, RTLIB::POW_PPCF128),
966 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
967 "Call lowered wrongly!");
968 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
971 void DAGTypeLegalizer::ExpandFloatRes_FPOWI(SDNode *N,
972 SDValue &Lo, SDValue &Hi) {
973 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
974 RTLIB::POWI_F32, RTLIB::POWI_F64,
975 RTLIB::POWI_F80, RTLIB::POWI_PPCF128),
977 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
978 "Call lowered wrongly!");
979 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
982 void DAGTypeLegalizer::ExpandFloatRes_FRINT(SDNode *N,
983 SDValue &Lo, SDValue &Hi) {
984 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
985 RTLIB::RINT_F32, RTLIB::RINT_F64,
986 RTLIB::RINT_F80, RTLIB::RINT_PPCF128),
988 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
989 "Call lowered wrongly!");
990 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
993 void DAGTypeLegalizer::ExpandFloatRes_FSIN(SDNode *N,
994 SDValue &Lo, SDValue &Hi) {
995 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
996 RTLIB::SIN_F32, RTLIB::SIN_F64,
997 RTLIB::SIN_F80, RTLIB::SIN_PPCF128),
999 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
1000 "Call lowered wrongly!");
1001 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
1004 void DAGTypeLegalizer::ExpandFloatRes_FSQRT(SDNode *N,
1005 SDValue &Lo, SDValue &Hi) {
1006 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
1007 RTLIB::SQRT_F32, RTLIB::SQRT_F64,
1008 RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128),
1010 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
1011 "Call lowered wrongly!");
1012 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
1015 void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo,
1017 SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
1018 SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0),
1022 RTLIB::SUB_PPCF128),
1023 N->getValueType(0), Ops, 2, false);
1024 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
1025 "Call lowered wrongly!");
1026 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
1029 void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(SDNode *N,
1030 SDValue &Lo, SDValue &Hi) {
1031 SDValue Call = LibCallify(GetFPLibCall(N->getValueType(0),
1032 RTLIB::TRUNC_F32, RTLIB::TRUNC_F64,
1033 RTLIB::TRUNC_F80, RTLIB::TRUNC_PPCF128),
1035 assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
1036 "Call lowered wrongly!");
1037 Lo = Call.getOperand(0); Hi = Call.getOperand(1);
1040 void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo,
1042 if (ISD::isNormalLoad(N)) {
1043 ExpandRes_NormalLoad(N, Lo, Hi);
1047 assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
1048 LoadSDNode *LD = cast<LoadSDNode>(N);
1049 SDValue Chain = LD->getChain();
1050 SDValue Ptr = LD->getBasePtr();
1052 MVT NVT = TLI.getTypeToTransformTo(LD->getValueType(0));
1053 assert(NVT.isByteSized() && "Expanded type not byte sized!");
1054 assert(LD->getMemoryVT().bitsLE(NVT) && "Float type not round?");
1056 Hi = DAG.getExtLoad(LD->getExtensionType(), NVT, Chain, Ptr,
1057 LD->getSrcValue(), LD->getSrcValueOffset(),
1059 LD->isVolatile(), LD->getAlignment());
1061 // Remember the chain.
1062 Chain = Hi.getValue(1);
1064 // The low part is zero.
1065 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT);
1067 // Modified the chain - switch anything that used the old chain to use the
1069 ReplaceValueWith(SDValue(LD, 1), Chain);
1072 void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
1074 assert(N->getValueType(0) == MVT::ppcf128 && "Unsupported XINT_TO_FP!");
1075 MVT VT = N->getValueType(0);
1076 MVT NVT = TLI.getTypeToTransformTo(VT);
1077 SDValue Src = N->getOperand(0);
1078 MVT SrcVT = Src.getValueType();
1079 bool isSigned = N->getOpcode() == ISD::SINT_TO_FP;
1081 // First do an SINT_TO_FP, whether the original was signed or unsigned.
1082 // When promoting partial word types to i32 we must honor the signedness,
1084 if (SrcVT.bitsLE(MVT::i32)) {
1085 // The integer can be represented exactly in an f64.
1086 Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
1088 Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT);
1089 Hi = DAG.getNode(ISD::SINT_TO_FP, NVT, Src);
1091 RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
1092 if (SrcVT.bitsLE(MVT::i64)) {
1093 Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND,
1095 LC = RTLIB::SINTTOFP_I64_PPCF128;
1096 } else if (SrcVT.bitsLE(MVT::i128)) {
1097 Src = DAG.getNode(ISD::SIGN_EXTEND, MVT::i128, Src);
1098 LC = RTLIB::SINTTOFP_I128_PPCF128;
1100 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!");
1102 Hi = MakeLibCall(LC, VT, &Src, 1, true);
1103 assert(Hi.getNode()->getOpcode() == ISD::BUILD_PAIR &&
1104 "Call lowered wrongly!");
1105 Lo = Hi.getOperand(0); Hi = Hi.getOperand(1);
1111 // Unsigned - fix up the SINT_TO_FP value just calculated.
1112 Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi);
1113 SrcVT = Src.getValueType();
1115 // x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128.
1116 static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 };
1117 static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 };
1118 static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
1119 const uint64_t *Parts = 0;
1121 switch (SrcVT.getSimpleVT()) {
1123 assert(false && "Unsupported UINT_TO_FP!");
1135 Lo = DAG.getNode(ISD::FADD, VT, Hi,
1136 DAG.getConstantFP(APFloat(APInt(128, 2, Parts)),
1138 Lo = DAG.getNode(ISD::SELECT_CC, VT, Src, DAG.getConstant(0, SrcVT), Lo, Hi,
1139 DAG.getCondCode(ISD::SETLT));
1140 Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, DAG.getIntPtrConstant(1));
1141 Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, DAG.getIntPtrConstant(0));
1145 //===----------------------------------------------------------------------===//
1146 // Float Operand Expansion
1147 //===----------------------------------------------------------------------===//
1149 /// ExpandFloatOperand - This method is called when the specified operand of the
1150 /// specified node is found to need expansion. At this point, all of the result
1151 /// types of the node are known to be legal, but other operands of the node may
1152 /// need promotion or expansion as well as the specified one.
1153 bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
1154 DEBUG(cerr << "Expand float operand: "; N->dump(&DAG); cerr << "\n");
1155 SDValue Res = SDValue();
1157 if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
1158 == TargetLowering::Custom)
1159 Res = TLI.LowerOperation(SDValue(N, 0), DAG);
1161 if (Res.getNode() == 0) {
1162 switch (N->getOpcode()) {
1165 cerr << "ExpandFloatOperand Op #" << OpNo << ": ";
1166 N->dump(&DAG); cerr << "\n";
1168 assert(0 && "Do not know how to expand this operator's operand!");
1171 case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break;
1172 case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break;
1173 case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
1175 case ISD::BR_CC: Res = ExpandFloatOp_BR_CC(N); break;
1176 case ISD::FP_ROUND: Res = ExpandFloatOp_FP_ROUND(N); break;
1177 case ISD::FP_TO_SINT: Res = ExpandFloatOp_FP_TO_SINT(N); break;
1178 case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_UINT(N); break;
1179 case ISD::SELECT_CC: Res = ExpandFloatOp_SELECT_CC(N); break;
1180 case ISD::SETCC: Res = ExpandFloatOp_SETCC(N); break;
1181 case ISD::STORE: Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N),
1186 // If the result is null, the sub-method took care of registering results etc.
1187 if (!Res.getNode()) return false;
1189 // If the result is N, the sub-method updated N in place. Tell the legalizer
1191 if (Res.getNode() == N)
1194 assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
1195 "Invalid operand expansion");
1197 ReplaceValueWith(SDValue(N, 0), Res);
1201 /// FloatExpandSetCCOperands - Expand the operands of a comparison. This code
1202 /// is shared among BR_CC, SELECT_CC, and SETCC handlers.
1203 void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS,
1205 ISD::CondCode &CCCode) {
1206 SDValue LHSLo, LHSHi, RHSLo, RHSHi;
1207 GetExpandedFloat(NewLHS, LHSLo, LHSHi);
1208 GetExpandedFloat(NewRHS, RHSLo, RHSHi);
1210 MVT VT = NewLHS.getValueType();
1211 assert(VT == MVT::ppcf128 && "Unsupported setcc type!");
1213 // FIXME: This generated code sucks. We want to generate
1214 // FCMPU crN, hi1, hi2
1216 // FCMPU crN, lo1, lo2
1217 // The following can be improved, but not that much.
1218 SDValue Tmp1, Tmp2, Tmp3;
1219 Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
1220 LHSHi, RHSHi, ISD::SETOEQ);
1221 Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo.getValueType()),
1222 LHSLo, RHSLo, CCCode);
1223 Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
1224 Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
1225 LHSHi, RHSHi, ISD::SETUNE);
1226 Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()),
1227 LHSHi, RHSHi, CCCode);
1228 Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
1229 NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3);
1230 NewRHS = SDValue(); // LHS is the result, not a compare.
1233 SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) {
1234 SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
1235 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
1236 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode);
1238 // If ExpandSetCCOperands returned a scalar, we need to compare the result
1239 // against zero to select between true and false values.
1240 if (NewRHS.getNode() == 0) {
1241 NewRHS = DAG.getConstant(0, NewLHS.getValueType());
1242 CCCode = ISD::SETNE;
1245 // Update N to have the operands specified.
1246 return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
1247 DAG.getCondCode(CCCode), NewLHS, NewRHS,
1251 SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) {
1252 assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
1253 "Logic only correct for ppcf128!");
1255 GetExpandedFloat(N->getOperand(0), Lo, Hi);
1256 // Round it the rest of the way (e.g. to f32) if needed.
1257 return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Hi, N->getOperand(1));
1260 SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) {
1261 MVT RVT = N->getValueType(0);
1263 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
1264 // PPC (the libcall is not available). FIXME: Do this in a less hacky way.
1265 if (RVT == MVT::i32) {
1266 assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
1267 "Logic only correct for ppcf128!");
1268 SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, MVT::ppcf128,
1269 N->getOperand(0), DAG.getValueType(MVT::f64));
1270 Res = DAG.getNode(ISD::FP_ROUND, MVT::f64, Res, DAG.getIntPtrConstant(1));
1271 return DAG.getNode(ISD::FP_TO_SINT, MVT::i32, Res);
1274 RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT);
1275 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!");
1276 return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false);
1279 SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) {
1280 MVT RVT = N->getValueType(0);
1282 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
1283 // PPC (the libcall is not available). FIXME: Do this in a less hacky way.
1284 if (RVT == MVT::i32) {
1285 assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
1286 "Logic only correct for ppcf128!");
1287 const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
1288 APFloat APF = APFloat(APInt(128, 2, TwoE31));
1289 SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128);
1290 // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
1291 // FIXME: generated code sucks.
1292 return DAG.getNode(ISD::SELECT_CC, MVT::i32, N->getOperand(0), Tmp,
1293 DAG.getNode(ISD::ADD, MVT::i32,
1294 DAG.getNode(ISD::FP_TO_SINT, MVT::i32,
1295 DAG.getNode(ISD::FSUB,
1299 DAG.getConstant(0x80000000, MVT::i32)),
1300 DAG.getNode(ISD::FP_TO_SINT, MVT::i32, N->getOperand(0)),
1301 DAG.getCondCode(ISD::SETGE));
1304 RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT);
1305 assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!");
1306 return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false);
1309 SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) {
1310 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
1311 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
1312 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode);
1314 // If ExpandSetCCOperands returned a scalar, we need to compare the result
1315 // against zero to select between true and false values.
1316 if (NewRHS.getNode() == 0) {
1317 NewRHS = DAG.getConstant(0, NewLHS.getValueType());
1318 CCCode = ISD::SETNE;
1321 // Update N to have the operands specified.
1322 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
1323 N->getOperand(2), N->getOperand(3),
1324 DAG.getCondCode(CCCode));
1327 SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) {
1328 SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
1329 ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
1330 FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode);
1332 // If ExpandSetCCOperands returned a scalar, use it.
1333 if (NewRHS.getNode() == 0) {
1334 assert(NewLHS.getValueType() == N->getValueType(0) &&
1335 "Unexpected setcc expansion!");
1339 // Otherwise, update N to have the operands specified.
1340 return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
1341 DAG.getCondCode(CCCode));
1344 SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) {
1345 if (ISD::isNormalStore(N))
1346 return ExpandOp_NormalStore(N, OpNo);
1348 assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
1349 assert(OpNo == 1 && "Can only expand the stored value so far");
1350 StoreSDNode *ST = cast<StoreSDNode>(N);
1352 SDValue Chain = ST->getChain();
1353 SDValue Ptr = ST->getBasePtr();
1355 MVT NVT = TLI.getTypeToTransformTo(ST->getValue().getValueType());
1356 assert(NVT.isByteSized() && "Expanded type not byte sized!");
1357 assert(ST->getMemoryVT().bitsLE(NVT) && "Float type not round?");
1360 GetExpandedOp(ST->getValue(), Lo, Hi);
1362 return DAG.getTruncStore(Chain, Hi, Ptr,
1363 ST->getSrcValue(), ST->getSrcValueOffset(),
1365 ST->isVolatile(), ST->getAlignment());