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