LegalizeFloatTypes.cpp revision 21c2972f7d24680f6475877a3398b7f8cf515b33
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  case ISD::VAARG:              ExpandRes_VAARG(N, Lo, Hi); break;
579
580  case ISD::ConstantFP: ExpandFloatRes_ConstantFP(N, Lo, Hi); break;
581  case ISD::FABS:       ExpandFloatRes_FABS(N, Lo, Hi); break;
582  case ISD::FADD:       ExpandFloatRes_FADD(N, Lo, Hi); break;
583  case ISD::FDIV:       ExpandFloatRes_FDIV(N, Lo, Hi); break;
584  case ISD::FMUL:       ExpandFloatRes_FMUL(N, Lo, Hi); break;
585  case ISD::FNEG:       ExpandFloatRes_FNEG(N, Lo, Hi); break;
586  case ISD::FP_EXTEND:  ExpandFloatRes_FP_EXTEND(N, Lo, Hi); break;
587  case ISD::FSUB:       ExpandFloatRes_FSUB(N, Lo, Hi); break;
588  case ISD::LOAD:       ExpandFloatRes_LOAD(N, Lo, Hi); break;
589  case ISD::SINT_TO_FP:
590  case ISD::UINT_TO_FP: ExpandFloatRes_XINT_TO_FP(N, Lo, Hi); break;
591  }
592
593  // If Lo/Hi is null, the sub-method took care of registering results etc.
594  if (Lo.getNode())
595    SetExpandedFloat(SDValue(N, ResNo), Lo, Hi);
596}
597
598void DAGTypeLegalizer::ExpandFloatRes_ConstantFP(SDNode *N, SDValue &Lo,
599                                                 SDValue &Hi) {
600  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
601  assert(NVT.getSizeInBits() == integerPartWidth &&
602         "Do not know how to expand this float constant!");
603  APInt C = cast<ConstantFPSDNode>(N)->getValueAPF().bitcastToAPInt();
604  Lo = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1,
605                                       &C.getRawData()[1])), NVT);
606  Hi = DAG.getConstantFP(APFloat(APInt(integerPartWidth, 1,
607                                       &C.getRawData()[0])), NVT);
608}
609
610void DAGTypeLegalizer::ExpandFloatRes_FADD(SDNode *N, SDValue &Lo,
611                                           SDValue &Hi) {
612  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
613  SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0),
614                                            RTLIB::ADD_F32,
615                                            RTLIB::ADD_F64,
616                                            RTLIB::ADD_F80,
617                                            RTLIB::ADD_PPCF128),
618                               N->getValueType(0), Ops, 2,
619                               false);
620  assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
621         "Call lowered wrongly!");
622  Lo = Call.getOperand(0); Hi = Call.getOperand(1);
623}
624
625void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo,
626                                           SDValue &Hi) {
627  assert(N->getValueType(0) == MVT::ppcf128 &&
628         "Logic only correct for ppcf128!");
629  SDValue Tmp;
630  GetExpandedFloat(N->getOperand(0), Lo, Tmp);
631  Hi = DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp);
632  // Lo = Hi==fabs(Hi) ? Lo : -Lo;
633  Lo = DAG.getNode(ISD::SELECT_CC, Lo.getValueType(), Tmp, Hi, Lo,
634                   DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo),
635                   DAG.getCondCode(ISD::SETEQ));
636}
637
638void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo,
639                                           SDValue &Hi) {
640  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
641  SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0),
642                                            RTLIB::DIV_F32,
643                                            RTLIB::DIV_F64,
644                                            RTLIB::DIV_F80,
645                                            RTLIB::DIV_PPCF128),
646                               N->getValueType(0), Ops, 2,
647                               false);
648  assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
649         "Call lowered wrongly!");
650  Lo = Call.getOperand(0); Hi = Call.getOperand(1);
651}
652
653void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo,
654                                           SDValue &Hi) {
655  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
656  SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0),
657                                            RTLIB::MUL_F32,
658                                            RTLIB::MUL_F64,
659                                            RTLIB::MUL_F80,
660                                            RTLIB::MUL_PPCF128),
661                               N->getValueType(0), Ops, 2,
662                               false);
663  assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
664         "Call lowered wrongly!");
665  Lo = Call.getOperand(0); Hi = Call.getOperand(1);
666}
667
668void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo,
669                                           SDValue &Hi) {
670  GetExpandedFloat(N->getOperand(0), Lo, Hi);
671  Lo = DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo);
672  Hi = DAG.getNode(ISD::FNEG, Hi.getValueType(), Hi);
673}
674
675void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo,
676                                                SDValue &Hi) {
677  MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0));
678  Hi = DAG.getNode(ISD::FP_EXTEND, NVT, N->getOperand(0));
679  Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT);
680}
681
682void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo,
683                                           SDValue &Hi) {
684  SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) };
685  SDValue Call = MakeLibCall(GetFPLibCall(N->getValueType(0),
686                                            RTLIB::SUB_F32,
687                                            RTLIB::SUB_F64,
688                                            RTLIB::SUB_F80,
689                                            RTLIB::SUB_PPCF128),
690                               N->getValueType(0), Ops, 2,
691                               false);
692  assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR &&
693         "Call lowered wrongly!");
694  Lo = Call.getOperand(0); Hi = Call.getOperand(1);
695}
696
697void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo,
698                                           SDValue &Hi) {
699  if (ISD::isNormalLoad(N)) {
700    ExpandRes_NormalLoad(N, Lo, Hi);
701    return;
702  }
703
704  assert(ISD::isUNINDEXEDLoad(N) && "Indexed load during type legalization!");
705  LoadSDNode *LD = cast<LoadSDNode>(N);
706  SDValue Chain = LD->getChain();
707  SDValue Ptr = LD->getBasePtr();
708
709  MVT NVT = TLI.getTypeToTransformTo(LD->getValueType(0));
710  assert(NVT.isByteSized() && "Expanded type not byte sized!");
711  assert(LD->getMemoryVT().bitsLE(NVT) && "Float type not round?");
712
713  Lo = DAG.getExtLoad(LD->getExtensionType(), NVT, Chain, Ptr,
714                      LD->getSrcValue(), LD->getSrcValueOffset(),
715                      LD->getMemoryVT(),
716                      LD->isVolatile(), LD->getAlignment());
717
718  // Remember the chain.
719  Chain = Lo.getValue(1);
720
721  // The high part is undefined.
722  Hi = DAG.getNode(ISD::UNDEF, NVT);
723
724  // Modified the chain - switch anything that used the old chain to use the
725  // new one.
726  ReplaceValueWith(SDValue(LD, 1), Chain);
727}
728
729void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo,
730                                                 SDValue &Hi) {
731  assert(N->getValueType(0) == MVT::ppcf128 && "Unsupported XINT_TO_FP!");
732  MVT VT = N->getValueType(0);
733  MVT NVT = TLI.getTypeToTransformTo(VT);
734  SDValue Src = N->getOperand(0);
735  MVT SrcVT = Src.getValueType();
736
737  // First do an SINT_TO_FP, whether the original was signed or unsigned.
738  if (SrcVT.bitsLE(MVT::i32)) {
739    // The integer can be represented exactly in an f64.
740    Src = DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Src);
741    Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT);
742    Hi = DAG.getNode(ISD::SINT_TO_FP, NVT, Src);
743  } else {
744    RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL;
745    if (SrcVT.bitsLE(MVT::i64)) {
746      Src = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Src);
747      LC = RTLIB::SINTTOFP_I64_PPCF128;
748    } else if (SrcVT.bitsLE(MVT::i128)) {
749      Src = DAG.getNode(ISD::SIGN_EXTEND, MVT::i128, Src);
750      LC = RTLIB::SINTTOFP_I128_PPCF128;
751    }
752    assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!");
753
754    Hi = MakeLibCall(LC, VT, &Src, 1, true);
755    assert(Hi.getNode()->getOpcode() == ISD::BUILD_PAIR &&
756           "Call lowered wrongly!");
757    Lo = Hi.getOperand(0); Hi = Hi.getOperand(1);
758  }
759
760  if (N->getOpcode() == ISD::SINT_TO_FP)
761    return;
762
763  // Unsigned - fix up the SINT_TO_FP value just calculated.
764  Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi);
765  SrcVT = Src.getValueType();
766
767  // x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128.
768  static const uint64_t TwoE32[]  = { 0x41f0000000000000LL, 0 };
769  static const uint64_t TwoE64[]  = { 0x43f0000000000000LL, 0 };
770  static const uint64_t TwoE128[] = { 0x47f0000000000000LL, 0 };
771  const uint64_t *Parts = 0;
772
773  switch (SrcVT.getSimpleVT()) {
774  default:
775    assert(false && "Unsupported UINT_TO_FP!");
776  case MVT::i32:
777    Parts = TwoE32;
778  case MVT::i64:
779    Parts = TwoE64;
780  case MVT::i128:
781    Parts = TwoE128;
782  }
783
784  Lo = DAG.getNode(ISD::FADD, VT, Hi,
785                   DAG.getConstantFP(APFloat(APInt(128, 2, Parts)),
786                                     MVT::ppcf128));
787  Lo = DAG.getNode(ISD::SELECT_CC, VT, Src, DAG.getConstant(0, SrcVT), Lo, Hi,
788                   DAG.getCondCode(ISD::SETLT));
789  Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, DAG.getIntPtrConstant(1));
790  Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, DAG.getIntPtrConstant(0));
791}
792
793
794//===----------------------------------------------------------------------===//
795//  Float Operand Expansion
796//===----------------------------------------------------------------------===//
797
798/// ExpandFloatOperand - This method is called when the specified operand of the
799/// specified node is found to need expansion.  At this point, all of the result
800/// types of the node are known to be legal, but other operands of the node may
801/// need promotion or expansion as well as the specified one.
802bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) {
803  DEBUG(cerr << "Expand float operand: "; N->dump(&DAG); cerr << "\n");
804  SDValue Res = SDValue();
805
806  if (TLI.getOperationAction(N->getOpcode(), N->getOperand(OpNo).getValueType())
807      == TargetLowering::Custom)
808    Res = TLI.LowerOperation(SDValue(N, 0), DAG);
809
810  if (Res.getNode() == 0) {
811    switch (N->getOpcode()) {
812    default:
813  #ifndef NDEBUG
814      cerr << "ExpandFloatOperand Op #" << OpNo << ": ";
815      N->dump(&DAG); cerr << "\n";
816  #endif
817      assert(0 && "Do not know how to expand this operator's operand!");
818      abort();
819
820    case ISD::BIT_CONVERT:     Res = ExpandOp_BIT_CONVERT(N); break;
821    case ISD::BUILD_VECTOR:    Res = ExpandOp_BUILD_VECTOR(N); break;
822    case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break;
823
824    case ISD::BR_CC:      Res = ExpandFloatOp_BR_CC(N); break;
825    case ISD::FP_ROUND:   Res = ExpandFloatOp_FP_ROUND(N); break;
826    case ISD::FP_TO_SINT: Res = ExpandFloatOp_FP_TO_SINT(N); break;
827    case ISD::FP_TO_UINT: Res = ExpandFloatOp_FP_TO_UINT(N); break;
828    case ISD::SELECT_CC:  Res = ExpandFloatOp_SELECT_CC(N); break;
829    case ISD::SETCC:      Res = ExpandFloatOp_SETCC(N); break;
830    case ISD::STORE:      Res = ExpandFloatOp_STORE(cast<StoreSDNode>(N),
831                                                    OpNo); break;
832    }
833  }
834
835  // If the result is null, the sub-method took care of registering results etc.
836  if (!Res.getNode()) return false;
837  // If the result is N, the sub-method updated N in place.  Check to see if any
838  // operands are new, and if so, mark them.
839  if (Res.getNode() == N) {
840    // Mark N as new and remark N and its operands.  This allows us to correctly
841    // revisit N if it needs another step of expansion and allows us to visit
842    // any new operands to N.
843    ReanalyzeNode(N);
844    return true;
845  }
846
847  assert(Res.getValueType() == N->getValueType(0) && N->getNumValues() == 1 &&
848         "Invalid operand expansion");
849
850  ReplaceValueWith(SDValue(N, 0), Res);
851  return false;
852}
853
854/// FloatExpandSetCCOperands - Expand the operands of a comparison.  This code
855/// is shared among BR_CC, SELECT_CC, and SETCC handlers.
856void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS,
857                                                SDValue &NewRHS,
858                                                ISD::CondCode &CCCode) {
859  SDValue LHSLo, LHSHi, RHSLo, RHSHi;
860  GetExpandedFloat(NewLHS, LHSLo, LHSHi);
861  GetExpandedFloat(NewRHS, RHSLo, RHSHi);
862
863  MVT VT = NewLHS.getValueType();
864  assert(VT == MVT::ppcf128 && "Unsupported setcc type!");
865
866  // FIXME:  This generated code sucks.  We want to generate
867  //         FCMP crN, hi1, hi2
868  //         BNE crN, L:
869  //         FCMP crN, lo1, lo2
870  // The following can be improved, but not that much.
871  SDValue Tmp1, Tmp2, Tmp3;
872  Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, ISD::SETEQ);
873  Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo), LHSLo, RHSLo, CCCode);
874  Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
875  Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, ISD::SETNE);
876  Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi), LHSHi, RHSHi, CCCode);
877  Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2);
878  NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3);
879  NewRHS = SDValue();   // LHS is the result, not a compare.
880}
881
882SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) {
883  SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3);
884  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(1))->get();
885  FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode);
886
887  // If ExpandSetCCOperands returned a scalar, we need to compare the result
888  // against zero to select between true and false values.
889  if (NewRHS.getNode() == 0) {
890    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
891    CCCode = ISD::SETNE;
892  }
893
894  // Update N to have the operands specified.
895  return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0),
896                                DAG.getCondCode(CCCode), NewLHS, NewRHS,
897                                N->getOperand(4));
898}
899
900SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) {
901  assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
902         "Logic only correct for ppcf128!");
903  SDValue Lo, Hi;
904  GetExpandedFloat(N->getOperand(0), Lo, Hi);
905  // Round it the rest of the way (e.g. to f32) if needed.
906  return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Hi, N->getOperand(1));
907}
908
909SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) {
910  MVT RVT = N->getValueType(0);
911
912  // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
913  // PPC (the libcall is not available).  FIXME: Do this in a less hacky way.
914  if (RVT == MVT::i32) {
915    assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
916           "Logic only correct for ppcf128!");
917    SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, MVT::ppcf128,
918                              N->getOperand(0), DAG.getValueType(MVT::f64));
919    Res = DAG.getNode(ISD::FP_ROUND, MVT::f64, Res, DAG.getIntPtrConstant(1));
920    return DAG.getNode(ISD::FP_TO_SINT, MVT::i32, Res);
921  }
922
923  RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT);
924  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!");
925  return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false);
926}
927
928SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) {
929  MVT RVT = N->getValueType(0);
930
931  // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on
932  // PPC (the libcall is not available).  FIXME: Do this in a less hacky way.
933  if (RVT == MVT::i32) {
934    assert(N->getOperand(0).getValueType() == MVT::ppcf128 &&
935           "Logic only correct for ppcf128!");
936    const uint64_t TwoE31[] = {0x41e0000000000000LL, 0};
937    APFloat APF = APFloat(APInt(128, 2, TwoE31));
938    SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128);
939    //  X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X
940    // FIXME: generated code sucks.
941    return DAG.getNode(ISD::SELECT_CC, MVT::i32, N->getOperand(0), Tmp,
942                       DAG.getNode(ISD::ADD, MVT::i32,
943                                   DAG.getNode(ISD::FP_TO_SINT, MVT::i32,
944                                               DAG.getNode(ISD::FSUB,
945                                                           MVT::ppcf128,
946                                                           N->getOperand(0),
947                                                           Tmp)),
948                                   DAG.getConstant(0x80000000, MVT::i32)),
949                       DAG.getNode(ISD::FP_TO_SINT, MVT::i32, N->getOperand(0)),
950                       DAG.getCondCode(ISD::SETGE));
951  }
952
953  RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT);
954  assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!");
955  return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false);
956}
957
958SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) {
959  SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
960  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(4))->get();
961  FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode);
962
963  // If ExpandSetCCOperands returned a scalar, we need to compare the result
964  // against zero to select between true and false values.
965  if (NewRHS.getNode() == 0) {
966    NewRHS = DAG.getConstant(0, NewLHS.getValueType());
967    CCCode = ISD::SETNE;
968  }
969
970  // Update N to have the operands specified.
971  return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
972                                N->getOperand(2), N->getOperand(3),
973                                DAG.getCondCode(CCCode));
974}
975
976SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) {
977  SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1);
978  ISD::CondCode CCCode = cast<CondCodeSDNode>(N->getOperand(2))->get();
979  FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode);
980
981  // If ExpandSetCCOperands returned a scalar, use it.
982  if (NewRHS.getNode() == 0) {
983    assert(NewLHS.getValueType() == N->getValueType(0) &&
984           "Unexpected setcc expansion!");
985    return NewLHS;
986  }
987
988  // Otherwise, update N to have the operands specified.
989  return DAG.UpdateNodeOperands(SDValue(N, 0), NewLHS, NewRHS,
990                                DAG.getCondCode(CCCode));
991}
992
993SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) {
994  if (ISD::isNormalStore(N))
995    return ExpandOp_NormalStore(N, OpNo);
996
997  assert(ISD::isUNINDEXEDStore(N) && "Indexed store during type legalization!");
998  assert(OpNo == 1 && "Can only expand the stored value so far");
999  StoreSDNode *ST = cast<StoreSDNode>(N);
1000
1001  SDValue Chain = ST->getChain();
1002  SDValue Ptr = ST->getBasePtr();
1003
1004  MVT NVT = TLI.getTypeToTransformTo(ST->getValue().getValueType());
1005  assert(NVT.isByteSized() && "Expanded type not byte sized!");
1006  assert(ST->getMemoryVT().bitsLE(NVT) && "Float type not round?");
1007
1008  SDValue Lo, Hi;
1009  GetExpandedOp(ST->getValue(), Lo, Hi);
1010
1011  return DAG.getTruncStore(Chain, Lo, Ptr,
1012                           ST->getSrcValue(), ST->getSrcValueOffset(),
1013                           ST->getMemoryVT(),
1014                           ST->isVolatile(), ST->getAlignment());
1015}
1016