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