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(dbgs() << "Soften float result " << ResNo
<< ": "; N
->dump(&DAG
);
48 SDValue R
= SDValue();
50 switch (N
->getOpcode()) {
53 dbgs() << "SoftenFloatResult #" << ResNo
<< ": ";
54 N
->dump(&DAG
); dbgs() << "\n";
56 llvm_unreachable("Do not know how to soften the result of this operator!");
58 case ISD::BITCAST
: R
= SoftenFloatRes_BITCAST(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::FMA
: R
= SoftenFloatRes_FMA(N
); break;
78 case ISD::FMUL
: R
= SoftenFloatRes_FMUL(N
); break;
79 case ISD::FNEARBYINT
: R
= SoftenFloatRes_FNEARBYINT(N
); break;
80 case ISD::FNEG
: R
= SoftenFloatRes_FNEG(N
); break;
81 case ISD::FP_EXTEND
: R
= SoftenFloatRes_FP_EXTEND(N
); break;
82 case ISD::FP_ROUND
: R
= SoftenFloatRes_FP_ROUND(N
); break;
83 case ISD::FP16_TO_FP32
:R
= SoftenFloatRes_FP16_TO_FP32(N
); break;
84 case ISD::FPOW
: R
= SoftenFloatRes_FPOW(N
); break;
85 case ISD::FPOWI
: R
= SoftenFloatRes_FPOWI(N
); break;
86 case ISD::FREM
: R
= SoftenFloatRes_FREM(N
); break;
87 case ISD::FRINT
: R
= SoftenFloatRes_FRINT(N
); break;
88 case ISD::FSIN
: R
= SoftenFloatRes_FSIN(N
); break;
89 case ISD::FSQRT
: R
= SoftenFloatRes_FSQRT(N
); break;
90 case ISD::FSUB
: R
= SoftenFloatRes_FSUB(N
); break;
91 case ISD::FTRUNC
: R
= SoftenFloatRes_FTRUNC(N
); break;
92 case ISD::LOAD
: R
= SoftenFloatRes_LOAD(N
); break;
93 case ISD::SELECT
: R
= SoftenFloatRes_SELECT(N
); break;
94 case ISD::SELECT_CC
: R
= SoftenFloatRes_SELECT_CC(N
); break;
96 case ISD::UINT_TO_FP
: R
= SoftenFloatRes_XINT_TO_FP(N
); break;
97 case ISD::UNDEF
: R
= SoftenFloatRes_UNDEF(N
); break;
98 case ISD::VAARG
: R
= SoftenFloatRes_VAARG(N
); break;
101 // If R is null, the sub-method took care of registering the result.
103 SetSoftenedFloat(SDValue(N
, ResNo
), R
);
106 SDValue
DAGTypeLegalizer::SoftenFloatRes_BITCAST(SDNode
*N
) {
107 return BitConvertToInteger(N
->getOperand(0));
110 SDValue
DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode
*N
) {
111 // Convert the inputs to integers, and build a new pair out of them.
112 return DAG
.getNode(ISD::BUILD_PAIR
, N
->getDebugLoc(),
113 TLI
.getTypeToTransformTo(*DAG
.getContext(),
115 BitConvertToInteger(N
->getOperand(0)),
116 BitConvertToInteger(N
->getOperand(1)));
119 SDValue
DAGTypeLegalizer::SoftenFloatRes_ConstantFP(ConstantFPSDNode
*N
) {
120 return DAG
.getConstant(N
->getValueAPF().bitcastToAPInt(),
121 TLI
.getTypeToTransformTo(*DAG
.getContext(),
122 N
->getValueType(0)));
125 SDValue
DAGTypeLegalizer::SoftenFloatRes_EXTRACT_VECTOR_ELT(SDNode
*N
) {
126 SDValue NewOp
= BitConvertVectorToIntegerVector(N
->getOperand(0));
127 return DAG
.getNode(ISD::EXTRACT_VECTOR_ELT
, N
->getDebugLoc(),
128 NewOp
.getValueType().getVectorElementType(),
129 NewOp
, N
->getOperand(1));
132 SDValue
DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode
*N
) {
133 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
134 unsigned Size
= NVT
.getSizeInBits();
136 // Mask = ~(1 << (Size-1))
137 APInt API
= APInt::getAllOnesValue(Size
);
138 API
.clearBit(Size
-1);
139 SDValue Mask
= DAG
.getConstant(API
, NVT
);
140 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
141 return DAG
.getNode(ISD::AND
, N
->getDebugLoc(), NVT
, Op
, Mask
);
144 SDValue
DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode
*N
) {
145 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
146 SDValue Ops
[2] = { GetSoftenedFloat(N
->getOperand(0)),
147 GetSoftenedFloat(N
->getOperand(1)) };
148 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
153 NVT
, Ops
, 2, false, N
->getDebugLoc());
156 SDValue
DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode
*N
) {
157 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
158 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
159 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
163 RTLIB::CEIL_PPCF128
),
164 NVT
, &Op
, 1, false, N
->getDebugLoc());
167 SDValue
DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode
*N
) {
168 SDValue LHS
= GetSoftenedFloat(N
->getOperand(0));
169 SDValue RHS
= BitConvertToInteger(N
->getOperand(1));
170 DebugLoc dl
= N
->getDebugLoc();
172 EVT LVT
= LHS
.getValueType();
173 EVT RVT
= RHS
.getValueType();
175 unsigned LSize
= LVT
.getSizeInBits();
176 unsigned RSize
= RVT
.getSizeInBits();
178 // First get the sign bit of second operand.
179 SDValue SignBit
= DAG
.getNode(ISD::SHL
, dl
, RVT
, DAG
.getConstant(1, RVT
),
180 DAG
.getConstant(RSize
- 1,
181 TLI
.getShiftAmountTy(RVT
)));
182 SignBit
= DAG
.getNode(ISD::AND
, dl
, RVT
, RHS
, SignBit
);
184 // Shift right or sign-extend it if the two operands have different types.
185 int SizeDiff
= RVT
.getSizeInBits() - LVT
.getSizeInBits();
187 SignBit
= DAG
.getNode(ISD::SRL
, dl
, RVT
, SignBit
,
188 DAG
.getConstant(SizeDiff
,
189 TLI
.getShiftAmountTy(SignBit
.getValueType())));
190 SignBit
= DAG
.getNode(ISD::TRUNCATE
, dl
, LVT
, SignBit
);
191 } else if (SizeDiff
< 0) {
192 SignBit
= DAG
.getNode(ISD::ANY_EXTEND
, dl
, LVT
, SignBit
);
193 SignBit
= DAG
.getNode(ISD::SHL
, dl
, LVT
, SignBit
,
194 DAG
.getConstant(-SizeDiff
,
195 TLI
.getShiftAmountTy(SignBit
.getValueType())));
198 // Clear the sign bit of the first operand.
199 SDValue Mask
= DAG
.getNode(ISD::SHL
, dl
, LVT
, DAG
.getConstant(1, LVT
),
200 DAG
.getConstant(LSize
- 1,
201 TLI
.getShiftAmountTy(LVT
)));
202 Mask
= DAG
.getNode(ISD::SUB
, dl
, LVT
, Mask
, DAG
.getConstant(1, LVT
));
203 LHS
= DAG
.getNode(ISD::AND
, dl
, LVT
, LHS
, Mask
);
205 // Or the value with the sign bit.
206 return DAG
.getNode(ISD::OR
, dl
, LVT
, LHS
, SignBit
);
209 SDValue
DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode
*N
) {
210 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
211 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
212 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
217 NVT
, &Op
, 1, false, N
->getDebugLoc());
220 SDValue
DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode
*N
) {
221 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
222 SDValue Ops
[2] = { GetSoftenedFloat(N
->getOperand(0)),
223 GetSoftenedFloat(N
->getOperand(1)) };
224 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
229 NVT
, Ops
, 2, false, N
->getDebugLoc());
232 SDValue
DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode
*N
) {
233 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
234 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
235 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
240 NVT
, &Op
, 1, false, N
->getDebugLoc());
243 SDValue
DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode
*N
) {
244 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
245 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
246 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
250 RTLIB::EXP2_PPCF128
),
251 NVT
, &Op
, 1, false, N
->getDebugLoc());
254 SDValue
DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode
*N
) {
255 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
256 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
257 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
261 RTLIB::FLOOR_PPCF128
),
262 NVT
, &Op
, 1, false, N
->getDebugLoc());
265 SDValue
DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode
*N
) {
266 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
267 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
268 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
273 NVT
, &Op
, 1, false, N
->getDebugLoc());
276 SDValue
DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode
*N
) {
277 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
278 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
279 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
283 RTLIB::LOG2_PPCF128
),
284 NVT
, &Op
, 1, false, N
->getDebugLoc());
287 SDValue
DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode
*N
) {
288 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
289 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
290 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
294 RTLIB::LOG10_PPCF128
),
295 NVT
, &Op
, 1, false, N
->getDebugLoc());
298 SDValue
DAGTypeLegalizer::SoftenFloatRes_FMA(SDNode
*N
) {
299 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
300 SDValue Ops
[3] = { GetSoftenedFloat(N
->getOperand(0)),
301 GetSoftenedFloat(N
->getOperand(1)),
302 GetSoftenedFloat(N
->getOperand(2)) };
303 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
308 NVT
, Ops
, 3, false, N
->getDebugLoc());
311 SDValue
DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode
*N
) {
312 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
313 SDValue Ops
[2] = { GetSoftenedFloat(N
->getOperand(0)),
314 GetSoftenedFloat(N
->getOperand(1)) };
315 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
320 NVT
, Ops
, 2, false, N
->getDebugLoc());
323 SDValue
DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode
*N
) {
324 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
325 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
326 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
327 RTLIB::NEARBYINT_F32
,
328 RTLIB::NEARBYINT_F64
,
329 RTLIB::NEARBYINT_F80
,
330 RTLIB::NEARBYINT_PPCF128
),
331 NVT
, &Op
, 1, false, N
->getDebugLoc());
334 SDValue
DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode
*N
) {
335 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
336 // Expand Y = FNEG(X) -> Y = SUB -0.0, X
337 SDValue Ops
[2] = { DAG
.getConstantFP(-0.0, N
->getValueType(0)),
338 GetSoftenedFloat(N
->getOperand(0)) };
339 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
344 NVT
, Ops
, 2, false, N
->getDebugLoc());
347 SDValue
DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode
*N
) {
348 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
349 SDValue Op
= N
->getOperand(0);
350 RTLIB::Libcall LC
= RTLIB::getFPEXT(Op
.getValueType(), N
->getValueType(0));
351 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported FP_EXTEND!");
352 return MakeLibCall(LC
, NVT
, &Op
, 1, false, N
->getDebugLoc());
355 // FIXME: Should we just use 'normal' FP_EXTEND / FP_TRUNC instead of special
357 SDValue
DAGTypeLegalizer::SoftenFloatRes_FP16_TO_FP32(SDNode
*N
) {
358 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
359 SDValue Op
= N
->getOperand(0);
360 return MakeLibCall(RTLIB::FPEXT_F16_F32
, NVT
, &Op
, 1, false,
364 SDValue
DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode
*N
) {
365 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
366 SDValue Op
= N
->getOperand(0);
367 RTLIB::Libcall LC
= RTLIB::getFPROUND(Op
.getValueType(), N
->getValueType(0));
368 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported FP_ROUND!");
369 return MakeLibCall(LC
, NVT
, &Op
, 1, false, N
->getDebugLoc());
372 SDValue
DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode
*N
) {
373 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
374 SDValue Ops
[2] = { GetSoftenedFloat(N
->getOperand(0)),
375 GetSoftenedFloat(N
->getOperand(1)) };
376 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
381 NVT
, Ops
, 2, false, N
->getDebugLoc());
384 SDValue
DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode
*N
) {
385 assert(N
->getOperand(1).getValueType() == MVT::i32
&&
386 "Unsupported power type!");
387 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
388 SDValue Ops
[2] = { GetSoftenedFloat(N
->getOperand(0)), N
->getOperand(1) };
389 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
393 RTLIB::POWI_PPCF128
),
394 NVT
, Ops
, 2, false, N
->getDebugLoc());
397 SDValue
DAGTypeLegalizer::SoftenFloatRes_FREM(SDNode
*N
) {
398 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
399 SDValue Ops
[2] = { GetSoftenedFloat(N
->getOperand(0)),
400 GetSoftenedFloat(N
->getOperand(1)) };
401 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
406 NVT
, Ops
, 2, false, N
->getDebugLoc());
409 SDValue
DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode
*N
) {
410 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
411 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
412 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
416 RTLIB::RINT_PPCF128
),
417 NVT
, &Op
, 1, false, N
->getDebugLoc());
420 SDValue
DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode
*N
) {
421 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
422 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
423 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
428 NVT
, &Op
, 1, false, N
->getDebugLoc());
431 SDValue
DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode
*N
) {
432 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
433 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
434 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
438 RTLIB::SQRT_PPCF128
),
439 NVT
, &Op
, 1, false, N
->getDebugLoc());
442 SDValue
DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode
*N
) {
443 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
444 SDValue Ops
[2] = { GetSoftenedFloat(N
->getOperand(0)),
445 GetSoftenedFloat(N
->getOperand(1)) };
446 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
451 NVT
, Ops
, 2, false, N
->getDebugLoc());
454 SDValue
DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode
*N
) {
455 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
456 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
457 return MakeLibCall(GetFPLibCall(N
->getValueType(0),
461 RTLIB::TRUNC_PPCF128
),
462 NVT
, &Op
, 1, false, N
->getDebugLoc());
465 SDValue
DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode
*N
) {
466 LoadSDNode
*L
= cast
<LoadSDNode
>(N
);
467 EVT VT
= N
->getValueType(0);
468 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
469 DebugLoc dl
= N
->getDebugLoc();
472 if (L
->getExtensionType() == ISD::NON_EXTLOAD
) {
473 NewL
= DAG
.getLoad(L
->getAddressingMode(), L
->getExtensionType(),
474 NVT
, dl
, L
->getChain(), L
->getBasePtr(), L
->getOffset(),
475 L
->getPointerInfo(), NVT
,
476 L
->isVolatile(), L
->isNonTemporal(), L
->getAlignment());
477 // Legalized the chain result - switch anything that used the old chain to
479 ReplaceValueWith(SDValue(N
, 1), NewL
.getValue(1));
483 // Do a non-extending load followed by FP_EXTEND.
484 NewL
= DAG
.getLoad(L
->getAddressingMode(), ISD::NON_EXTLOAD
,
485 L
->getMemoryVT(), dl
, L
->getChain(),
486 L
->getBasePtr(), L
->getOffset(), L
->getPointerInfo(),
487 L
->getMemoryVT(), L
->isVolatile(),
488 L
->isNonTemporal(), L
->getAlignment());
489 // Legalized the chain result - switch anything that used the old chain to
491 ReplaceValueWith(SDValue(N
, 1), NewL
.getValue(1));
492 return BitConvertToInteger(DAG
.getNode(ISD::FP_EXTEND
, dl
, VT
, NewL
));
495 SDValue
DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode
*N
) {
496 SDValue LHS
= GetSoftenedFloat(N
->getOperand(1));
497 SDValue RHS
= GetSoftenedFloat(N
->getOperand(2));
498 return DAG
.getNode(ISD::SELECT
, N
->getDebugLoc(),
499 LHS
.getValueType(), N
->getOperand(0),LHS
,RHS
);
502 SDValue
DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode
*N
) {
503 SDValue LHS
= GetSoftenedFloat(N
->getOperand(2));
504 SDValue RHS
= GetSoftenedFloat(N
->getOperand(3));
505 return DAG
.getNode(ISD::SELECT_CC
, N
->getDebugLoc(),
506 LHS
.getValueType(), N
->getOperand(0),
507 N
->getOperand(1), LHS
, RHS
, N
->getOperand(4));
510 SDValue
DAGTypeLegalizer::SoftenFloatRes_UNDEF(SDNode
*N
) {
511 return DAG
.getUNDEF(TLI
.getTypeToTransformTo(*DAG
.getContext(),
512 N
->getValueType(0)));
515 SDValue
DAGTypeLegalizer::SoftenFloatRes_VAARG(SDNode
*N
) {
516 SDValue Chain
= N
->getOperand(0); // Get the chain.
517 SDValue Ptr
= N
->getOperand(1); // Get the pointer.
518 EVT VT
= N
->getValueType(0);
519 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
520 DebugLoc dl
= N
->getDebugLoc();
523 NewVAARG
= DAG
.getVAArg(NVT
, dl
, Chain
, Ptr
, N
->getOperand(2),
524 N
->getConstantOperandVal(3));
526 // Legalized the chain result - switch anything that used the old chain to
528 ReplaceValueWith(SDValue(N
, 1), NewVAARG
.getValue(1));
532 SDValue
DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode
*N
) {
533 bool Signed
= N
->getOpcode() == ISD::SINT_TO_FP
;
534 EVT SVT
= N
->getOperand(0).getValueType();
535 EVT RVT
= N
->getValueType(0);
537 DebugLoc dl
= N
->getDebugLoc();
539 // If the input is not legal, eg: i1 -> fp, then it needs to be promoted to
540 // a larger type, eg: i8 -> fp. Even if it is legal, no libcall may exactly
541 // match. Look for an appropriate libcall.
542 RTLIB::Libcall LC
= RTLIB::UNKNOWN_LIBCALL
;
543 for (unsigned t
= MVT::FIRST_INTEGER_VALUETYPE
;
544 t
<= MVT::LAST_INTEGER_VALUETYPE
&& LC
== RTLIB::UNKNOWN_LIBCALL
; ++t
) {
545 NVT
= (MVT::SimpleValueType
)t
;
546 // The source needs to big enough to hold the operand.
548 LC
= Signed
? RTLIB::getSINTTOFP(NVT
, RVT
):RTLIB::getUINTTOFP (NVT
, RVT
);
550 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported XINT_TO_FP!");
552 // Sign/zero extend the argument if the libcall takes a larger type.
553 SDValue Op
= DAG
.getNode(Signed
? ISD::SIGN_EXTEND
: ISD::ZERO_EXTEND
, dl
,
554 NVT
, N
->getOperand(0));
555 return MakeLibCall(LC
, TLI
.getTypeToTransformTo(*DAG
.getContext(), RVT
),
560 //===----------------------------------------------------------------------===//
561 // Operand Float to Integer Conversion..
562 //===----------------------------------------------------------------------===//
564 bool DAGTypeLegalizer::SoftenFloatOperand(SDNode
*N
, unsigned OpNo
) {
565 DEBUG(dbgs() << "Soften float operand " << OpNo
<< ": "; N
->dump(&DAG
);
567 SDValue Res
= SDValue();
569 switch (N
->getOpcode()) {
572 dbgs() << "SoftenFloatOperand Op #" << OpNo
<< ": ";
573 N
->dump(&DAG
); dbgs() << "\n";
575 llvm_unreachable("Do not know how to soften this operator's operand!");
577 case ISD::BITCAST
: Res
= SoftenFloatOp_BITCAST(N
); break;
578 case ISD::BR_CC
: Res
= SoftenFloatOp_BR_CC(N
); break;
579 case ISD::FP_ROUND
: Res
= SoftenFloatOp_FP_ROUND(N
); break;
580 case ISD::FP_TO_SINT
: Res
= SoftenFloatOp_FP_TO_SINT(N
); break;
581 case ISD::FP_TO_UINT
: Res
= SoftenFloatOp_FP_TO_UINT(N
); break;
582 case ISD::FP32_TO_FP16
:Res
= SoftenFloatOp_FP32_TO_FP16(N
); break;
583 case ISD::SELECT_CC
: Res
= SoftenFloatOp_SELECT_CC(N
); break;
584 case ISD::SETCC
: Res
= SoftenFloatOp_SETCC(N
); break;
585 case ISD::STORE
: Res
= SoftenFloatOp_STORE(N
, OpNo
); break;
588 // If the result is null, the sub-method took care of registering results etc.
589 if (!Res
.getNode()) return false;
591 // If the result is N, the sub-method updated N in place. Tell the legalizer
593 if (Res
.getNode() == N
)
596 assert(Res
.getValueType() == N
->getValueType(0) && N
->getNumValues() == 1 &&
597 "Invalid operand expansion");
599 ReplaceValueWith(SDValue(N
, 0), Res
);
603 /// SoftenSetCCOperands - Soften the operands of a comparison. This code is
604 /// shared among BR_CC, SELECT_CC, and SETCC handlers.
605 void DAGTypeLegalizer::SoftenSetCCOperands(SDValue
&NewLHS
, SDValue
&NewRHS
,
606 ISD::CondCode
&CCCode
, DebugLoc dl
) {
607 SDValue LHSInt
= GetSoftenedFloat(NewLHS
);
608 SDValue RHSInt
= GetSoftenedFloat(NewRHS
);
609 EVT VT
= NewLHS
.getValueType();
611 assert((VT
== MVT::f32
|| VT
== MVT::f64
) && "Unsupported setcc type!");
613 // Expand into one or more soft-fp libcall(s).
614 RTLIB::Libcall LC1
= RTLIB::UNKNOWN_LIBCALL
, LC2
= RTLIB::UNKNOWN_LIBCALL
;
618 LC1
= (VT
== MVT::f32
) ? RTLIB::OEQ_F32
: RTLIB::OEQ_F64
;
622 LC1
= (VT
== MVT::f32
) ? RTLIB::UNE_F32
: RTLIB::UNE_F64
;
626 LC1
= (VT
== MVT::f32
) ? RTLIB::OGE_F32
: RTLIB::OGE_F64
;
630 LC1
= (VT
== MVT::f32
) ? RTLIB::OLT_F32
: RTLIB::OLT_F64
;
634 LC1
= (VT
== MVT::f32
) ? RTLIB::OLE_F32
: RTLIB::OLE_F64
;
638 LC1
= (VT
== MVT::f32
) ? RTLIB::OGT_F32
: RTLIB::OGT_F64
;
641 LC1
= (VT
== MVT::f32
) ? RTLIB::UO_F32
: RTLIB::UO_F64
;
644 LC1
= (VT
== MVT::f32
) ? RTLIB::O_F32
: RTLIB::O_F64
;
647 LC1
= (VT
== MVT::f32
) ? RTLIB::UO_F32
: RTLIB::UO_F64
;
650 // SETONE = SETOLT | SETOGT
651 LC1
= (VT
== MVT::f32
) ? RTLIB::OLT_F32
: RTLIB::OLT_F64
;
654 LC2
= (VT
== MVT::f32
) ? RTLIB::OGT_F32
: RTLIB::OGT_F64
;
657 LC2
= (VT
== MVT::f32
) ? RTLIB::OGE_F32
: RTLIB::OGE_F64
;
660 LC2
= (VT
== MVT::f32
) ? RTLIB::OLT_F32
: RTLIB::OLT_F64
;
663 LC2
= (VT
== MVT::f32
) ? RTLIB::OLE_F32
: RTLIB::OLE_F64
;
666 LC2
= (VT
== MVT::f32
) ? RTLIB::OEQ_F32
: RTLIB::OEQ_F64
;
668 default: assert(false && "Do not know how to soften this setcc!");
672 // Use the target specific return value for comparions lib calls.
673 EVT RetVT
= TLI
.getCmpLibcallReturnType();
674 SDValue Ops
[2] = { LHSInt
, RHSInt
};
675 NewLHS
= MakeLibCall(LC1
, RetVT
, Ops
, 2, false/*sign irrelevant*/, dl
);
676 NewRHS
= DAG
.getConstant(0, RetVT
);
677 CCCode
= TLI
.getCmpLibcallCC(LC1
);
678 if (LC2
!= RTLIB::UNKNOWN_LIBCALL
) {
679 SDValue Tmp
= DAG
.getNode(ISD::SETCC
, dl
, TLI
.getSetCCResultType(RetVT
),
680 NewLHS
, NewRHS
, DAG
.getCondCode(CCCode
));
681 NewLHS
= MakeLibCall(LC2
, RetVT
, Ops
, 2, false/*sign irrelevant*/, dl
);
682 NewLHS
= DAG
.getNode(ISD::SETCC
, dl
, TLI
.getSetCCResultType(RetVT
), NewLHS
,
683 NewRHS
, DAG
.getCondCode(TLI
.getCmpLibcallCC(LC2
)));
684 NewLHS
= DAG
.getNode(ISD::OR
, dl
, Tmp
.getValueType(), Tmp
, NewLHS
);
689 SDValue
DAGTypeLegalizer::SoftenFloatOp_BITCAST(SDNode
*N
) {
690 return DAG
.getNode(ISD::BITCAST
, N
->getDebugLoc(), N
->getValueType(0),
691 GetSoftenedFloat(N
->getOperand(0)));
694 SDValue
DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode
*N
) {
695 EVT SVT
= N
->getOperand(0).getValueType();
696 EVT RVT
= N
->getValueType(0);
698 RTLIB::Libcall LC
= RTLIB::getFPROUND(SVT
, RVT
);
699 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported FP_ROUND libcall");
701 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
702 return MakeLibCall(LC
, RVT
, &Op
, 1, false, N
->getDebugLoc());
705 SDValue
DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode
*N
) {
706 SDValue NewLHS
= N
->getOperand(2), NewRHS
= N
->getOperand(3);
707 ISD::CondCode CCCode
= cast
<CondCodeSDNode
>(N
->getOperand(1))->get();
708 SoftenSetCCOperands(NewLHS
, NewRHS
, CCCode
, N
->getDebugLoc());
710 // If SoftenSetCCOperands returned a scalar, we need to compare the result
711 // against zero to select between true and false values.
712 if (NewRHS
.getNode() == 0) {
713 NewRHS
= DAG
.getConstant(0, NewLHS
.getValueType());
717 // Update N to have the operands specified.
718 return SDValue(DAG
.UpdateNodeOperands(N
, N
->getOperand(0),
719 DAG
.getCondCode(CCCode
), NewLHS
, NewRHS
,
724 SDValue
DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode
*N
) {
725 EVT RVT
= N
->getValueType(0);
726 RTLIB::Libcall LC
= RTLIB::getFPTOSINT(N
->getOperand(0).getValueType(), RVT
);
727 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported FP_TO_SINT!");
728 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
729 return MakeLibCall(LC
, RVT
, &Op
, 1, false, N
->getDebugLoc());
732 SDValue
DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode
*N
) {
733 EVT RVT
= N
->getValueType(0);
734 RTLIB::Libcall LC
= RTLIB::getFPTOUINT(N
->getOperand(0).getValueType(), RVT
);
735 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported FP_TO_UINT!");
736 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
737 return MakeLibCall(LC
, RVT
, &Op
, 1, false, N
->getDebugLoc());
740 SDValue
DAGTypeLegalizer::SoftenFloatOp_FP32_TO_FP16(SDNode
*N
) {
741 EVT RVT
= N
->getValueType(0);
742 RTLIB::Libcall LC
= RTLIB::FPROUND_F32_F16
;
743 SDValue Op
= GetSoftenedFloat(N
->getOperand(0));
744 return MakeLibCall(LC
, RVT
, &Op
, 1, false, N
->getDebugLoc());
747 SDValue
DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode
*N
) {
748 SDValue NewLHS
= N
->getOperand(0), NewRHS
= N
->getOperand(1);
749 ISD::CondCode CCCode
= cast
<CondCodeSDNode
>(N
->getOperand(4))->get();
750 SoftenSetCCOperands(NewLHS
, NewRHS
, CCCode
, N
->getDebugLoc());
752 // If SoftenSetCCOperands returned a scalar, we need to compare the result
753 // against zero to select between true and false values.
754 if (NewRHS
.getNode() == 0) {
755 NewRHS
= DAG
.getConstant(0, NewLHS
.getValueType());
759 // Update N to have the operands specified.
760 return SDValue(DAG
.UpdateNodeOperands(N
, NewLHS
, NewRHS
,
761 N
->getOperand(2), N
->getOperand(3),
762 DAG
.getCondCode(CCCode
)),
766 SDValue
DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode
*N
) {
767 SDValue NewLHS
= N
->getOperand(0), NewRHS
= N
->getOperand(1);
768 ISD::CondCode CCCode
= cast
<CondCodeSDNode
>(N
->getOperand(2))->get();
769 SoftenSetCCOperands(NewLHS
, NewRHS
, CCCode
, N
->getDebugLoc());
771 // If SoftenSetCCOperands returned a scalar, use it.
772 if (NewRHS
.getNode() == 0) {
773 assert(NewLHS
.getValueType() == N
->getValueType(0) &&
774 "Unexpected setcc expansion!");
778 // Otherwise, update N to have the operands specified.
779 return SDValue(DAG
.UpdateNodeOperands(N
, NewLHS
, NewRHS
,
780 DAG
.getCondCode(CCCode
)),
784 SDValue
DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode
*N
, unsigned OpNo
) {
785 assert(ISD::isUNINDEXEDStore(N
) && "Indexed store during type legalization!");
786 assert(OpNo
== 1 && "Can only soften the stored value!");
787 StoreSDNode
*ST
= cast
<StoreSDNode
>(N
);
788 SDValue Val
= ST
->getValue();
789 DebugLoc dl
= N
->getDebugLoc();
791 if (ST
->isTruncatingStore())
792 // Do an FP_ROUND followed by a non-truncating store.
793 Val
= BitConvertToInteger(DAG
.getNode(ISD::FP_ROUND
, dl
, ST
->getMemoryVT(),
794 Val
, DAG
.getIntPtrConstant(0)));
796 Val
= GetSoftenedFloat(Val
);
798 return DAG
.getStore(ST
->getChain(), dl
, Val
, ST
->getBasePtr(),
799 ST
->getPointerInfo(),
800 ST
->isVolatile(), ST
->isNonTemporal(),
805 //===----------------------------------------------------------------------===//
806 // Float Result Expansion
807 //===----------------------------------------------------------------------===//
809 /// ExpandFloatResult - This method is called when the specified result of the
810 /// specified node is found to need expansion. At this point, the node may also
811 /// have invalid operands or may have other results that need promotion, we just
812 /// know that (at least) one result needs expansion.
813 void DAGTypeLegalizer::ExpandFloatResult(SDNode
*N
, unsigned ResNo
) {
814 DEBUG(dbgs() << "Expand float result: "; N
->dump(&DAG
); dbgs() << "\n");
818 // See if the target wants to custom expand this node.
819 if (CustomLowerNode(N
, N
->getValueType(ResNo
), true))
822 switch (N
->getOpcode()) {
825 dbgs() << "ExpandFloatResult #" << ResNo
<< ": ";
826 N
->dump(&DAG
); dbgs() << "\n";
828 llvm_unreachable("Do not know how to expand the result of this operator!");
830 case ISD::MERGE_VALUES
: SplitRes_MERGE_VALUES(N
, Lo
, Hi
); break;
831 case ISD::UNDEF
: SplitRes_UNDEF(N
, Lo
, Hi
); break;
832 case ISD::SELECT
: SplitRes_SELECT(N
, Lo
, Hi
); break;
833 case ISD::SELECT_CC
: SplitRes_SELECT_CC(N
, Lo
, Hi
); break;
835 case ISD::BITCAST
: ExpandRes_BITCAST(N
, Lo
, Hi
); break;
836 case ISD::BUILD_PAIR
: ExpandRes_BUILD_PAIR(N
, Lo
, Hi
); break;
837 case ISD::EXTRACT_ELEMENT
: ExpandRes_EXTRACT_ELEMENT(N
, Lo
, Hi
); break;
838 case ISD::EXTRACT_VECTOR_ELT
: ExpandRes_EXTRACT_VECTOR_ELT(N
, Lo
, Hi
); break;
839 case ISD::VAARG
: ExpandRes_VAARG(N
, Lo
, Hi
); break;
841 case ISD::ConstantFP
: ExpandFloatRes_ConstantFP(N
, Lo
, Hi
); break;
842 case ISD::FABS
: ExpandFloatRes_FABS(N
, Lo
, Hi
); break;
843 case ISD::FADD
: ExpandFloatRes_FADD(N
, Lo
, Hi
); break;
844 case ISD::FCEIL
: ExpandFloatRes_FCEIL(N
, Lo
, Hi
); break;
845 case ISD::FCOPYSIGN
: ExpandFloatRes_FCOPYSIGN(N
, Lo
, Hi
); break;
846 case ISD::FCOS
: ExpandFloatRes_FCOS(N
, Lo
, Hi
); break;
847 case ISD::FDIV
: ExpandFloatRes_FDIV(N
, Lo
, Hi
); break;
848 case ISD::FEXP
: ExpandFloatRes_FEXP(N
, Lo
, Hi
); break;
849 case ISD::FEXP2
: ExpandFloatRes_FEXP2(N
, Lo
, Hi
); break;
850 case ISD::FFLOOR
: ExpandFloatRes_FFLOOR(N
, Lo
, Hi
); break;
851 case ISD::FLOG
: ExpandFloatRes_FLOG(N
, Lo
, Hi
); break;
852 case ISD::FLOG2
: ExpandFloatRes_FLOG2(N
, Lo
, Hi
); break;
853 case ISD::FLOG10
: ExpandFloatRes_FLOG10(N
, Lo
, Hi
); break;
854 case ISD::FMA
: ExpandFloatRes_FMA(N
, Lo
, Hi
); break;
855 case ISD::FMUL
: ExpandFloatRes_FMUL(N
, Lo
, Hi
); break;
856 case ISD::FNEARBYINT
: ExpandFloatRes_FNEARBYINT(N
, Lo
, Hi
); break;
857 case ISD::FNEG
: ExpandFloatRes_FNEG(N
, Lo
, Hi
); break;
858 case ISD::FP_EXTEND
: ExpandFloatRes_FP_EXTEND(N
, Lo
, Hi
); break;
859 case ISD::FPOW
: ExpandFloatRes_FPOW(N
, Lo
, Hi
); break;
860 case ISD::FPOWI
: ExpandFloatRes_FPOWI(N
, Lo
, Hi
); break;
861 case ISD::FRINT
: ExpandFloatRes_FRINT(N
, Lo
, Hi
); break;
862 case ISD::FSIN
: ExpandFloatRes_FSIN(N
, Lo
, Hi
); break;
863 case ISD::FSQRT
: ExpandFloatRes_FSQRT(N
, Lo
, Hi
); break;
864 case ISD::FSUB
: ExpandFloatRes_FSUB(N
, Lo
, Hi
); break;
865 case ISD::FTRUNC
: ExpandFloatRes_FTRUNC(N
, Lo
, Hi
); break;
866 case ISD::LOAD
: ExpandFloatRes_LOAD(N
, Lo
, Hi
); break;
867 case ISD::SINT_TO_FP
:
868 case ISD::UINT_TO_FP
: ExpandFloatRes_XINT_TO_FP(N
, Lo
, Hi
); break;
871 // If Lo/Hi is null, the sub-method took care of registering results etc.
873 SetExpandedFloat(SDValue(N
, ResNo
), Lo
, Hi
);
876 void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode
*N
, SDValue
&Lo
,
878 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
879 assert(NVT
.getSizeInBits() == integerPartWidth
&&
880 "Do not know how to expand this float constant!");
881 APInt C
= cast
<ConstantFPSDNode
>(N
)->getValueAPF().bitcastToAPInt();
882 Lo
= DAG
.getConstantFP(APFloat(APInt(integerPartWidth
, 1,
883 &C
.getRawData()[1])), NVT
);
884 Hi
= DAG
.getConstantFP(APFloat(APInt(integerPartWidth
, 1,
885 &C
.getRawData()[0])), NVT
);
888 void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode
*N
, SDValue
&Lo
,
890 assert(N
->getValueType(0) == MVT::ppcf128
&&
891 "Logic only correct for ppcf128!");
892 DebugLoc dl
= N
->getDebugLoc();
894 GetExpandedFloat(N
->getOperand(0), Lo
, Tmp
);
895 Hi
= DAG
.getNode(ISD::FABS
, dl
, Tmp
.getValueType(), Tmp
);
896 // Lo = Hi==fabs(Hi) ? Lo : -Lo;
897 Lo
= DAG
.getNode(ISD::SELECT_CC
, dl
, Lo
.getValueType(), Tmp
, Hi
, Lo
,
898 DAG
.getNode(ISD::FNEG
, dl
, Lo
.getValueType(), Lo
),
899 DAG
.getCondCode(ISD::SETEQ
));
902 void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode
*N
, SDValue
&Lo
,
904 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
905 RTLIB::ADD_F32
, RTLIB::ADD_F64
,
906 RTLIB::ADD_F80
, RTLIB::ADD_PPCF128
),
908 GetPairElements(Call
, Lo
, Hi
);
911 void DAGTypeLegalizer::ExpandFloatRes_FCEIL(SDNode
*N
,
912 SDValue
&Lo
, SDValue
&Hi
) {
913 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
914 RTLIB::CEIL_F32
, RTLIB::CEIL_F64
,
915 RTLIB::CEIL_F80
, RTLIB::CEIL_PPCF128
),
917 GetPairElements(Call
, Lo
, Hi
);
920 void DAGTypeLegalizer::ExpandFloatRes_FCOPYSIGN(SDNode
*N
,
921 SDValue
&Lo
, SDValue
&Hi
) {
922 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
926 RTLIB::COPYSIGN_PPCF128
),
928 GetPairElements(Call
, Lo
, Hi
);
931 void DAGTypeLegalizer::ExpandFloatRes_FCOS(SDNode
*N
,
932 SDValue
&Lo
, SDValue
&Hi
) {
933 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
934 RTLIB::COS_F32
, RTLIB::COS_F64
,
935 RTLIB::COS_F80
, RTLIB::COS_PPCF128
),
937 GetPairElements(Call
, Lo
, Hi
);
940 void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode
*N
, SDValue
&Lo
,
942 SDValue Ops
[2] = { N
->getOperand(0), N
->getOperand(1) };
943 SDValue Call
= MakeLibCall(GetFPLibCall(N
->getValueType(0),
948 N
->getValueType(0), Ops
, 2, false,
950 GetPairElements(Call
, Lo
, Hi
);
953 void DAGTypeLegalizer::ExpandFloatRes_FEXP(SDNode
*N
,
954 SDValue
&Lo
, SDValue
&Hi
) {
955 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
956 RTLIB::EXP_F32
, RTLIB::EXP_F64
,
957 RTLIB::EXP_F80
, RTLIB::EXP_PPCF128
),
959 GetPairElements(Call
, Lo
, Hi
);
962 void DAGTypeLegalizer::ExpandFloatRes_FEXP2(SDNode
*N
,
963 SDValue
&Lo
, SDValue
&Hi
) {
964 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
965 RTLIB::EXP2_F32
, RTLIB::EXP2_F64
,
966 RTLIB::EXP2_F80
, RTLIB::EXP2_PPCF128
),
968 GetPairElements(Call
, Lo
, Hi
);
971 void DAGTypeLegalizer::ExpandFloatRes_FFLOOR(SDNode
*N
,
972 SDValue
&Lo
, SDValue
&Hi
) {
973 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
974 RTLIB::FLOOR_F32
,RTLIB::FLOOR_F64
,
975 RTLIB::FLOOR_F80
,RTLIB::FLOOR_PPCF128
),
977 GetPairElements(Call
, Lo
, Hi
);
980 void DAGTypeLegalizer::ExpandFloatRes_FLOG(SDNode
*N
,
981 SDValue
&Lo
, SDValue
&Hi
) {
982 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
983 RTLIB::LOG_F32
, RTLIB::LOG_F64
,
984 RTLIB::LOG_F80
, RTLIB::LOG_PPCF128
),
986 GetPairElements(Call
, Lo
, Hi
);
989 void DAGTypeLegalizer::ExpandFloatRes_FLOG2(SDNode
*N
,
990 SDValue
&Lo
, SDValue
&Hi
) {
991 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
992 RTLIB::LOG2_F32
, RTLIB::LOG2_F64
,
993 RTLIB::LOG2_F80
, RTLIB::LOG2_PPCF128
),
995 GetPairElements(Call
, Lo
, Hi
);
998 void DAGTypeLegalizer::ExpandFloatRes_FLOG10(SDNode
*N
,
999 SDValue
&Lo
, SDValue
&Hi
) {
1000 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
1001 RTLIB::LOG10_F32
,RTLIB::LOG10_F64
,
1002 RTLIB::LOG10_F80
,RTLIB::LOG10_PPCF128
),
1004 GetPairElements(Call
, Lo
, Hi
);
1007 void DAGTypeLegalizer::ExpandFloatRes_FMA(SDNode
*N
, SDValue
&Lo
,
1009 SDValue Ops
[3] = { N
->getOperand(0), N
->getOperand(1), N
->getOperand(2) };
1010 SDValue Call
= MakeLibCall(GetFPLibCall(N
->getValueType(0),
1014 RTLIB::FMA_PPCF128
),
1015 N
->getValueType(0), Ops
, 3, false,
1017 GetPairElements(Call
, Lo
, Hi
);
1020 void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode
*N
, SDValue
&Lo
,
1022 SDValue Ops
[2] = { N
->getOperand(0), N
->getOperand(1) };
1023 SDValue Call
= MakeLibCall(GetFPLibCall(N
->getValueType(0),
1027 RTLIB::MUL_PPCF128
),
1028 N
->getValueType(0), Ops
, 2, false,
1030 GetPairElements(Call
, Lo
, Hi
);
1033 void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode
*N
,
1034 SDValue
&Lo
, SDValue
&Hi
) {
1035 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
1036 RTLIB::NEARBYINT_F32
,
1037 RTLIB::NEARBYINT_F64
,
1038 RTLIB::NEARBYINT_F80
,
1039 RTLIB::NEARBYINT_PPCF128
),
1041 GetPairElements(Call
, Lo
, Hi
);
1044 void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode
*N
, SDValue
&Lo
,
1046 DebugLoc dl
= N
->getDebugLoc();
1047 GetExpandedFloat(N
->getOperand(0), Lo
, Hi
);
1048 Lo
= DAG
.getNode(ISD::FNEG
, dl
, Lo
.getValueType(), Lo
);
1049 Hi
= DAG
.getNode(ISD::FNEG
, dl
, Hi
.getValueType(), Hi
);
1052 void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode
*N
, SDValue
&Lo
,
1054 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), N
->getValueType(0));
1055 Hi
= DAG
.getNode(ISD::FP_EXTEND
, N
->getDebugLoc(), NVT
, N
->getOperand(0));
1056 Lo
= DAG
.getConstantFP(APFloat(APInt(NVT
.getSizeInBits(), 0)), NVT
);
1059 void DAGTypeLegalizer::ExpandFloatRes_FPOW(SDNode
*N
,
1060 SDValue
&Lo
, SDValue
&Hi
) {
1061 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
1062 RTLIB::POW_F32
, RTLIB::POW_F64
,
1063 RTLIB::POW_F80
, RTLIB::POW_PPCF128
),
1065 GetPairElements(Call
, Lo
, Hi
);
1068 void DAGTypeLegalizer::ExpandFloatRes_FPOWI(SDNode
*N
,
1069 SDValue
&Lo
, SDValue
&Hi
) {
1070 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
1071 RTLIB::POWI_F32
, RTLIB::POWI_F64
,
1072 RTLIB::POWI_F80
, RTLIB::POWI_PPCF128
),
1074 GetPairElements(Call
, Lo
, Hi
);
1077 void DAGTypeLegalizer::ExpandFloatRes_FRINT(SDNode
*N
,
1078 SDValue
&Lo
, SDValue
&Hi
) {
1079 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
1080 RTLIB::RINT_F32
, RTLIB::RINT_F64
,
1081 RTLIB::RINT_F80
, RTLIB::RINT_PPCF128
),
1083 GetPairElements(Call
, Lo
, Hi
);
1086 void DAGTypeLegalizer::ExpandFloatRes_FSIN(SDNode
*N
,
1087 SDValue
&Lo
, SDValue
&Hi
) {
1088 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
1089 RTLIB::SIN_F32
, RTLIB::SIN_F64
,
1090 RTLIB::SIN_F80
, RTLIB::SIN_PPCF128
),
1092 GetPairElements(Call
, Lo
, Hi
);
1095 void DAGTypeLegalizer::ExpandFloatRes_FSQRT(SDNode
*N
,
1096 SDValue
&Lo
, SDValue
&Hi
) {
1097 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
1098 RTLIB::SQRT_F32
, RTLIB::SQRT_F64
,
1099 RTLIB::SQRT_F80
, RTLIB::SQRT_PPCF128
),
1101 GetPairElements(Call
, Lo
, Hi
);
1104 void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode
*N
, SDValue
&Lo
,
1106 SDValue Ops
[2] = { N
->getOperand(0), N
->getOperand(1) };
1107 SDValue Call
= MakeLibCall(GetFPLibCall(N
->getValueType(0),
1111 RTLIB::SUB_PPCF128
),
1112 N
->getValueType(0), Ops
, 2, false,
1114 GetPairElements(Call
, Lo
, Hi
);
1117 void DAGTypeLegalizer::ExpandFloatRes_FTRUNC(SDNode
*N
,
1118 SDValue
&Lo
, SDValue
&Hi
) {
1119 SDValue Call
= LibCallify(GetFPLibCall(N
->getValueType(0),
1120 RTLIB::TRUNC_F32
, RTLIB::TRUNC_F64
,
1121 RTLIB::TRUNC_F80
, RTLIB::TRUNC_PPCF128
),
1123 GetPairElements(Call
, Lo
, Hi
);
1126 void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode
*N
, SDValue
&Lo
,
1128 if (ISD::isNormalLoad(N
)) {
1129 ExpandRes_NormalLoad(N
, Lo
, Hi
);
1133 assert(ISD::isUNINDEXEDLoad(N
) && "Indexed load during type legalization!");
1134 LoadSDNode
*LD
= cast
<LoadSDNode
>(N
);
1135 SDValue Chain
= LD
->getChain();
1136 SDValue Ptr
= LD
->getBasePtr();
1137 DebugLoc dl
= N
->getDebugLoc();
1139 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), LD
->getValueType(0));
1140 assert(NVT
.isByteSized() && "Expanded type not byte sized!");
1141 assert(LD
->getMemoryVT().bitsLE(NVT
) && "Float type not round?");
1143 Hi
= DAG
.getExtLoad(LD
->getExtensionType(), dl
, NVT
, Chain
, Ptr
,
1144 LD
->getPointerInfo(), LD
->getMemoryVT(), LD
->isVolatile(),
1145 LD
->isNonTemporal(), LD
->getAlignment());
1147 // Remember the chain.
1148 Chain
= Hi
.getValue(1);
1150 // The low part is zero.
1151 Lo
= DAG
.getConstantFP(APFloat(APInt(NVT
.getSizeInBits(), 0)), NVT
);
1153 // Modified the chain - switch anything that used the old chain to use the
1155 ReplaceValueWith(SDValue(LD
, 1), Chain
);
1158 void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode
*N
, SDValue
&Lo
,
1160 assert(N
->getValueType(0) == MVT::ppcf128
&& "Unsupported XINT_TO_FP!");
1161 EVT VT
= N
->getValueType(0);
1162 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(), VT
);
1163 SDValue Src
= N
->getOperand(0);
1164 EVT SrcVT
= Src
.getValueType();
1165 bool isSigned
= N
->getOpcode() == ISD::SINT_TO_FP
;
1166 DebugLoc dl
= N
->getDebugLoc();
1168 // First do an SINT_TO_FP, whether the original was signed or unsigned.
1169 // When promoting partial word types to i32 we must honor the signedness,
1171 if (SrcVT
.bitsLE(MVT::i32
)) {
1172 // The integer can be represented exactly in an f64.
1173 Src
= DAG
.getNode(isSigned
? ISD::SIGN_EXTEND
: ISD::ZERO_EXTEND
, dl
,
1175 Lo
= DAG
.getConstantFP(APFloat(APInt(NVT
.getSizeInBits(), 0)), NVT
);
1176 Hi
= DAG
.getNode(ISD::SINT_TO_FP
, dl
, NVT
, Src
);
1178 RTLIB::Libcall LC
= RTLIB::UNKNOWN_LIBCALL
;
1179 if (SrcVT
.bitsLE(MVT::i64
)) {
1180 Src
= DAG
.getNode(isSigned
? ISD::SIGN_EXTEND
: ISD::ZERO_EXTEND
, dl
,
1182 LC
= RTLIB::SINTTOFP_I64_PPCF128
;
1183 } else if (SrcVT
.bitsLE(MVT::i128
)) {
1184 Src
= DAG
.getNode(ISD::SIGN_EXTEND
, dl
, MVT::i128
, Src
);
1185 LC
= RTLIB::SINTTOFP_I128_PPCF128
;
1187 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported XINT_TO_FP!");
1189 Hi
= MakeLibCall(LC
, VT
, &Src
, 1, true, dl
);
1190 GetPairElements(Hi
, Lo
, Hi
);
1196 // Unsigned - fix up the SINT_TO_FP value just calculated.
1197 Hi
= DAG
.getNode(ISD::BUILD_PAIR
, dl
, VT
, Lo
, Hi
);
1198 SrcVT
= Src
.getValueType();
1200 // x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128.
1201 static const uint64_t TwoE32
[] = { 0x41f0000000000000LL
, 0 };
1202 static const uint64_t TwoE64
[] = { 0x43f0000000000000LL
, 0 };
1203 static const uint64_t TwoE128
[] = { 0x47f0000000000000LL
, 0 };
1204 const uint64_t *Parts
= 0;
1206 switch (SrcVT
.getSimpleVT().SimpleTy
) {
1208 assert(false && "Unsupported UINT_TO_FP!");
1220 Lo
= DAG
.getNode(ISD::FADD
, dl
, VT
, Hi
,
1221 DAG
.getConstantFP(APFloat(APInt(128, 2, Parts
)),
1223 Lo
= DAG
.getNode(ISD::SELECT_CC
, dl
, VT
, Src
, DAG
.getConstant(0, SrcVT
),
1224 Lo
, Hi
, DAG
.getCondCode(ISD::SETLT
));
1225 GetPairElements(Lo
, Lo
, Hi
);
1229 //===----------------------------------------------------------------------===//
1230 // Float Operand Expansion
1231 //===----------------------------------------------------------------------===//
1233 /// ExpandFloatOperand - This method is called when the specified operand of the
1234 /// specified node is found to need expansion. At this point, all of the result
1235 /// types of the node are known to be legal, but other operands of the node may
1236 /// need promotion or expansion as well as the specified one.
1237 bool DAGTypeLegalizer::ExpandFloatOperand(SDNode
*N
, unsigned OpNo
) {
1238 DEBUG(dbgs() << "Expand float operand: "; N
->dump(&DAG
); dbgs() << "\n");
1239 SDValue Res
= SDValue();
1241 if (TLI
.getOperationAction(N
->getOpcode(), N
->getOperand(OpNo
).getValueType())
1242 == TargetLowering::Custom
)
1243 Res
= TLI
.LowerOperation(SDValue(N
, 0), DAG
);
1245 if (Res
.getNode() == 0) {
1246 switch (N
->getOpcode()) {
1249 dbgs() << "ExpandFloatOperand Op #" << OpNo
<< ": ";
1250 N
->dump(&DAG
); dbgs() << "\n";
1252 llvm_unreachable("Do not know how to expand this operator's operand!");
1254 case ISD::BITCAST
: Res
= ExpandOp_BITCAST(N
); break;
1255 case ISD::BUILD_VECTOR
: Res
= ExpandOp_BUILD_VECTOR(N
); break;
1256 case ISD::EXTRACT_ELEMENT
: Res
= ExpandOp_EXTRACT_ELEMENT(N
); break;
1258 case ISD::BR_CC
: Res
= ExpandFloatOp_BR_CC(N
); break;
1259 case ISD::FP_ROUND
: Res
= ExpandFloatOp_FP_ROUND(N
); break;
1260 case ISD::FP_TO_SINT
: Res
= ExpandFloatOp_FP_TO_SINT(N
); break;
1261 case ISD::FP_TO_UINT
: Res
= ExpandFloatOp_FP_TO_UINT(N
); break;
1262 case ISD::SELECT_CC
: Res
= ExpandFloatOp_SELECT_CC(N
); break;
1263 case ISD::SETCC
: Res
= ExpandFloatOp_SETCC(N
); break;
1264 case ISD::STORE
: Res
= ExpandFloatOp_STORE(cast
<StoreSDNode
>(N
),
1269 // If the result is null, the sub-method took care of registering results etc.
1270 if (!Res
.getNode()) return false;
1272 // If the result is N, the sub-method updated N in place. Tell the legalizer
1274 if (Res
.getNode() == N
)
1277 assert(Res
.getValueType() == N
->getValueType(0) && N
->getNumValues() == 1 &&
1278 "Invalid operand expansion");
1280 ReplaceValueWith(SDValue(N
, 0), Res
);
1284 /// FloatExpandSetCCOperands - Expand the operands of a comparison. This code
1285 /// is shared among BR_CC, SELECT_CC, and SETCC handlers.
1286 void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue
&NewLHS
,
1288 ISD::CondCode
&CCCode
,
1290 SDValue LHSLo
, LHSHi
, RHSLo
, RHSHi
;
1291 GetExpandedFloat(NewLHS
, LHSLo
, LHSHi
);
1292 GetExpandedFloat(NewRHS
, RHSLo
, RHSHi
);
1294 EVT VT
= NewLHS
.getValueType();
1295 assert(VT
== MVT::ppcf128
&& "Unsupported setcc type!");
1297 // FIXME: This generated code sucks. We want to generate
1298 // FCMPU crN, hi1, hi2
1300 // FCMPU crN, lo1, lo2
1301 // The following can be improved, but not that much.
1302 SDValue Tmp1
, Tmp2
, Tmp3
;
1303 Tmp1
= DAG
.getSetCC(dl
, TLI
.getSetCCResultType(LHSHi
.getValueType()),
1304 LHSHi
, RHSHi
, ISD::SETOEQ
);
1305 Tmp2
= DAG
.getSetCC(dl
, TLI
.getSetCCResultType(LHSLo
.getValueType()),
1306 LHSLo
, RHSLo
, CCCode
);
1307 Tmp3
= DAG
.getNode(ISD::AND
, dl
, Tmp1
.getValueType(), Tmp1
, Tmp2
);
1308 Tmp1
= DAG
.getSetCC(dl
, TLI
.getSetCCResultType(LHSHi
.getValueType()),
1309 LHSHi
, RHSHi
, ISD::SETUNE
);
1310 Tmp2
= DAG
.getSetCC(dl
, TLI
.getSetCCResultType(LHSHi
.getValueType()),
1311 LHSHi
, RHSHi
, CCCode
);
1312 Tmp1
= DAG
.getNode(ISD::AND
, dl
, Tmp1
.getValueType(), Tmp1
, Tmp2
);
1313 NewLHS
= DAG
.getNode(ISD::OR
, dl
, Tmp1
.getValueType(), Tmp1
, Tmp3
);
1314 NewRHS
= SDValue(); // LHS is the result, not a compare.
1317 SDValue
DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode
*N
) {
1318 SDValue NewLHS
= N
->getOperand(2), NewRHS
= N
->getOperand(3);
1319 ISD::CondCode CCCode
= cast
<CondCodeSDNode
>(N
->getOperand(1))->get();
1320 FloatExpandSetCCOperands(NewLHS
, NewRHS
, CCCode
, N
->getDebugLoc());
1322 // If ExpandSetCCOperands returned a scalar, we need to compare the result
1323 // against zero to select between true and false values.
1324 if (NewRHS
.getNode() == 0) {
1325 NewRHS
= DAG
.getConstant(0, NewLHS
.getValueType());
1326 CCCode
= ISD::SETNE
;
1329 // Update N to have the operands specified.
1330 return SDValue(DAG
.UpdateNodeOperands(N
, N
->getOperand(0),
1331 DAG
.getCondCode(CCCode
), NewLHS
, NewRHS
,
1332 N
->getOperand(4)), 0);
1335 SDValue
DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode
*N
) {
1336 assert(N
->getOperand(0).getValueType() == MVT::ppcf128
&&
1337 "Logic only correct for ppcf128!");
1339 GetExpandedFloat(N
->getOperand(0), Lo
, Hi
);
1340 // Round it the rest of the way (e.g. to f32) if needed.
1341 return DAG
.getNode(ISD::FP_ROUND
, N
->getDebugLoc(),
1342 N
->getValueType(0), Hi
, N
->getOperand(1));
1345 SDValue
DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode
*N
) {
1346 EVT RVT
= N
->getValueType(0);
1347 DebugLoc dl
= N
->getDebugLoc();
1349 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
1350 // PPC (the libcall is not available). FIXME: Do this in a less hacky way.
1351 if (RVT
== MVT::i32
) {
1352 assert(N
->getOperand(0).getValueType() == MVT::ppcf128
&&
1353 "Logic only correct for ppcf128!");
1354 SDValue Res
= DAG
.getNode(ISD::FP_ROUND_INREG
, dl
, MVT::ppcf128
,
1355 N
->getOperand(0), DAG
.getValueType(MVT::f64
));
1356 Res
= DAG
.getNode(ISD::FP_ROUND
, dl
, MVT::f64
, Res
,
1357 DAG
.getIntPtrConstant(1));
1358 return DAG
.getNode(ISD::FP_TO_SINT
, dl
, MVT::i32
, Res
);
1361 RTLIB::Libcall LC
= RTLIB::getFPTOSINT(N
->getOperand(0).getValueType(), RVT
);
1362 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported FP_TO_SINT!");
1363 return MakeLibCall(LC
, RVT
, &N
->getOperand(0), 1, false, dl
);
1366 SDValue
DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode
*N
) {
1367 EVT RVT
= N
->getValueType(0);
1368 DebugLoc dl
= N
->getDebugLoc();
1370 // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
1371 // PPC (the libcall is not available). FIXME: Do this in a less hacky way.
1372 if (RVT
== MVT::i32
) {
1373 assert(N
->getOperand(0).getValueType() == MVT::ppcf128
&&
1374 "Logic only correct for ppcf128!");
1375 const uint64_t TwoE31
[] = {0x41e0000000000000LL
, 0};
1376 APFloat APF
= APFloat(APInt(128, 2, TwoE31
));
1377 SDValue Tmp
= DAG
.getConstantFP(APF
, MVT::ppcf128
);
1378 // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
1379 // FIXME: generated code sucks.
1380 return DAG
.getNode(ISD::SELECT_CC
, dl
, MVT::i32
, N
->getOperand(0), Tmp
,
1381 DAG
.getNode(ISD::ADD
, dl
, MVT::i32
,
1382 DAG
.getNode(ISD::FP_TO_SINT
, dl
, MVT::i32
,
1383 DAG
.getNode(ISD::FSUB
, dl
,
1387 DAG
.getConstant(0x80000000, MVT::i32
)),
1388 DAG
.getNode(ISD::FP_TO_SINT
, dl
,
1389 MVT::i32
, N
->getOperand(0)),
1390 DAG
.getCondCode(ISD::SETGE
));
1393 RTLIB::Libcall LC
= RTLIB::getFPTOUINT(N
->getOperand(0).getValueType(), RVT
);
1394 assert(LC
!= RTLIB::UNKNOWN_LIBCALL
&& "Unsupported FP_TO_UINT!");
1395 return MakeLibCall(LC
, N
->getValueType(0), &N
->getOperand(0), 1, false, dl
);
1398 SDValue
DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode
*N
) {
1399 SDValue NewLHS
= N
->getOperand(0), NewRHS
= N
->getOperand(1);
1400 ISD::CondCode CCCode
= cast
<CondCodeSDNode
>(N
->getOperand(4))->get();
1401 FloatExpandSetCCOperands(NewLHS
, NewRHS
, CCCode
, N
->getDebugLoc());
1403 // If ExpandSetCCOperands returned a scalar, we need to compare the result
1404 // against zero to select between true and false values.
1405 if (NewRHS
.getNode() == 0) {
1406 NewRHS
= DAG
.getConstant(0, NewLHS
.getValueType());
1407 CCCode
= ISD::SETNE
;
1410 // Update N to have the operands specified.
1411 return SDValue(DAG
.UpdateNodeOperands(N
, NewLHS
, NewRHS
,
1412 N
->getOperand(2), N
->getOperand(3),
1413 DAG
.getCondCode(CCCode
)), 0);
1416 SDValue
DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode
*N
) {
1417 SDValue NewLHS
= N
->getOperand(0), NewRHS
= N
->getOperand(1);
1418 ISD::CondCode CCCode
= cast
<CondCodeSDNode
>(N
->getOperand(2))->get();
1419 FloatExpandSetCCOperands(NewLHS
, NewRHS
, CCCode
, N
->getDebugLoc());
1421 // If ExpandSetCCOperands returned a scalar, use it.
1422 if (NewRHS
.getNode() == 0) {
1423 assert(NewLHS
.getValueType() == N
->getValueType(0) &&
1424 "Unexpected setcc expansion!");
1428 // Otherwise, update N to have the operands specified.
1429 return SDValue(DAG
.UpdateNodeOperands(N
, NewLHS
, NewRHS
,
1430 DAG
.getCondCode(CCCode
)), 0);
1433 SDValue
DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode
*N
, unsigned OpNo
) {
1434 if (ISD::isNormalStore(N
))
1435 return ExpandOp_NormalStore(N
, OpNo
);
1437 assert(ISD::isUNINDEXEDStore(N
) && "Indexed store during type legalization!");
1438 assert(OpNo
== 1 && "Can only expand the stored value so far");
1439 StoreSDNode
*ST
= cast
<StoreSDNode
>(N
);
1441 SDValue Chain
= ST
->getChain();
1442 SDValue Ptr
= ST
->getBasePtr();
1444 EVT NVT
= TLI
.getTypeToTransformTo(*DAG
.getContext(),
1445 ST
->getValue().getValueType());
1446 assert(NVT
.isByteSized() && "Expanded type not byte sized!");
1447 assert(ST
->getMemoryVT().bitsLE(NVT
) && "Float type not round?");
1450 GetExpandedOp(ST
->getValue(), Lo
, Hi
);
1452 return DAG
.getTruncStore(Chain
, N
->getDebugLoc(), Hi
, Ptr
,
1453 ST
->getPointerInfo(),
1454 ST
->getMemoryVT(), ST
->isVolatile(),
1455 ST
->isNonTemporal(), ST
->getAlignment());