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"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/raw_ostream.h"
27 /// GetFPLibCall - Return the right libcall for the given floating point type.
28 static RTLIB::Libcall
GetFPLibCall(EVT VT
,
29 RTLIB::Libcall Call_F32
,
30 RTLIB::Libcall Call_F64
,
31 RTLIB::Libcall Call_F80
,
32 RTLIB::Libcall Call_PPCF128
) {
34 VT
== MVT::f32
? Call_F32
:
35 VT
== MVT::f64
? Call_F64
:
36 VT
== MVT::f80
? Call_F80
:
37 VT
== MVT::ppcf128
? Call_PPCF128
:
38 RTLIB::UNKNOWN_LIBCALL
;
41 //===----------------------------------------------------------------------===//
42 // Result Float to Integer Conversion.
43 //===----------------------------------------------------------------------===//
45 void DAGTypeLegalizer::SoftenFloatResult(SDNode
*N
, unsigned ResNo
) {
46 DEBUG(errs() << "Soften float result " << ResNo
<< ": "; N
->dump(&DAG
);
48 SDValue R
= SDValue();
50 switch (N
->getOpcode()) {
53 errs() << "SoftenFloatResult #" << ResNo
<< ": ";
54 N
->dump(&DAG
); errs() << "\n";
56 llvm_unreachable("Do not know how to soften the result of this operator!");
58 case ISD::BIT_CONVERT
: R
= SoftenFloatRes_BIT_CONVERT(N
); break;
59 case ISD::BUILD_PAIR
: R
= SoftenFloatRes_BUILD_PAIR(N
); break;
61 R
= SoftenFloatRes_ConstantFP(cast
<ConstantFPSDNode
>(N
));
63 case ISD::EXTRACT_VECTOR_ELT
:
64 R
= SoftenFloatRes_EXTRACT_VECTOR_ELT(N
); break;
65 case ISD::FABS
: R
= SoftenFloatRes_FABS(N
); break;
66 case ISD::FADD
: R
= SoftenFloatRes_FADD(N
); break;
67 case ISD::FCEIL
: R
= SoftenFloatRes_FCEIL(N
); break;
68 case ISD::FCOPYSIGN
: R
= SoftenFloatRes_FCOPYSIGN(N
); break;
69 case ISD::FCOS
: R
= SoftenFloatRes_FCOS(N
); break;
70 case ISD::FDIV
: R
= SoftenFloatRes_FDIV(N
); break;
71 case ISD::FEXP
: R
= SoftenFloatRes_FEXP(N
); break;
72 case ISD::FEXP2
: R
= SoftenFloatRes_FEXP2(N
); break;
73 case ISD::FFLOOR
: R
= SoftenFloatRes_FFLOOR(N
); break;
74 case ISD::FLOG
: R
= SoftenFloatRes_FLOG(N
); break;
75 case ISD::FLOG2
: R
= SoftenFloatRes_FLOG2(N
); break;
76 case ISD::FLOG10
: R
= SoftenFloatRes_FLOG10(N
); break;
77 case ISD::FMUL
: R
= SoftenFloatRes_FMUL(N
); break;
78 case ISD::FNEARBYINT
: R
= SoftenFloatRes_FNEARBYINT(N
); break;
79 case ISD::FNEG
: R
= SoftenFloatRes_FNEG(N
); break;
80 case ISD::FP_EXTEND
: R
= SoftenFloatRes_FP_EXTEND(N
); break;
81 case ISD::FP_ROUND
: R
= SoftenFloatRes_FP_ROUND(N
); break;
82 case ISD::FPOW
: R
= SoftenFloatRes_FPOW(N
); break;
83 case ISD::FPOWI
: R
= SoftenFloatRes_FPOWI(N
); break;
84 case ISD::FREM
: R
= SoftenFloatRes_FREM(N
); break;
85 case ISD::FRINT
: R
= SoftenFloatRes_FRINT(N
); break;
86 case ISD::FSIN
: R
= SoftenFloatRes_FSIN(N
); break;
87 case ISD::FSQRT
: R
= SoftenFloatRes_FSQRT(N
); break;
88 case ISD::FSUB
: R
= SoftenFloatRes_FSUB(N
); break;
89 case ISD::FTRUNC
: R
= SoftenFloatRes_FTRUNC(N
); break;
90 case ISD::LOAD
: R
= SoftenFloatRes_LOAD(N
); break;
91 case ISD::SELECT
: R
= SoftenFloatRes_SELECT(N
); break;
92 case ISD::SELECT_CC
: R
= SoftenFloatRes_SELECT_CC(N
); break;
94 case ISD::UINT_TO_FP
: R
= SoftenFloatRes_XINT_TO_FP(N
); break;
95 case ISD::UNDEF
: R
= SoftenFloatRes_UNDEF(N
); break;
96 case ISD::VAARG
: R
= SoftenFloatRes_VAARG(N
); break;
99 // If R is null, the sub-method took care of registering the result.
101 SetSoftenedFloat(SDValue(N
, ResNo
), R
);
104 SDValue
DAGTypeLegalizer::SoftenFloatRes_BIT_CONVERT(SDNode
*N
) {
105 return BitConvertToInteger(N
->getOperand(0));
108 SDValue
DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode
*N
) {
109 // Convert the inputs to integers, and build a new pair out of them.
110 return DAG
.getNode(ISD::BUILD_PAIR
, N
->getDebugLoc(),
111 TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0)),
112 BitConvertToInteger(N
->getOperand(0)),
113 BitConvertToInteger(N
->getOperand(1)));
116 SDValue
DAGTypeLegalizer::SoftenFloatRes_ConstantFP(ConstantFPSDNode
*N
) {
117 return DAG
.getConstant(N
->getValueAPF().bitcastToAPInt(),
118 TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0)));
121 SDValue
DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode
*N
) {
122 SDValue NewOp
= BitConvertVectorToIntegerVector(N
->getOperand(0));
123 return DAG
.getNode(ISD::EXTRACT_VECTOR_ELT
, N
->getDebugLoc(),
124 NewOp
.getValueType().getVectorElementType(),
125 NewOp
, N
->getOperand(1));
128 SDValue
DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode
*N
) {
129 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
130 unsigned Size
= NVT
.getSizeInBits();
132 // Mask = ~(1 << (Size-1))
133 SDValue Mask
= DAG
.getConstant(APInt::getAllOnesValue(Size
).clear(Size
-1),
135 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
136 return DAG
.getNode(ISD::AND
, N
->getDebugLoc(), NVT
, Op
, Mask
);
139 SDValue
DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode
*N
) {
140 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
141 SDValue Ops
[2] = { GetSoftenedFloat(N
->getOperand(0)),
142 GetSoftenedFloat(N
->getOperand(1)) };
143 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
148 NVT
, Ops
, 2, false, N
->getDebugLoc());
151 SDValue
DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode
*N
) {
152 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
153 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
154 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
158 RTLIB::CEIL_PPCF128
),
159 NVT
, &Op
, 1, false, N
->getDebugLoc());
162 SDValue
DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode
*N
) {
163 SDValue LHS
= GetSoftenedFloat(N
->getOperand(0));
164 SDValue RHS
= BitConvertToInteger(N
->getOperand(1));
165 DebugLoc dl
= N
->getDebugLoc();
167 EVT LVT
= LHS
.getValueType();
168 EVT RVT
= RHS
.getValueType();
170 unsigned LSize
= LVT
.getSizeInBits();
171 unsigned RSize
= RVT
.getSizeInBits();
173 // First get the sign bit of second operand.
174 SDValue SignBit
= DAG
.getNode(ISD::SHL
, dl
, RVT
, DAG
.getConstant(1, RVT
),
175 DAG
.getConstant(RSize
- 1,
176 TLI
.getShiftAmountTy()));
177 SignBit
= DAG
.getNode(ISD::AND
, dl
, RVT
, RHS
, SignBit
);
179 // Shift right or sign-extend it if the two operands have different types.
180 int SizeDiff
= RVT
.getSizeInBits() - LVT
.getSizeInBits();
182 SignBit
= DAG
.getNode(ISD::SRL
, dl
, RVT
, SignBit
,
183 DAG
.getConstant(SizeDiff
, TLI
.getShiftAmountTy()));
184 SignBit
= DAG
.getNode(ISD::TRUNCATE
, dl
, LVT
, SignBit
);
185 } else if (SizeDiff
< 0) {
186 SignBit
= DAG
.getNode(ISD::ANY_EXTEND
, dl
, LVT
, SignBit
);
187 SignBit
= DAG
.getNode(ISD::SHL
, dl
, LVT
, SignBit
,
188 DAG
.getConstant(-SizeDiff
, TLI
.getShiftAmountTy()));
191 // Clear the sign bit of the first operand.
192 SDValue Mask
= DAG
.getNode(ISD::SHL
, dl
, LVT
, DAG
.getConstant(1, LVT
),
193 DAG
.getConstant(LSize
- 1,
194 TLI
.getShiftAmountTy()));
195 Mask
= DAG
.getNode(ISD::SUB
, dl
, LVT
, Mask
, DAG
.getConstant(1, LVT
));
196 LHS
= DAG
.getNode(ISD::AND
, dl
, LVT
, LHS
, Mask
);
198 // Or the value with the sign bit.
199 return DAG
.getNode(ISD::OR
, dl
, LVT
, LHS
, SignBit
);
202 SDValue
DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode
*N
) {
203 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
204 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
205 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
210 NVT
, &Op
, 1, false, N
->getDebugLoc());
213 SDValue
DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode
*N
) {
214 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
215 SDValue Ops
[2] = { GetSoftenedFloat(N
->getOperand(0)),
216 GetSoftenedFloat(N
->getOperand(1)) };
217 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
222 NVT
, Ops
, 2, false, N
->getDebugLoc());
225 SDValue
DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode
*N
) {
226 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
227 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
228 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
233 NVT
, &Op
, 1, false, N
->getDebugLoc());
236 SDValue
DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode
*N
) {
237 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
238 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
239 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
243 RTLIB::EXP2_PPCF128
),
244 NVT
, &Op
, 1, false, N
->getDebugLoc());
247 SDValue
DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode
*N
) {
248 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
249 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
250 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
254 RTLIB::FLOOR_PPCF128
),
255 NVT
, &Op
, 1, false, N
->getDebugLoc());
258 SDValue
DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode
*N
) {
259 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
260 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
261 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
266 NVT
, &Op
, 1, false, N
->getDebugLoc());
269 SDValue
DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode
*N
) {
270 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
271 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
272 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
276 RTLIB::LOG2_PPCF128
),
277 NVT
, &Op
, 1, false, N
->getDebugLoc());
280 SDValue
DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode
*N
) {
281 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
282 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
283 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
287 RTLIB::LOG10_PPCF128
),
288 NVT
, &Op
, 1, false, N
->getDebugLoc());
291 SDValue
DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode
*N
) {
292 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
293 SDValue Ops
[2] = { GetSoftenedFloat(N
->getOperand(0)),
294 GetSoftenedFloat(N
->getOperand(1)) };
295 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
300 NVT
, Ops
, 2, false, N
->getDebugLoc());
303 SDValue
DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode
*N
) {
304 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
305 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
306 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
307 RTLIB::NEARBYINT_F32
,
308 RTLIB::NEARBYINT_F64
,
309 RTLIB::NEARBYINT_F80
,
310 RTLIB::NEARBYINT_PPCF128
),
311 NVT
, &Op
, 1, false, N
->getDebugLoc());
314 SDValue
DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode
*N
) {
315 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
316 // Expand Y = FNEG(X) -> Y = SUB -0.0, X
317 SDValue Ops
[2] = { DAG
.getConstantFP(-0.0, N
->getValueType(0)),
318 GetSoftenedFloat(N
->getOperand(0)) };
319 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
324 NVT
, Ops
, 2, false, N
->getDebugLoc());
327 SDValue
DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode
*N
) {
328 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
329 SDValue Op
= N
->getOperand(0);
330 RTLIB::Libcall LC
= RTLIB::getFPEXT(Op
.getValueType(), N
->getValueType(0));
331 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported FP_EXTEND!");
332 return MakeLibCall(LC
, NVT
, &Op
, 1, false, N
->getDebugLoc());
335 SDValue
DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode
*N
) {
336 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
337 SDValue Op
= N
->getOperand(0);
338 RTLIB::Libcall LC
= RTLIB::getFPROUND(Op
.getValueType(), N
->getValueType(0));
339 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported FP_ROUND!");
340 return MakeLibCall(LC
, NVT
, &Op
, 1, false, N
->getDebugLoc());
343 SDValue
DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode
*N
) {
344 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
345 SDValue Ops
[2] = { GetSoftenedFloat(N
->getOperand(0)),
346 GetSoftenedFloat(N
->getOperand(1)) };
347 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
352 NVT
, Ops
, 2, false, N
->getDebugLoc());
355 SDValue
DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode
*N
) {
356 assert(N
->getOperand(1).getValueType() == MVT::i32
&&
357 "Unsupported power type!");
358 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
359 SDValue Ops
[2] = { GetSoftenedFloat(N
->getOperand(0)), N
->getOperand(1) };
360 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
364 RTLIB::POWI_PPCF128
),
365 NVT
, Ops
, 2, false, N
->getDebugLoc());
368 SDValue
DAGTypeLegalizer::SoftenFloatRes_FREM(SDNode
*N
) {
369 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
370 SDValue Ops
[2] = { GetSoftenedFloat(N
->getOperand(0)),
371 GetSoftenedFloat(N
->getOperand(1)) };
372 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
377 NVT
, Ops
, 2, false, N
->getDebugLoc());
380 SDValue
DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode
*N
) {
381 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
382 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
383 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
387 RTLIB::RINT_PPCF128
),
388 NVT
, &Op
, 1, false, N
->getDebugLoc());
391 SDValue
DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode
*N
) {
392 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
393 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
394 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
399 NVT
, &Op
, 1, false, N
->getDebugLoc());
402 SDValue
DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode
*N
) {
403 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
404 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
405 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
409 RTLIB::SQRT_PPCF128
),
410 NVT
, &Op
, 1, false, N
->getDebugLoc());
413 SDValue
DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode
*N
) {
414 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
415 SDValue Ops
[2] = { GetSoftenedFloat(N
->getOperand(0)),
416 GetSoftenedFloat(N
->getOperand(1)) };
417 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
422 NVT
, Ops
, 2, false, N
->getDebugLoc());
425 SDValue
DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode
*N
) {
426 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
427 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
428 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
432 RTLIB::TRUNC_PPCF128
),
433 NVT
, &Op
, 1, false, N
->getDebugLoc());
436 SDValue
DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode
*N
) {
437 LoadSDNode
*L
= cast
<LoadSDNode
>(N
);
438 EVT VT
= N
->getValueType(0);
439 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
440 DebugLoc dl
= N
->getDebugLoc();
443 if (L
->getExtensionType() == ISD::NON_EXTLOAD
) {
444 NewL
= DAG
.getLoad(L
->getAddressingMode(), dl
, L
->getExtensionType(),
445 NVT
, L
->getChain(), L
->getBasePtr(), L
->getOffset(),
446 L
->getSrcValue(), L
->getSrcValueOffset(), NVT
,
447 L
->isVolatile(), L
->getAlignment());
448 // Legalized the chain result - switch anything that used the old chain to
450 ReplaceValueWith(SDValue(N
, 1), NewL
.getValue(1));
454 // Do a non-extending load followed by FP_EXTEND.
455 NewL
= DAG
.getLoad(L
->getAddressingMode(), dl
, ISD::NON_EXTLOAD
,
456 L
->getMemoryVT(), L
->getChain(),
457 L
->getBasePtr(), L
->getOffset(),
458 L
->getSrcValue(), L
->getSrcValueOffset(),
460 L
->isVolatile(), L
->getAlignment());
461 // Legalized the chain result - switch anything that used the old chain to
463 ReplaceValueWith(SDValue(N
, 1), NewL
.getValue(1));
464 return BitConvertToInteger(DAG
.getNode(ISD::FP_EXTEND
, dl
, VT
, NewL
));
467 SDValue
DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode
*N
) {
468 SDValue LHS
= GetSoftenedFloat(N
->getOperand(1));
469 SDValue RHS
= GetSoftenedFloat(N
->getOperand(2));
470 return DAG
.getNode(ISD::SELECT
, N
->getDebugLoc(),
471 LHS
.getValueType(), N
->getOperand(0),LHS
,RHS
);
474 SDValue
DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode
*N
) {
475 SDValue LHS
= GetSoftenedFloat(N
->getOperand(2));
476 SDValue RHS
= GetSoftenedFloat(N
->getOperand(3));
477 return DAG
.getNode(ISD::SELECT_CC
, N
->getDebugLoc(),
478 LHS
.getValueType(), N
->getOperand(0),
479 N
->getOperand(1), LHS
, RHS
, N
->getOperand(4));
482 SDValue
DAGTypeLegalizer::SoftenFloatRes_UNDEF(SDNode
*N
) {
483 return DAG
.getUNDEF(TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0)));
486 SDValue
DAGTypeLegalizer::SoftenFloatRes_VAARG(SDNode
*N
) {
487 SDValue Chain
= N
->getOperand(0); // Get the chain.
488 SDValue Ptr
= N
->getOperand(1); // Get the pointer.
489 EVT VT
= N
->getValueType(0);
490 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
491 DebugLoc dl
= N
->getDebugLoc();
494 NewVAARG
= DAG
.getVAArg(NVT
, dl
, Chain
, Ptr
, N
->getOperand(2));
496 // Legalized the chain result - switch anything that used the old chain to
498 ReplaceValueWith(SDValue(N
, 1), NewVAARG
.getValue(1));
502 SDValue
DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode
*N
) {
503 bool Signed
= N
->getOpcode() == ISD::SINT_TO_FP
;
504 EVT SVT
= N
->getOperand(0).getValueType();
505 EVT RVT
= N
->getValueType(0);
507 DebugLoc dl
= N
->getDebugLoc();
509 // If the input is not legal, eg: i1 -> fp, then it needs to be promoted to
510 // a larger type, eg: i8 -> fp. Even if it is legal, no libcall may exactly
511 // match. Look for an appropriate libcall.
512 RTLIB::Libcall LC
= RTLIB::UNKNOWN_LIBCALL
;
513 for (unsigned t
= MVT::FIRST_INTEGER_VALUETYPE
;
514 t
<= MVT::LAST_INTEGER_VALUETYPE
&& LC
== RTLIB::UNKNOWN_LIBCALL
; ++t
) {
515 NVT
= (MVT::SimpleValueType
)t
;
516 // The source needs to big enough to hold the operand.
518 LC
= Signed
? RTLIB::getSINTTOFP(NVT
, RVT
):RTLIB::getUINTTOFP (NVT
, RVT
);
520 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported XINT_TO_FP!");
522 // Sign/zero extend the argument if the libcall takes a larger type.
523 SDValue Op
= DAG
.getNode(Signed
? ISD::SIGN_EXTEND
: ISD::ZERO_EXTEND
, dl
,
524 NVT
, N
->getOperand(0));
525 return MakeLibCall(LC
, TLI
.getTypeToTransformTo(*DAG
.getContext(), RVT
), &Op
, 1, false, dl
);
529 //===----------------------------------------------------------------------===//
530 // Operand Float to Integer Conversion..
531 //===----------------------------------------------------------------------===//
533 bool DAGTypeLegalizer::SoftenFloatOperand(SDNode
*N
, unsigned OpNo
) {
534 DEBUG(errs() << "Soften float operand " << OpNo
<< ": "; N
->dump(&DAG
);
536 SDValue Res
= SDValue();
538 switch (N
->getOpcode()) {
541 errs() << "SoftenFloatOperand Op #" << OpNo
<< ": ";
542 N
->dump(&DAG
); errs() << "\n";
544 llvm_unreachable("Do not know how to soften this operator's operand!");
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;
556 // If the result is null, the sub-method took care of registering results etc.
557 if (!Res
.getNode()) return false;
559 // If the result is N, the sub-method updated N in place. Tell the legalizer
561 if (Res
.getNode() == N
)
564 assert(Res
.getValueType() == N
->getValueType(0) && N
->getNumValues() == 1 &&
565 "Invalid operand expansion");
567 ReplaceValueWith(SDValue(N
, 0), Res
);
571 /// SoftenSetCCOperands - Soften the operands of a comparison. This code is
572 /// shared among BR_CC, SELECT_CC, and SETCC handlers.
573 void DAGTypeLegalizer::SoftenSetCCOperands(SDValue
&NewLHS
, SDValue
&NewRHS
,
574 ISD::CondCode
&CCCode
, DebugLoc dl
) {
575 SDValue LHSInt
= GetSoftenedFloat(NewLHS
);
576 SDValue RHSInt
= GetSoftenedFloat(NewRHS
);
577 EVT VT
= NewLHS
.getValueType();
579 assert((VT
== MVT::f32
|| VT
== MVT::f64
) && "Unsupported setcc type!");
581 // Expand into one or more soft-fp libcall(s).
582 RTLIB::Libcall LC1
= RTLIB::UNKNOWN_LIBCALL
, LC2
= RTLIB::UNKNOWN_LIBCALL
;
586 LC1
= (VT
== MVT::f32
) ? RTLIB::OEQ_F32
: RTLIB::OEQ_F64
;
590 LC1
= (VT
== MVT::f32
) ? RTLIB::UNE_F32
: RTLIB::UNE_F64
;
594 LC1
= (VT
== MVT::f32
) ? RTLIB::OGE_F32
: RTLIB::OGE_F64
;
598 LC1
= (VT
== MVT::f32
) ? RTLIB::OLT_F32
: RTLIB::OLT_F64
;
602 LC1
= (VT
== MVT::f32
) ? RTLIB::OLE_F32
: RTLIB::OLE_F64
;
606 LC1
= (VT
== MVT::f32
) ? RTLIB::OGT_F32
: RTLIB::OGT_F64
;
609 LC1
= (VT
== MVT::f32
) ? RTLIB::UO_F32
: RTLIB::UO_F64
;
612 LC1
= (VT
== MVT::f32
) ? RTLIB::O_F32
: RTLIB::O_F64
;
615 LC1
= (VT
== MVT::f32
) ? RTLIB::UO_F32
: RTLIB::UO_F64
;
618 // SETONE = SETOLT | SETOGT
619 LC1
= (VT
== MVT::f32
) ? RTLIB::OLT_F32
: RTLIB::OLT_F64
;
622 LC2
= (VT
== MVT::f32
) ? RTLIB::OGT_F32
: RTLIB::OGT_F64
;
625 LC2
= (VT
== MVT::f32
) ? RTLIB::OGE_F32
: RTLIB::OGE_F64
;
628 LC2
= (VT
== MVT::f32
) ? RTLIB::OLT_F32
: RTLIB::OLT_F64
;
631 LC2
= (VT
== MVT::f32
) ? RTLIB::OLE_F32
: RTLIB::OLE_F64
;
634 LC2
= (VT
== MVT::f32
) ? RTLIB::OEQ_F32
: RTLIB::OEQ_F64
;
636 default: assert(false && "Do not know how to soften this setcc!");
640 EVT 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
);
656 SDValue
DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode
*N
) {
657 return DAG
.getNode(ISD::BIT_CONVERT
, N
->getDebugLoc(), N
->getValueType(0),
658 GetSoftenedFloat(N
->getOperand(0)));
661 SDValue
DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode
*N
) {
662 EVT SVT
= N
->getOperand(0).getValueType();
663 EVT RVT
= N
->getValueType(0);
665 RTLIB::Libcall LC
= RTLIB::getFPROUND(SVT
, RVT
);
666 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported FP_ROUND libcall");
668 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
669 return MakeLibCall(LC
, RVT
, &Op
, 1, false, N
->getDebugLoc());
672 SDValue
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());
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());
684 // Update N to have the operands specified.
685 return DAG
.UpdateNodeOperands(SDValue(N
, 0), N
->getOperand(0),
686 DAG
.getCondCode(CCCode
), NewLHS
, NewRHS
,
690 SDValue
DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode
*N
) {
691 EVT 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());
698 SDValue
DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode
*N
) {
699 EVT 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());
706 SDValue
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());
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());
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
));
724 SDValue
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());
729 // If SoftenSetCCOperands returned a scalar, use it.
730 if (NewRHS
.getNode() == 0) {
731 assert(NewLHS
.getValueType() == N
->getValueType(0) &&
732 "Unexpected setcc expansion!");
736 // Otherwise, update N to have the operands specified.
737 return DAG
.UpdateNodeOperands(SDValue(N
, 0), NewLHS
, NewRHS
,
738 DAG
.getCondCode(CCCode
));
741 SDValue
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();
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)));
753 Val
= GetSoftenedFloat(Val
);
755 return DAG
.getStore(ST
->getChain(), dl
, Val
, ST
->getBasePtr(),
756 ST
->getSrcValue(), ST
->getSrcValueOffset(),
757 ST
->isVolatile(), ST
->getAlignment());
761 //===----------------------------------------------------------------------===//
762 // Float Result Expansion
763 //===----------------------------------------------------------------------===//
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.
769 void DAGTypeLegalizer::ExpandFloatResult(SDNode
*N
, unsigned ResNo
) {
770 DEBUG(errs() << "Expand float result: "; N
->dump(&DAG
); errs() << "\n");
774 // See if the target wants to custom expand this node.
775 if (CustomLowerNode(N
, N
->getValueType(ResNo
), true))
778 switch (N
->getOpcode()) {
781 errs() << "ExpandFloatResult #" << ResNo
<< ": ";
782 N
->dump(&DAG
); errs() << "\n";
784 llvm_unreachable("Do not know how to expand the result of this operator!");
786 case ISD::MERGE_VALUES
: SplitRes_MERGE_VALUES(N
, Lo
, Hi
); break;
787 case ISD::UNDEF
: SplitRes_UNDEF(N
, Lo
, Hi
); break;
788 case ISD::SELECT
: SplitRes_SELECT(N
, Lo
, Hi
); break;
789 case ISD::SELECT_CC
: SplitRes_SELECT_CC(N
, Lo
, Hi
); break;
791 case ISD::BIT_CONVERT
: ExpandRes_BIT_CONVERT(N
, Lo
, Hi
); break;
792 case ISD::BUILD_PAIR
: ExpandRes_BUILD_PAIR(N
, Lo
, Hi
); break;
793 case ISD::EXTRACT_ELEMENT
: ExpandRes_EXTRACT_ELEMENT(N
, Lo
, Hi
); break;
794 case ISD::EXTRACT_VECTOR_ELT
: ExpandRes_EXTRACT_VECTOR_ELT(N
, Lo
, Hi
); break;
795 case ISD::VAARG
: ExpandRes_VAARG(N
, Lo
, Hi
); break;
797 case ISD::ConstantFP
: ExpandFloatRes_ConstantFP(N
, Lo
, Hi
); break;
798 case ISD::FABS
: ExpandFloatRes_FABS(N
, Lo
, Hi
); break;
799 case ISD::FADD
: ExpandFloatRes_FADD(N
, Lo
, Hi
); break;
800 case ISD::FCEIL
: ExpandFloatRes_FCEIL(N
, Lo
, Hi
); break;
801 case ISD::FCOS
: ExpandFloatRes_FCOS(N
, Lo
, Hi
); break;
802 case ISD::FDIV
: ExpandFloatRes_FDIV(N
, Lo
, Hi
); break;
803 case ISD::FEXP
: ExpandFloatRes_FEXP(N
, Lo
, Hi
); break;
804 case ISD::FEXP2
: ExpandFloatRes_FEXP2(N
, Lo
, Hi
); break;
805 case ISD::FFLOOR
: ExpandFloatRes_FFLOOR(N
, Lo
, Hi
); break;
806 case ISD::FLOG
: ExpandFloatRes_FLOG(N
, Lo
, Hi
); break;
807 case ISD::FLOG2
: ExpandFloatRes_FLOG2(N
, Lo
, Hi
); break;
808 case ISD::FLOG10
: ExpandFloatRes_FLOG10(N
, Lo
, Hi
); break;
809 case ISD::FMUL
: ExpandFloatRes_FMUL(N
, Lo
, Hi
); break;
810 case ISD::FNEARBYINT
: ExpandFloatRes_FNEARBYINT(N
, Lo
, Hi
); break;
811 case ISD::FNEG
: ExpandFloatRes_FNEG(N
, Lo
, Hi
); break;
812 case ISD::FP_EXTEND
: ExpandFloatRes_FP_EXTEND(N
, Lo
, Hi
); break;
813 case ISD::FPOW
: ExpandFloatRes_FPOW(N
, Lo
, Hi
); break;
814 case ISD::FPOWI
: ExpandFloatRes_FPOWI(N
, Lo
, Hi
); break;
815 case ISD::FRINT
: ExpandFloatRes_FRINT(N
, Lo
, Hi
); break;
816 case ISD::FSIN
: ExpandFloatRes_FSIN(N
, Lo
, Hi
); break;
817 case ISD::FSQRT
: ExpandFloatRes_FSQRT(N
, Lo
, Hi
); break;
818 case ISD::FSUB
: ExpandFloatRes_FSUB(N
, Lo
, Hi
); break;
819 case ISD::FTRUNC
: ExpandFloatRes_FTRUNC(N
, Lo
, Hi
); break;
820 case ISD::LOAD
: ExpandFloatRes_LOAD(N
, Lo
, Hi
); break;
821 case ISD::SINT_TO_FP
:
822 case ISD::UINT_TO_FP
: ExpandFloatRes_XINT_TO_FP(N
, Lo
, Hi
); break;
825 // If Lo/Hi is null, the sub-method took care of registering results etc.
827 SetExpandedFloat(SDValue(N
, ResNo
), Lo
, Hi
);
830 void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode
*N
, SDValue
&Lo
,
832 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
833 assert(NVT
.getSizeInBits() == integerPartWidth
&&
834 "Do not know how to expand this float constant!");
835 APInt C
= cast
<ConstantFPSDNode
>(N
)->getValueAPF().bitcastToAPInt();
836 Lo
= DAG
.getConstantFP(APFloat(APInt(integerPartWidth
, 1,
837 &C
.getRawData()[1])), NVT
);
838 Hi
= DAG
.getConstantFP(APFloat(APInt(integerPartWidth
, 1,
839 &C
.getRawData()[0])), NVT
);
842 void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode
*N
, SDValue
&Lo
,
844 assert(N
->getValueType(0) == MVT::ppcf128
&&
845 "Logic only correct for ppcf128!");
846 DebugLoc dl
= N
->getDebugLoc();
848 GetExpandedFloat(N
->getOperand(0), Lo
, Tmp
);
849 Hi
= DAG
.getNode(ISD::FABS
, dl
, Tmp
.getValueType(), Tmp
);
850 // Lo = Hi==fabs(Hi) ? Lo : -Lo;
851 Lo
= DAG
.getNode(ISD::SELECT_CC
, dl
, Lo
.getValueType(), Tmp
, Hi
, Lo
,
852 DAG
.getNode(ISD::FNEG
, dl
, Lo
.getValueType(), Lo
),
853 DAG
.getCondCode(ISD::SETEQ
));
856 void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode
*N
, SDValue
&Lo
,
858 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
859 RTLIB::ADD_F32
, RTLIB::ADD_F64
,
860 RTLIB::ADD_F80
, RTLIB::ADD_PPCF128
),
862 GetPairElements(Call
, Lo
, Hi
);
865 void DAGTypeLegalizer::ExpandFloatRes_FCEIL(SDNode
*N
,
866 SDValue
&Lo
, SDValue
&Hi
) {
867 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
868 RTLIB::CEIL_F32
, RTLIB::CEIL_F64
,
869 RTLIB::CEIL_F80
, RTLIB::CEIL_PPCF128
),
871 GetPairElements(Call
, Lo
, Hi
);
874 void DAGTypeLegalizer::ExpandFloatRes_FCOS(SDNode
*N
,
875 SDValue
&Lo
, SDValue
&Hi
) {
876 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
877 RTLIB::COS_F32
, RTLIB::COS_F64
,
878 RTLIB::COS_F80
, RTLIB::COS_PPCF128
),
880 GetPairElements(Call
, Lo
, Hi
);
883 void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode
*N
, SDValue
&Lo
,
885 SDValue Ops
[2] = { N
->getOperand(0), N
->getOperand(1) };
886 SDValue Call
= MakeLibCall(GetFPLibCall(N
->getValueType(0),
891 N
->getValueType(0), Ops
, 2, false,
893 GetPairElements(Call
, Lo
, Hi
);
896 void DAGTypeLegalizer::ExpandFloatRes_FEXP(SDNode
*N
,
897 SDValue
&Lo
, SDValue
&Hi
) {
898 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
899 RTLIB::EXP_F32
, RTLIB::EXP_F64
,
900 RTLIB::EXP_F80
, RTLIB::EXP_PPCF128
),
902 GetPairElements(Call
, Lo
, Hi
);
905 void DAGTypeLegalizer::ExpandFloatRes_FEXP2(SDNode
*N
,
906 SDValue
&Lo
, SDValue
&Hi
) {
907 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
908 RTLIB::EXP2_F32
, RTLIB::EXP2_F64
,
909 RTLIB::EXP2_F80
, RTLIB::EXP2_PPCF128
),
911 GetPairElements(Call
, Lo
, Hi
);
914 void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(SDNode
*N
,
915 SDValue
&Lo
, SDValue
&Hi
) {
916 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
917 RTLIB::FLOOR_F32
,RTLIB::FLOOR_F64
,
918 RTLIB::FLOOR_F80
,RTLIB::FLOOR_PPCF128
),
920 GetPairElements(Call
, Lo
, Hi
);
923 void DAGTypeLegalizer::ExpandFloatRes_FLOG(SDNode
*N
,
924 SDValue
&Lo
, SDValue
&Hi
) {
925 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
926 RTLIB::LOG_F32
, RTLIB::LOG_F64
,
927 RTLIB::LOG_F80
, RTLIB::LOG_PPCF128
),
929 GetPairElements(Call
, Lo
, Hi
);
932 void DAGTypeLegalizer::ExpandFloatRes_FLOG2(SDNode
*N
,
933 SDValue
&Lo
, SDValue
&Hi
) {
934 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
935 RTLIB::LOG2_F32
, RTLIB::LOG2_F64
,
936 RTLIB::LOG2_F80
, RTLIB::LOG2_PPCF128
),
938 GetPairElements(Call
, Lo
, Hi
);
941 void DAGTypeLegalizer::ExpandFloatRes_FLOG10(SDNode
*N
,
942 SDValue
&Lo
, SDValue
&Hi
) {
943 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
944 RTLIB::LOG10_F32
,RTLIB::LOG10_F64
,
945 RTLIB::LOG10_F80
,RTLIB::LOG10_PPCF128
),
947 GetPairElements(Call
, Lo
, Hi
);
950 void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode
*N
, SDValue
&Lo
,
952 SDValue Ops
[2] = { N
->getOperand(0), N
->getOperand(1) };
953 SDValue Call
= MakeLibCall(GetFPLibCall(N
->getValueType(0),
958 N
->getValueType(0), Ops
, 2, false,
960 GetPairElements(Call
, Lo
, Hi
);
963 void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode
*N
,
964 SDValue
&Lo
, SDValue
&Hi
) {
965 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
966 RTLIB::NEARBYINT_F32
,
967 RTLIB::NEARBYINT_F64
,
968 RTLIB::NEARBYINT_F80
,
969 RTLIB::NEARBYINT_PPCF128
),
971 GetPairElements(Call
, Lo
, Hi
);
974 void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode
*N
, SDValue
&Lo
,
976 DebugLoc dl
= N
->getDebugLoc();
977 GetExpandedFloat(N
->getOperand(0), Lo
, Hi
);
978 Lo
= DAG
.getNode(ISD::FNEG
, dl
, Lo
.getValueType(), Lo
);
979 Hi
= DAG
.getNode(ISD::FNEG
, dl
, Hi
.getValueType(), Hi
);
982 void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode
*N
, SDValue
&Lo
,
984 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
985 Hi
= DAG
.getNode(ISD::FP_EXTEND
, N
->getDebugLoc(), NVT
, N
->getOperand(0));
986 Lo
= DAG
.getConstantFP(APFloat(APInt(NVT
.getSizeInBits(), 0)), NVT
);
989 void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode
*N
,
990 SDValue
&Lo
, SDValue
&Hi
) {
991 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
992 RTLIB::POW_F32
, RTLIB::POW_F64
,
993 RTLIB::POW_F80
, RTLIB::POW_PPCF128
),
995 GetPairElements(Call
, Lo
, Hi
);
998 void DAGTypeLegalizer::ExpandFloatRes_FPOWI(SDNode
*N
,
999 SDValue
&Lo
, SDValue
&Hi
) {
1000 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
1001 RTLIB::POWI_F32
, RTLIB::POWI_F64
,
1002 RTLIB::POWI_F80
, RTLIB::POWI_PPCF128
),
1004 GetPairElements(Call
, Lo
, Hi
);
1007 void DAGTypeLegalizer::ExpandFloatRes_FRINT(SDNode
*N
,
1008 SDValue
&Lo
, SDValue
&Hi
) {
1009 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
1010 RTLIB::RINT_F32
, RTLIB::RINT_F64
,
1011 RTLIB::RINT_F80
, RTLIB::RINT_PPCF128
),
1013 GetPairElements(Call
, Lo
, Hi
);
1016 void DAGTypeLegalizer::ExpandFloatRes_FSIN(SDNode
*N
,
1017 SDValue
&Lo
, SDValue
&Hi
) {
1018 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
1019 RTLIB::SIN_F32
, RTLIB::SIN_F64
,
1020 RTLIB::SIN_F80
, RTLIB::SIN_PPCF128
),
1022 GetPairElements(Call
, Lo
, Hi
);
1025 void DAGTypeLegalizer::ExpandFloatRes_FSQRT(SDNode
*N
,
1026 SDValue
&Lo
, SDValue
&Hi
) {
1027 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
1028 RTLIB::SQRT_F32
, RTLIB::SQRT_F64
,
1029 RTLIB::SQRT_F80
, RTLIB::SQRT_PPCF128
),
1031 GetPairElements(Call
, Lo
, Hi
);
1034 void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode
*N
, SDValue
&Lo
,
1036 SDValue Ops
[2] = { N
->getOperand(0), N
->getOperand(1) };
1037 SDValue Call
= MakeLibCall(GetFPLibCall(N
->getValueType(0),
1041 RTLIB::SUB_PPCF128
),
1042 N
->getValueType(0), Ops
, 2, false,
1044 GetPairElements(Call
, Lo
, Hi
);
1047 void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(SDNode
*N
,
1048 SDValue
&Lo
, SDValue
&Hi
) {
1049 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
1050 RTLIB::TRUNC_F32
, RTLIB::TRUNC_F64
,
1051 RTLIB::TRUNC_F80
, RTLIB::TRUNC_PPCF128
),
1053 GetPairElements(Call
, Lo
, Hi
);
1056 void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode
*N
, SDValue
&Lo
,
1058 if (ISD::isNormalLoad(N
)) {
1059 ExpandRes_NormalLoad(N
, Lo
, Hi
);
1063 assert(ISD::isUNINDEXEDLoad(N
) && "Indexed load during type legalization!");
1064 LoadSDNode
*LD
= cast
<LoadSDNode
>(N
);
1065 SDValue Chain
= LD
->getChain();
1066 SDValue Ptr
= LD
->getBasePtr();
1067 DebugLoc dl
= N
->getDebugLoc();
1069 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), LD
->getValueType(0));
1070 assert(NVT
.isByteSized() && "Expanded type not byte sized!");
1071 assert(LD
->getMemoryVT().bitsLE(NVT
) && "Float type not round?");
1073 Hi
= DAG
.getExtLoad(LD
->getExtensionType(), dl
, NVT
, Chain
, Ptr
,
1074 LD
->getSrcValue(), LD
->getSrcValueOffset(),
1076 LD
->isVolatile(), LD
->getAlignment());
1078 // Remember the chain.
1079 Chain
= Hi
.getValue(1);
1081 // The low part is zero.
1082 Lo
= DAG
.getConstantFP(APFloat(APInt(NVT
.getSizeInBits(), 0)), NVT
);
1084 // Modified the chain - switch anything that used the old chain to use the
1086 ReplaceValueWith(SDValue(LD
, 1), Chain
);
1089 void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode
*N
, SDValue
&Lo
,
1091 assert(N
->getValueType(0) == MVT::ppcf128
&& "Unsupported XINT_TO_FP!");
1092 EVT VT
= N
->getValueType(0);
1093 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
1094 SDValue Src
= N
->getOperand(0);
1095 EVT SrcVT
= Src
.getValueType();
1096 bool isSigned
= N
->getOpcode() == ISD::SINT_TO_FP
;
1097 DebugLoc dl
= N
->getDebugLoc();
1099 // First do an SINT_TO_FP, whether the original was signed or unsigned.
1100 // When promoting partial word types to i32 we must honor the signedness,
1102 if (SrcVT
.bitsLE(MVT::i32
)) {
1103 // The integer can be represented exactly in an f64.
1104 Src
= DAG
.getNode(isSigned
? ISD::SIGN_EXTEND
: ISD::ZERO_EXTEND
, dl
,
1106 Lo
= DAG
.getConstantFP(APFloat(APInt(NVT
.getSizeInBits(), 0)), NVT
);
1107 Hi
= DAG
.getNode(ISD::SINT_TO_FP
, dl
, NVT
, Src
);
1109 RTLIB::Libcall LC
= RTLIB::UNKNOWN_LIBCALL
;
1110 if (SrcVT
.bitsLE(MVT::i64
)) {
1111 Src
= DAG
.getNode(isSigned
? ISD::SIGN_EXTEND
: ISD::ZERO_EXTEND
, dl
,
1113 LC
= RTLIB::SINTTOFP_I64_PPCF128
;
1114 } else if (SrcVT
.bitsLE(MVT::i128
)) {
1115 Src
= DAG
.getNode(ISD::SIGN_EXTEND
, dl
, MVT::i128
, Src
);
1116 LC
= RTLIB::SINTTOFP_I128_PPCF128
;
1118 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported XINT_TO_FP!");
1120 Hi
= MakeLibCall(LC
, VT
, &Src
, 1, true, dl
);
1121 GetPairElements(Hi
, Lo
, Hi
);
1127 // Unsigned - fix up the SINT_TO_FP value just calculated.
1128 Hi
= DAG
.getNode(ISD::BUILD_PAIR
, dl
, VT
, Lo
, Hi
);
1129 SrcVT
= Src
.getValueType();
1131 // x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128.
1132 static const uint64_t TwoE32
[] = { 0x41f0000000000000LL
, 0 };
1133 static const uint64_t TwoE64
[] = { 0x43f0000000000000LL
, 0 };
1134 static const uint64_t TwoE128
[] = { 0x47f0000000000000LL
, 0 };
1135 const uint64_t *Parts
= 0;
1137 switch (SrcVT
.getSimpleVT().SimpleTy
) {
1139 assert(false && "Unsupported UINT_TO_FP!");
1151 Lo
= DAG
.getNode(ISD::FADD
, dl
, VT
, Hi
,
1152 DAG
.getConstantFP(APFloat(APInt(128, 2, Parts
)),
1154 Lo
= DAG
.getNode(ISD::SELECT_CC
, dl
, VT
, Src
, DAG
.getConstant(0, SrcVT
),
1155 Lo
, Hi
, DAG
.getCondCode(ISD::SETLT
));
1156 GetPairElements(Lo
, Lo
, Hi
);
1160 //===----------------------------------------------------------------------===//
1161 // Float Operand Expansion
1162 //===----------------------------------------------------------------------===//
1164 /// ExpandFloatOperand - This method is called when the specified operand of the
1165 /// specified node is found to need expansion. At this point, all of the result
1166 /// types of the node are known to be legal, but other operands of the node may
1167 /// need promotion or expansion as well as the specified one.
1168 bool DAGTypeLegalizer::ExpandFloatOperand(SDNode
*N
, unsigned OpNo
) {
1169 DEBUG(errs() << "Expand float operand: "; N
->dump(&DAG
); errs() << "\n");
1170 SDValue Res
= SDValue();
1172 if (TLI
.getOperationAction(N
->getOpcode(), N
->getOperand(OpNo
).getValueType())
1173 == TargetLowering::Custom
)
1174 Res
= TLI
.LowerOperation(SDValue(N
, 0), DAG
);
1176 if (Res
.getNode() == 0) {
1177 switch (N
->getOpcode()) {
1180 errs() << "ExpandFloatOperand Op #" << OpNo
<< ": ";
1181 N
->dump(&DAG
); errs() << "\n";
1183 llvm_unreachable("Do not know how to expand this operator's operand!");
1185 case ISD::BIT_CONVERT
: Res
= ExpandOp_BIT_CONVERT(N
); break;
1186 case ISD::BUILD_VECTOR
: Res
= ExpandOp_BUILD_VECTOR(N
); break;
1187 case ISD::EXTRACT_ELEMENT
: Res
= ExpandOp_EXTRACT_ELEMENT(N
); break;
1189 case ISD::BR_CC
: Res
= ExpandFloatOp_BR_CC(N
); break;
1190 case ISD::FP_ROUND
: Res
= ExpandFloatOp_FP_ROUND(N
); break;
1191 case ISD::FP_TO_SINT
: Res
= ExpandFloatOp_FP_TO_SINT(N
); break;
1192 case ISD::FP_TO_UINT
: Res
= ExpandFloatOp_FP_TO_UINT(N
); break;
1193 case ISD::SELECT_CC
: Res
= ExpandFloatOp_SELECT_CC(N
); break;
1194 case ISD::SETCC
: Res
= ExpandFloatOp_SETCC(N
); break;
1195 case ISD::STORE
: Res
= ExpandFloatOp_STORE(cast
<StoreSDNode
>(N
),
1200 // If the result is null, the sub-method took care of registering results etc.
1201 if (!Res
.getNode()) return false;
1203 // If the result is N, the sub-method updated N in place. Tell the legalizer
1205 if (Res
.getNode() == N
)
1208 assert(Res
.getValueType() == N
->getValueType(0) && N
->getNumValues() == 1 &&
1209 "Invalid operand expansion");
1211 ReplaceValueWith(SDValue(N
, 0), Res
);
1215 /// FloatExpandSetCCOperands - Expand the operands of a comparison. This code
1216 /// is shared among BR_CC, SELECT_CC, and SETCC handlers.
1217 void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue
&NewLHS
,
1219 ISD::CondCode
&CCCode
,
1221 SDValue LHSLo
, LHSHi
, RHSLo
, RHSHi
;
1222 GetExpandedFloat(NewLHS
, LHSLo
, LHSHi
);
1223 GetExpandedFloat(NewRHS
, RHSLo
, RHSHi
);
1225 EVT VT
= NewLHS
.getValueType();
1226 assert(VT
== MVT::ppcf128
&& "Unsupported setcc type!");
1228 // FIXME: This generated code sucks. We want to generate
1229 // FCMPU crN, hi1, hi2
1231 // FCMPU crN, lo1, lo2
1232 // The following can be improved, but not that much.
1233 SDValue Tmp1
, Tmp2
, Tmp3
;
1234 Tmp1
= DAG
.getSetCC(dl
, TLI
.getSetCCResultType(LHSHi
.getValueType()),
1235 LHSHi
, RHSHi
, ISD::SETOEQ
);
1236 Tmp2
= DAG
.getSetCC(dl
, TLI
.getSetCCResultType(LHSLo
.getValueType()),
1237 LHSLo
, RHSLo
, CCCode
);
1238 Tmp3
= DAG
.getNode(ISD::AND
, dl
, Tmp1
.getValueType(), Tmp1
, Tmp2
);
1239 Tmp1
= DAG
.getSetCC(dl
, TLI
.getSetCCResultType(LHSHi
.getValueType()),
1240 LHSHi
, RHSHi
, ISD::SETUNE
);
1241 Tmp2
= DAG
.getSetCC(dl
, TLI
.getSetCCResultType(LHSHi
.getValueType()),
1242 LHSHi
, RHSHi
, CCCode
);
1243 Tmp1
= DAG
.getNode(ISD::AND
, dl
, Tmp1
.getValueType(), Tmp1
, Tmp2
);
1244 NewLHS
= DAG
.getNode(ISD::OR
, dl
, Tmp1
.getValueType(), Tmp1
, Tmp3
);
1245 NewRHS
= SDValue(); // LHS is the result, not a compare.
1248 SDValue
DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode
*N
) {
1249 SDValue NewLHS
= N
->getOperand(2), NewRHS
= N
->getOperand(3);
1250 ISD::CondCode CCCode
= cast
<CondCodeSDNode
>(N
->getOperand(1))->get();
1251 FloatExpandSetCCOperands(NewLHS
, NewRHS
, CCCode
, N
->getDebugLoc());
1253 // If ExpandSetCCOperands returned a scalar, we need to compare the result
1254 // against zero to select between true and false values.
1255 if (NewRHS
.getNode() == 0) {
1256 NewRHS
= DAG
.getConstant(0, NewLHS
.getValueType());
1257 CCCode
= ISD::SETNE
;
1260 // Update N to have the operands specified.
1261 return DAG
.UpdateNodeOperands(SDValue(N
, 0), N
->getOperand(0),
1262 DAG
.getCondCode(CCCode
), NewLHS
, NewRHS
,
1266 SDValue
DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode
*N
) {
1267 assert(N
->getOperand(0).getValueType() == MVT::ppcf128
&&
1268 "Logic only correct for ppcf128!");
1270 GetExpandedFloat(N
->getOperand(0), Lo
, Hi
);
1271 // Round it the rest of the way (e.g. to f32) if needed.
1272 return DAG
.getNode(ISD::FP_ROUND
, N
->getDebugLoc(),
1273 N
->getValueType(0), Hi
, N
->getOperand(1));
1276 SDValue
DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode
*N
) {
1277 EVT RVT
= N
->getValueType(0);
1278 DebugLoc dl
= N
->getDebugLoc();
1280 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
1281 // PPC (the libcall is not available). FIXME: Do this in a less hacky way.
1282 if (RVT
== MVT::i32
) {
1283 assert(N
->getOperand(0).getValueType() == MVT::ppcf128
&&
1284 "Logic only correct for ppcf128!");
1285 SDValue Res
= DAG
.getNode(ISD::FP_ROUND_INREG
, dl
, MVT::ppcf128
,
1286 N
->getOperand(0), DAG
.getValueType(MVT::f64
));
1287 Res
= DAG
.getNode(ISD::FP_ROUND
, dl
, MVT::f64
, Res
,
1288 DAG
.getIntPtrConstant(1));
1289 return DAG
.getNode(ISD::FP_TO_SINT
, dl
, MVT::i32
, Res
);
1292 RTLIB::Libcall LC
= RTLIB::getFPTOSINT(N
->getOperand(0).getValueType(), RVT
);
1293 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported FP_TO_SINT!");
1294 return MakeLibCall(LC
, RVT
, &N
->getOperand(0), 1, false, dl
);
1297 SDValue
DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode
*N
) {
1298 EVT RVT
= N
->getValueType(0);
1299 DebugLoc dl
= N
->getDebugLoc();
1301 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
1302 // PPC (the libcall is not available). FIXME: Do this in a less hacky way.
1303 if (RVT
== MVT::i32
) {
1304 assert(N
->getOperand(0).getValueType() == MVT::ppcf128
&&
1305 "Logic only correct for ppcf128!");
1306 const uint64_t TwoE31
[] = {0x41e0000000000000LL
, 0};
1307 APFloat APF
= APFloat(APInt(128, 2, TwoE31
));
1308 SDValue Tmp
= DAG
.getConstantFP(APF
, MVT::ppcf128
);
1309 // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
1310 // FIXME: generated code sucks.
1311 return DAG
.getNode(ISD::SELECT_CC
, dl
, MVT::i32
, N
->getOperand(0), Tmp
,
1312 DAG
.getNode(ISD::ADD
, dl
, MVT::i32
,
1313 DAG
.getNode(ISD::FP_TO_SINT
, dl
, MVT::i32
,
1314 DAG
.getNode(ISD::FSUB
, dl
,
1318 DAG
.getConstant(0x80000000, MVT::i32
)),
1319 DAG
.getNode(ISD::FP_TO_SINT
, dl
,
1320 MVT::i32
, N
->getOperand(0)),
1321 DAG
.getCondCode(ISD::SETGE
));
1324 RTLIB::Libcall LC
= RTLIB::getFPTOUINT(N
->getOperand(0).getValueType(), RVT
);
1325 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported FP_TO_UINT!");
1326 return MakeLibCall(LC
, N
->getValueType(0), &N
->getOperand(0), 1, false, dl
);
1329 SDValue
DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode
*N
) {
1330 SDValue NewLHS
= N
->getOperand(0), NewRHS
= N
->getOperand(1);
1331 ISD::CondCode CCCode
= cast
<CondCodeSDNode
>(N
->getOperand(4))->get();
1332 FloatExpandSetCCOperands(NewLHS
, NewRHS
, CCCode
, N
->getDebugLoc());
1334 // If ExpandSetCCOperands returned a scalar, we need to compare the result
1335 // against zero to select between true and false values.
1336 if (NewRHS
.getNode() == 0) {
1337 NewRHS
= DAG
.getConstant(0, NewLHS
.getValueType());
1338 CCCode
= ISD::SETNE
;
1341 // Update N to have the operands specified.
1342 return DAG
.UpdateNodeOperands(SDValue(N
, 0), NewLHS
, NewRHS
,
1343 N
->getOperand(2), N
->getOperand(3),
1344 DAG
.getCondCode(CCCode
));
1347 SDValue
DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode
*N
) {
1348 SDValue NewLHS
= N
->getOperand(0), NewRHS
= N
->getOperand(1);
1349 ISD::CondCode CCCode
= cast
<CondCodeSDNode
>(N
->getOperand(2))->get();
1350 FloatExpandSetCCOperands(NewLHS
, NewRHS
, CCCode
, N
->getDebugLoc());
1352 // If ExpandSetCCOperands returned a scalar, use it.
1353 if (NewRHS
.getNode() == 0) {
1354 assert(NewLHS
.getValueType() == N
->getValueType(0) &&
1355 "Unexpected setcc expansion!");
1359 // Otherwise, update N to have the operands specified.
1360 return DAG
.UpdateNodeOperands(SDValue(N
, 0), NewLHS
, NewRHS
,
1361 DAG
.getCondCode(CCCode
));
1364 SDValue
DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode
*N
, unsigned OpNo
) {
1365 if (ISD::isNormalStore(N
))
1366 return ExpandOp_NormalStore(N
, OpNo
);
1368 assert(ISD::isUNINDEXEDStore(N
) && "Indexed store during type legalization!");
1369 assert(OpNo
== 1 && "Can only expand the stored value so far");
1370 StoreSDNode
*ST
= cast
<StoreSDNode
>(N
);
1372 SDValue Chain
= ST
->getChain();
1373 SDValue Ptr
= ST
->getBasePtr();
1375 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), ST
->getValue().getValueType());
1376 assert(NVT
.isByteSized() && "Expanded type not byte sized!");
1377 assert(ST
->getMemoryVT().bitsLE(NVT
) && "Float type not round?");
1380 GetExpandedOp(ST
->getValue(), Lo
, Hi
);
1382 return DAG
.getTruncStore(Chain
, N
->getDebugLoc(), Hi
, Ptr
,
1383 ST
->getSrcValue(), ST
->getSrcValueOffset(),
1385 ST
->isVolatile(), ST
->getAlignment());