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