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