~ubuntu-branches/ubuntu/wily/clamav/wily-proposed

« back to all changes in this revision

Viewing changes to libclamav/c++/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp

  • Committer: Package Import Robot
  • Author(s): Scott Kitterman, Sebastian Andrzej Siewior, Andreas Cadhalpun, Scott Kitterman, Javier Fernández-Sanguino
  • Date: 2015-01-28 00:25:13 UTC
  • mfrom: (0.48.14 sid)
  • Revision ID: package-import@ubuntu.com-20150128002513-lil2oi74cooy4lzr
Tags: 0.98.6+dfsg-1
[ Sebastian Andrzej Siewior ]
* update "fix-ssize_t-size_t-off_t-printf-modifier", include of misc.h was
  missing but was pulled in via the systemd patch.
* Don't leak return codes from libmspack to clamav API. (Closes: #774686).

[ Andreas Cadhalpun ]
* Add patch to avoid emitting incremental progress messages when not
  outputting to a terminal. (Closes: #767350)
* Update lintian-overrides for unused-file-paragraph-in-dep5-copyright.
* clamav-base.postinst: always chown /var/log/clamav and /var/lib/clamav
  to clamav:clamav, not only on fresh installations. (Closes: #775400)
* Adapt the clamav-daemon and clamav-freshclam logrotate scripts,
  so that they correctly work under systemd.
* Move the PidFile variable from the clamd/freshclam configuration files
  to the init scripts. This makes the init scripts more robust against
  misconfiguration and avoids error messages with systemd. (Closes: #767353)
* debian/copyright: drop files from Files-Excluded only present in github
  tarballs
* Drop Workaround-a-bug-in-libc-on-Hurd.patch, because hurd got fixed.
  (see #752237)
* debian/rules: Remove useless --with-system-tommath --without-included-ltdl
  configure options.

[ Scott Kitterman ]
* Stop stripping llvm when repacking the tarball as the system llvm on some
  releases is too old to use
* New upstream bugfix release
  - Library shared object revisions.
  - Includes a patch from Sebastian Andrzej Siewior making ClamAV pid files
    compatible with systemd.
  - Fix a heap out of bounds condition with crafted Yoda's crypter files.
    This issue was discovered by Felix Groebert of the Google Security Team.
  - Fix a heap out of bounds condition with crafted mew packer files. This
    issue was discovered by Felix Groebert of the Google Security Team.
  - Fix a heap out of bounds condition with crafted upx packer files. This
    issue was discovered by Kevin Szkudlapski of Quarkslab.
  - Fix a heap out of bounds condition with crafted upack packer files. This
    issue was discovered by Sebastian Andrzej Siewior. CVE-2014-9328.
  - Compensate a crash due to incorrect compiler optimization when handling
    crafted petite packer files. This issue was discovered by Sebastian
    Andrzej Siewior.
* Update lintian override for embedded zlib to match new so version

[ Javier Fernández-Sanguino ]
* Updated Spanish Debconf template translation (Closes: #773563)

Show diffs side-by-side

added added

removed removed

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