/home/arjun/llvm-project/llvm/include/llvm/ADT/APFloat.h
Line | Count | Source (jump to first uncovered line) |
1 | | //===- llvm/ADT/APFloat.h - Arbitrary Precision Floating Point ---*- C++ -*-==// |
2 | | // |
3 | | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | | // See https://llvm.org/LICENSE.txt for license information. |
5 | | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | | // |
7 | | //===----------------------------------------------------------------------===// |
8 | | /// |
9 | | /// \file |
10 | | /// \brief |
11 | | /// This file declares a class to represent arbitrary precision floating point |
12 | | /// values and provide a variety of arithmetic operations on them. |
13 | | /// |
14 | | //===----------------------------------------------------------------------===// |
15 | | |
16 | | #ifndef LLVM_ADT_APFLOAT_H |
17 | | #define LLVM_ADT_APFLOAT_H |
18 | | |
19 | | #include "llvm/ADT/APInt.h" |
20 | | #include "llvm/ADT/ArrayRef.h" |
21 | | #include "llvm/ADT/FloatingPointMode.h" |
22 | | #include "llvm/Support/ErrorHandling.h" |
23 | | #include <memory> |
24 | | |
25 | | #define APFLOAT_DISPATCH_ON_SEMANTICS(METHOD_CALL) \ |
26 | 0 | do { \ |
27 | 0 | if (usesLayout<IEEEFloat>(getSemantics())) \ |
28 | 0 | return U.IEEE.METHOD_CALL; \ |
29 | 0 | if (usesLayout<DoubleAPFloat>(getSemantics())) \ |
30 | 0 | return U.Double.METHOD_CALL; \ |
31 | 0 | llvm_unreachable("Unexpected semantics"); \ |
32 | 0 | } while (false) |
33 | | |
34 | | namespace llvm { |
35 | | |
36 | | struct fltSemantics; |
37 | | class APSInt; |
38 | | class StringRef; |
39 | | class APFloat; |
40 | | class raw_ostream; |
41 | | |
42 | | template <typename T> class Expected; |
43 | | template <typename T> class SmallVectorImpl; |
44 | | |
45 | | /// Enum that represents what fraction of the LSB truncated bits of an fp number |
46 | | /// represent. |
47 | | /// |
48 | | /// This essentially combines the roles of guard and sticky bits. |
49 | | enum lostFraction { // Example of truncated bits: |
50 | | lfExactlyZero, // 000000 |
51 | | lfLessThanHalf, // 0xxxxx x's not all zero |
52 | | lfExactlyHalf, // 100000 |
53 | | lfMoreThanHalf // 1xxxxx x's not all zero |
54 | | }; |
55 | | |
56 | | /// A self-contained host- and target-independent arbitrary-precision |
57 | | /// floating-point software implementation. |
58 | | /// |
59 | | /// APFloat uses bignum integer arithmetic as provided by static functions in |
60 | | /// the APInt class. The library will work with bignum integers whose parts are |
61 | | /// any unsigned type at least 16 bits wide, but 64 bits is recommended. |
62 | | /// |
63 | | /// Written for clarity rather than speed, in particular with a view to use in |
64 | | /// the front-end of a cross compiler so that target arithmetic can be correctly |
65 | | /// performed on the host. Performance should nonetheless be reasonable, |
66 | | /// particularly for its intended use. It may be useful as a base |
67 | | /// implementation for a run-time library during development of a faster |
68 | | /// target-specific one. |
69 | | /// |
70 | | /// All 5 rounding modes in the IEEE-754R draft are handled correctly for all |
71 | | /// implemented operations. Currently implemented operations are add, subtract, |
72 | | /// multiply, divide, fused-multiply-add, conversion-to-float, |
73 | | /// conversion-to-integer and conversion-from-integer. New rounding modes |
74 | | /// (e.g. away from zero) can be added with three or four lines of code. |
75 | | /// |
76 | | /// Four formats are built-in: IEEE single precision, double precision, |
77 | | /// quadruple precision, and x87 80-bit extended double (when operating with |
78 | | /// full extended precision). Adding a new format that obeys IEEE semantics |
79 | | /// only requires adding two lines of code: a declaration and definition of the |
80 | | /// format. |
81 | | /// |
82 | | /// All operations return the status of that operation as an exception bit-mask, |
83 | | /// so multiple operations can be done consecutively with their results or-ed |
84 | | /// together. The returned status can be useful for compiler diagnostics; e.g., |
85 | | /// inexact, underflow and overflow can be easily diagnosed on constant folding, |
86 | | /// and compiler optimizers can determine what exceptions would be raised by |
87 | | /// folding operations and optimize, or perhaps not optimize, accordingly. |
88 | | /// |
89 | | /// At present, underflow tininess is detected after rounding; it should be |
90 | | /// straight forward to add support for the before-rounding case too. |
91 | | /// |
92 | | /// The library reads hexadecimal floating point numbers as per C99, and |
93 | | /// correctly rounds if necessary according to the specified rounding mode. |
94 | | /// Syntax is required to have been validated by the caller. It also converts |
95 | | /// floating point numbers to hexadecimal text as per the C99 %a and %A |
96 | | /// conversions. The output precision (or alternatively the natural minimal |
97 | | /// precision) can be specified; if the requested precision is less than the |
98 | | /// natural precision the output is correctly rounded for the specified rounding |
99 | | /// mode. |
100 | | /// |
101 | | /// It also reads decimal floating point numbers and correctly rounds according |
102 | | /// to the specified rounding mode. |
103 | | /// |
104 | | /// Conversion to decimal text is not currently implemented. |
105 | | /// |
106 | | /// Non-zero finite numbers are represented internally as a sign bit, a 16-bit |
107 | | /// signed exponent, and the significand as an array of integer parts. After |
108 | | /// normalization of a number of precision P the exponent is within the range of |
109 | | /// the format, and if the number is not denormal the P-th bit of the |
110 | | /// significand is set as an explicit integer bit. For denormals the most |
111 | | /// significant bit is shifted right so that the exponent is maintained at the |
112 | | /// format's minimum, so that the smallest denormal has just the least |
113 | | /// significant bit of the significand set. The sign of zeroes and infinities |
114 | | /// is significant; the exponent and significand of such numbers is not stored, |
115 | | /// but has a known implicit (deterministic) value: 0 for the significands, 0 |
116 | | /// for zero exponent, all 1 bits for infinity exponent. For NaNs the sign and |
117 | | /// significand are deterministic, although not really meaningful, and preserved |
118 | | /// in non-conversion operations. The exponent is implicitly all 1 bits. |
119 | | /// |
120 | | /// APFloat does not provide any exception handling beyond default exception |
121 | | /// handling. We represent Signaling NaNs via IEEE-754R 2008 6.2.1 should clause |
122 | | /// by encoding Signaling NaNs with the first bit of its trailing significand as |
123 | | /// 0. |
124 | | /// |
125 | | /// TODO |
126 | | /// ==== |
127 | | /// |
128 | | /// Some features that may or may not be worth adding: |
129 | | /// |
130 | | /// Binary to decimal conversion (hard). |
131 | | /// |
132 | | /// Optional ability to detect underflow tininess before rounding. |
133 | | /// |
134 | | /// New formats: x87 in single and double precision mode (IEEE apart from |
135 | | /// extended exponent range) (hard). |
136 | | /// |
137 | | /// New operations: sqrt, IEEE remainder, C90 fmod, nexttoward. |
138 | | /// |
139 | | |
140 | | // This is the common type definitions shared by APFloat and its internal |
141 | | // implementation classes. This struct should not define any non-static data |
142 | | // members. |
143 | | struct APFloatBase { |
144 | | typedef APInt::WordType integerPart; |
145 | | static constexpr unsigned integerPartWidth = APInt::APINT_BITS_PER_WORD; |
146 | | |
147 | | /// A signed type to represent a floating point numbers unbiased exponent. |
148 | | typedef int32_t ExponentType; |
149 | | |
150 | | /// \name Floating Point Semantics. |
151 | | /// @{ |
152 | | enum Semantics { |
153 | | S_IEEEhalf, |
154 | | S_BFloat, |
155 | | S_IEEEsingle, |
156 | | S_IEEEdouble, |
157 | | S_x87DoubleExtended, |
158 | | S_IEEEquad, |
159 | | S_PPCDoubleDouble |
160 | | }; |
161 | | |
162 | | static const llvm::fltSemantics &EnumToSemantics(Semantics S); |
163 | | static Semantics SemanticsToEnum(const llvm::fltSemantics &Sem); |
164 | | |
165 | | static const fltSemantics &IEEEhalf() LLVM_READNONE; |
166 | | static const fltSemantics &BFloat() LLVM_READNONE; |
167 | | static const fltSemantics &IEEEsingle() LLVM_READNONE; |
168 | | static const fltSemantics &IEEEdouble() LLVM_READNONE; |
169 | | static const fltSemantics &IEEEquad() LLVM_READNONE; |
170 | | static const fltSemantics &PPCDoubleDouble() LLVM_READNONE; |
171 | | static const fltSemantics &x87DoubleExtended() LLVM_READNONE; |
172 | | |
173 | | /// A Pseudo fltsemantic used to construct APFloats that cannot conflict with |
174 | | /// anything real. |
175 | | static const fltSemantics &Bogus() LLVM_READNONE; |
176 | | |
177 | | /// @} |
178 | | |
179 | | /// IEEE-754R 5.11: Floating Point Comparison Relations. |
180 | | enum cmpResult { |
181 | | cmpLessThan, |
182 | | cmpEqual, |
183 | | cmpGreaterThan, |
184 | | cmpUnordered |
185 | | }; |
186 | | |
187 | | /// IEEE-754R 4.3: Rounding-direction attributes. |
188 | | using roundingMode = llvm::RoundingMode; |
189 | | |
190 | | static constexpr roundingMode rmNearestTiesToEven = |
191 | | RoundingMode::NearestTiesToEven; |
192 | | static constexpr roundingMode rmTowardPositive = RoundingMode::TowardPositive; |
193 | | static constexpr roundingMode rmTowardNegative = RoundingMode::TowardNegative; |
194 | | static constexpr roundingMode rmTowardZero = RoundingMode::TowardZero; |
195 | | static constexpr roundingMode rmNearestTiesToAway = |
196 | | RoundingMode::NearestTiesToAway; |
197 | | |
198 | | /// IEEE-754R 7: Default exception handling. |
199 | | /// |
200 | | /// opUnderflow or opOverflow are always returned or-ed with opInexact. |
201 | | /// |
202 | | /// APFloat models this behavior specified by IEEE-754: |
203 | | /// "For operations producing results in floating-point format, the default |
204 | | /// result of an operation that signals the invalid operation exception |
205 | | /// shall be a quiet NaN." |
206 | | enum opStatus { |
207 | | opOK = 0x00, |
208 | | opInvalidOp = 0x01, |
209 | | opDivByZero = 0x02, |
210 | | opOverflow = 0x04, |
211 | | opUnderflow = 0x08, |
212 | | opInexact = 0x10 |
213 | | }; |
214 | | |
215 | | /// Category of internally-represented number. |
216 | | enum fltCategory { |
217 | | fcInfinity, |
218 | | fcNaN, |
219 | | fcNormal, |
220 | | fcZero |
221 | | }; |
222 | | |
223 | | /// Convenience enum used to construct an uninitialized APFloat. |
224 | | enum uninitializedTag { |
225 | | uninitialized |
226 | | }; |
227 | | |
228 | | /// Enumeration of \c ilogb error results. |
229 | | enum IlogbErrorKinds { |
230 | | IEK_Zero = INT_MIN + 1, |
231 | | IEK_NaN = INT_MIN, |
232 | | IEK_Inf = INT_MAX |
233 | | }; |
234 | | |
235 | | static unsigned int semanticsPrecision(const fltSemantics &); |
236 | | static ExponentType semanticsMinExponent(const fltSemantics &); |
237 | | static ExponentType semanticsMaxExponent(const fltSemantics &); |
238 | | static unsigned int semanticsSizeInBits(const fltSemantics &); |
239 | | |
240 | | /// Returns the size of the floating point number (in bits) in the given |
241 | | /// semantics. |
242 | | static unsigned getSizeInBits(const fltSemantics &Sem); |
243 | | }; |
244 | | |
245 | | namespace detail { |
246 | | |
247 | | class IEEEFloat final : public APFloatBase { |
248 | | public: |
249 | | /// \name Constructors |
250 | | /// @{ |
251 | | |
252 | | IEEEFloat(const fltSemantics &); // Default construct to 0.0 |
253 | | IEEEFloat(const fltSemantics &, integerPart); |
254 | | IEEEFloat(const fltSemantics &, uninitializedTag); |
255 | | IEEEFloat(const fltSemantics &, const APInt &); |
256 | | explicit IEEEFloat(double d); |
257 | | explicit IEEEFloat(float f); |
258 | | IEEEFloat(const IEEEFloat &); |
259 | | IEEEFloat(IEEEFloat &&); |
260 | | ~IEEEFloat(); |
261 | | |
262 | | /// @} |
263 | | |
264 | | /// Returns whether this instance allocated memory. |
265 | 0 | bool needsCleanup() const { return partCount() > 1; } |
266 | | |
267 | | /// \name Convenience "constructors" |
268 | | /// @{ |
269 | | |
270 | | /// @} |
271 | | |
272 | | /// \name Arithmetic |
273 | | /// @{ |
274 | | |
275 | | opStatus add(const IEEEFloat &, roundingMode); |
276 | | opStatus subtract(const IEEEFloat &, roundingMode); |
277 | | opStatus multiply(const IEEEFloat &, roundingMode); |
278 | | opStatus divide(const IEEEFloat &, roundingMode); |
279 | | /// IEEE remainder. |
280 | | opStatus remainder(const IEEEFloat &); |
281 | | /// C fmod, or llvm frem. |
282 | | opStatus mod(const IEEEFloat &); |
283 | | opStatus fusedMultiplyAdd(const IEEEFloat &, const IEEEFloat &, roundingMode); |
284 | | opStatus roundToIntegral(roundingMode); |
285 | | /// IEEE-754R 5.3.1: nextUp/nextDown. |
286 | | opStatus next(bool nextDown); |
287 | | |
288 | | /// @} |
289 | | |
290 | | /// \name Sign operations. |
291 | | /// @{ |
292 | | |
293 | | void changeSign(); |
294 | | |
295 | | /// @} |
296 | | |
297 | | /// \name Conversions |
298 | | /// @{ |
299 | | |
300 | | opStatus convert(const fltSemantics &, roundingMode, bool *); |
301 | | opStatus convertToInteger(MutableArrayRef<integerPart>, unsigned int, bool, |
302 | | roundingMode, bool *) const; |
303 | | opStatus convertFromAPInt(const APInt &, bool, roundingMode); |
304 | | opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int, |
305 | | bool, roundingMode); |
306 | | opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int, |
307 | | bool, roundingMode); |
308 | | Expected<opStatus> convertFromString(StringRef, roundingMode); |
309 | | APInt bitcastToAPInt() const; |
310 | | double convertToDouble() const; |
311 | | float convertToFloat() const; |
312 | | |
313 | | /// @} |
314 | | |
315 | | /// The definition of equality is not straightforward for floating point, so |
316 | | /// we won't use operator==. Use one of the following, or write whatever it |
317 | | /// is you really mean. |
318 | | bool operator==(const IEEEFloat &) const = delete; |
319 | | |
320 | | /// IEEE comparison with another floating point number (NaNs compare |
321 | | /// unordered, 0==-0). |
322 | | cmpResult compare(const IEEEFloat &) const; |
323 | | |
324 | | /// Bitwise comparison for equality (QNaNs compare equal, 0!=-0). |
325 | | bool bitwiseIsEqual(const IEEEFloat &) const; |
326 | | |
327 | | /// Write out a hexadecimal representation of the floating point value to DST, |
328 | | /// which must be of sufficient size, in the C99 form [-]0xh.hhhhp[+-]d. |
329 | | /// Return the number of characters written, excluding the terminating NUL. |
330 | | unsigned int convertToHexString(char *dst, unsigned int hexDigits, |
331 | | bool upperCase, roundingMode) const; |
332 | | |
333 | | /// \name IEEE-754R 5.7.2 General operations. |
334 | | /// @{ |
335 | | |
336 | | /// IEEE-754R isSignMinus: Returns true if and only if the current value is |
337 | | /// negative. |
338 | | /// |
339 | | /// This applies to zeros and NaNs as well. |
340 | 0 | bool isNegative() const { return sign; } |
341 | | |
342 | | /// IEEE-754R isNormal: Returns true if and only if the current value is normal. |
343 | | /// |
344 | | /// This implies that the current value of the float is not zero, subnormal, |
345 | | /// infinite, or NaN following the definition of normality from IEEE-754R. |
346 | 0 | bool isNormal() const { return !isDenormal() && isFiniteNonZero(); } |
347 | | |
348 | | /// Returns true if and only if the current value is zero, subnormal, or |
349 | | /// normal. |
350 | | /// |
351 | | /// This means that the value is not infinite or NaN. |
352 | 0 | bool isFinite() const { return !isNaN() && !isInfinity(); } |
353 | | |
354 | | /// Returns true if and only if the float is plus or minus zero. |
355 | 0 | bool isZero() const { return category == fcZero; } |
356 | | |
357 | | /// IEEE-754R isSubnormal(): Returns true if and only if the float is a |
358 | | /// denormal. |
359 | | bool isDenormal() const; |
360 | | |
361 | | /// IEEE-754R isInfinite(): Returns true if and only if the float is infinity. |
362 | 0 | bool isInfinity() const { return category == fcInfinity; } |
363 | | |
364 | | /// Returns true if and only if the float is a quiet or signaling NaN. |
365 | 0 | bool isNaN() const { return category == fcNaN; } |
366 | | |
367 | | /// Returns true if and only if the float is a signaling NaN. |
368 | | bool isSignaling() const; |
369 | | |
370 | | /// @} |
371 | | |
372 | | /// \name Simple Queries |
373 | | /// @{ |
374 | | |
375 | 0 | fltCategory getCategory() const { return category; } |
376 | 0 | const fltSemantics &getSemantics() const { return *semantics; } |
377 | 0 | bool isNonZero() const { return category != fcZero; } |
378 | 0 | bool isFiniteNonZero() const { return isFinite() && !isZero(); } |
379 | 0 | bool isPosZero() const { return isZero() && !isNegative(); } |
380 | 0 | bool isNegZero() const { return isZero() && isNegative(); } |
381 | | |
382 | | /// Returns true if and only if the number has the smallest possible non-zero |
383 | | /// magnitude in the current semantics. |
384 | | bool isSmallest() const; |
385 | | |
386 | | /// Returns true if and only if the number has the largest possible finite |
387 | | /// magnitude in the current semantics. |
388 | | bool isLargest() const; |
389 | | |
390 | | /// Returns true if and only if the number is an exact integer. |
391 | | bool isInteger() const; |
392 | | |
393 | | /// @} |
394 | | |
395 | | IEEEFloat &operator=(const IEEEFloat &); |
396 | | IEEEFloat &operator=(IEEEFloat &&); |
397 | | |
398 | | /// Overload to compute a hash code for an APFloat value. |
399 | | /// |
400 | | /// Note that the use of hash codes for floating point values is in general |
401 | | /// frought with peril. Equality is hard to define for these values. For |
402 | | /// example, should negative and positive zero hash to different codes? Are |
403 | | /// they equal or not? This hash value implementation specifically |
404 | | /// emphasizes producing different codes for different inputs in order to |
405 | | /// be used in canonicalization and memoization. As such, equality is |
406 | | /// bitwiseIsEqual, and 0 != -0. |
407 | | friend hash_code hash_value(const IEEEFloat &Arg); |
408 | | |
409 | | /// Converts this value into a decimal string. |
410 | | /// |
411 | | /// \param FormatPrecision The maximum number of digits of |
412 | | /// precision to output. If there are fewer digits available, |
413 | | /// zero padding will not be used unless the value is |
414 | | /// integral and small enough to be expressed in |
415 | | /// FormatPrecision digits. 0 means to use the natural |
416 | | /// precision of the number. |
417 | | /// \param FormatMaxPadding The maximum number of zeros to |
418 | | /// consider inserting before falling back to scientific |
419 | | /// notation. 0 means to always use scientific notation. |
420 | | /// |
421 | | /// \param TruncateZero Indicate whether to remove the trailing zero in |
422 | | /// fraction part or not. Also setting this parameter to false forcing |
423 | | /// producing of output more similar to default printf behavior. |
424 | | /// Specifically the lower e is used as exponent delimiter and exponent |
425 | | /// always contains no less than two digits. |
426 | | /// |
427 | | /// Number Precision MaxPadding Result |
428 | | /// ------ --------- ---------- ------ |
429 | | /// 1.01E+4 5 2 10100 |
430 | | /// 1.01E+4 4 2 1.01E+4 |
431 | | /// 1.01E+4 5 1 1.01E+4 |
432 | | /// 1.01E-2 5 2 0.0101 |
433 | | /// 1.01E-2 4 2 0.0101 |
434 | | /// 1.01E-2 4 1 1.01E-2 |
435 | | void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0, |
436 | | unsigned FormatMaxPadding = 3, bool TruncateZero = true) const; |
437 | | |
438 | | /// If this value has an exact multiplicative inverse, store it in inv and |
439 | | /// return true. |
440 | | bool getExactInverse(APFloat *inv) const; |
441 | | |
442 | | /// Returns the exponent of the internal representation of the APFloat. |
443 | | /// |
444 | | /// Because the radix of APFloat is 2, this is equivalent to floor(log2(x)). |
445 | | /// For special APFloat values, this returns special error codes: |
446 | | /// |
447 | | /// NaN -> \c IEK_NaN |
448 | | /// 0 -> \c IEK_Zero |
449 | | /// Inf -> \c IEK_Inf |
450 | | /// |
451 | | friend int ilogb(const IEEEFloat &Arg); |
452 | | |
453 | | /// Returns: X * 2^Exp for integral exponents. |
454 | | friend IEEEFloat scalbn(IEEEFloat X, int Exp, roundingMode); |
455 | | |
456 | | friend IEEEFloat frexp(const IEEEFloat &X, int &Exp, roundingMode); |
457 | | |
458 | | /// \name Special value setters. |
459 | | /// @{ |
460 | | |
461 | | void makeLargest(bool Neg = false); |
462 | | void makeSmallest(bool Neg = false); |
463 | | void makeNaN(bool SNaN = false, bool Neg = false, |
464 | | const APInt *fill = nullptr); |
465 | | void makeInf(bool Neg = false); |
466 | | void makeZero(bool Neg = false); |
467 | | void makeQuiet(); |
468 | | |
469 | | /// Returns the smallest (by magnitude) normalized finite number in the given |
470 | | /// semantics. |
471 | | /// |
472 | | /// \param Negative - True iff the number should be negative |
473 | | void makeSmallestNormalized(bool Negative = false); |
474 | | |
475 | | /// @} |
476 | | |
477 | | cmpResult compareAbsoluteValue(const IEEEFloat &) const; |
478 | | |
479 | | private: |
480 | | /// \name Simple Queries |
481 | | /// @{ |
482 | | |
483 | | integerPart *significandParts(); |
484 | | const integerPart *significandParts() const; |
485 | | unsigned int partCount() const; |
486 | | |
487 | | /// @} |
488 | | |
489 | | /// \name Significand operations. |
490 | | /// @{ |
491 | | |
492 | | integerPart addSignificand(const IEEEFloat &); |
493 | | integerPart subtractSignificand(const IEEEFloat &, integerPart); |
494 | | lostFraction addOrSubtractSignificand(const IEEEFloat &, bool subtract); |
495 | | lostFraction multiplySignificand(const IEEEFloat &, IEEEFloat); |
496 | | lostFraction multiplySignificand(const IEEEFloat&); |
497 | | lostFraction divideSignificand(const IEEEFloat &); |
498 | | void incrementSignificand(); |
499 | | void initialize(const fltSemantics *); |
500 | | void shiftSignificandLeft(unsigned int); |
501 | | lostFraction shiftSignificandRight(unsigned int); |
502 | | unsigned int significandLSB() const; |
503 | | unsigned int significandMSB() const; |
504 | | void zeroSignificand(); |
505 | | /// Return true if the significand excluding the integral bit is all ones. |
506 | | bool isSignificandAllOnes() const; |
507 | | /// Return true if the significand excluding the integral bit is all zeros. |
508 | | bool isSignificandAllZeros() const; |
509 | | |
510 | | /// @} |
511 | | |
512 | | /// \name Arithmetic on special values. |
513 | | /// @{ |
514 | | |
515 | | opStatus addOrSubtractSpecials(const IEEEFloat &, bool subtract); |
516 | | opStatus divideSpecials(const IEEEFloat &); |
517 | | opStatus multiplySpecials(const IEEEFloat &); |
518 | | opStatus modSpecials(const IEEEFloat &); |
519 | | opStatus remainderSpecials(const IEEEFloat&); |
520 | | |
521 | | /// @} |
522 | | |
523 | | /// \name Miscellany |
524 | | /// @{ |
525 | | |
526 | | bool convertFromStringSpecials(StringRef str); |
527 | | opStatus normalize(roundingMode, lostFraction); |
528 | | opStatus addOrSubtract(const IEEEFloat &, roundingMode, bool subtract); |
529 | | opStatus handleOverflow(roundingMode); |
530 | | bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const; |
531 | | opStatus convertToSignExtendedInteger(MutableArrayRef<integerPart>, |
532 | | unsigned int, bool, roundingMode, |
533 | | bool *) const; |
534 | | opStatus convertFromUnsignedParts(const integerPart *, unsigned int, |
535 | | roundingMode); |
536 | | Expected<opStatus> convertFromHexadecimalString(StringRef, roundingMode); |
537 | | Expected<opStatus> convertFromDecimalString(StringRef, roundingMode); |
538 | | char *convertNormalToHexString(char *, unsigned int, bool, |
539 | | roundingMode) const; |
540 | | opStatus roundSignificandWithExponent(const integerPart *, unsigned int, int, |
541 | | roundingMode); |
542 | | |
543 | | /// @} |
544 | | |
545 | | APInt convertHalfAPFloatToAPInt() const; |
546 | | APInt convertBFloatAPFloatToAPInt() const; |
547 | | APInt convertFloatAPFloatToAPInt() const; |
548 | | APInt convertDoubleAPFloatToAPInt() const; |
549 | | APInt convertQuadrupleAPFloatToAPInt() const; |
550 | | APInt convertF80LongDoubleAPFloatToAPInt() const; |
551 | | APInt convertPPCDoubleDoubleAPFloatToAPInt() const; |
552 | | void initFromAPInt(const fltSemantics *Sem, const APInt &api); |
553 | | void initFromHalfAPInt(const APInt &api); |
554 | | void initFromBFloatAPInt(const APInt &api); |
555 | | void initFromFloatAPInt(const APInt &api); |
556 | | void initFromDoubleAPInt(const APInt &api); |
557 | | void initFromQuadrupleAPInt(const APInt &api); |
558 | | void initFromF80LongDoubleAPInt(const APInt &api); |
559 | | void initFromPPCDoubleDoubleAPInt(const APInt &api); |
560 | | |
561 | | void assign(const IEEEFloat &); |
562 | | void copySignificand(const IEEEFloat &); |
563 | | void freeSignificand(); |
564 | | |
565 | | /// Note: this must be the first data member. |
566 | | /// The semantics that this value obeys. |
567 | | const fltSemantics *semantics; |
568 | | |
569 | | /// A binary fraction with an explicit integer bit. |
570 | | /// |
571 | | /// The significand must be at least one bit wider than the target precision. |
572 | | union Significand { |
573 | | integerPart part; |
574 | | integerPart *parts; |
575 | | } significand; |
576 | | |
577 | | /// The signed unbiased exponent of the value. |
578 | | ExponentType exponent; |
579 | | |
580 | | /// What kind of floating point number this is. |
581 | | /// |
582 | | /// Only 2 bits are required, but VisualStudio incorrectly sign extends it. |
583 | | /// Using the extra bit keeps it from failing under VisualStudio. |
584 | | fltCategory category : 3; |
585 | | |
586 | | /// Sign bit of the number. |
587 | | unsigned int sign : 1; |
588 | | }; |
589 | | |
590 | | hash_code hash_value(const IEEEFloat &Arg); |
591 | | int ilogb(const IEEEFloat &Arg); |
592 | | IEEEFloat scalbn(IEEEFloat X, int Exp, IEEEFloat::roundingMode); |
593 | | IEEEFloat frexp(const IEEEFloat &Val, int &Exp, IEEEFloat::roundingMode RM); |
594 | | |
595 | | // This mode implements more precise float in terms of two APFloats. |
596 | | // The interface and layout is designed for arbitrary underlying semantics, |
597 | | // though currently only PPCDoubleDouble semantics are supported, whose |
598 | | // corresponding underlying semantics are IEEEdouble. |
599 | | class DoubleAPFloat final : public APFloatBase { |
600 | | // Note: this must be the first data member. |
601 | | const fltSemantics *Semantics; |
602 | | std::unique_ptr<APFloat[]> Floats; |
603 | | |
604 | | opStatus addImpl(const APFloat &a, const APFloat &aa, const APFloat &c, |
605 | | const APFloat &cc, roundingMode RM); |
606 | | |
607 | | opStatus addWithSpecial(const DoubleAPFloat &LHS, const DoubleAPFloat &RHS, |
608 | | DoubleAPFloat &Out, roundingMode RM); |
609 | | |
610 | | public: |
611 | | DoubleAPFloat(const fltSemantics &S); |
612 | | DoubleAPFloat(const fltSemantics &S, uninitializedTag); |
613 | | DoubleAPFloat(const fltSemantics &S, integerPart); |
614 | | DoubleAPFloat(const fltSemantics &S, const APInt &I); |
615 | | DoubleAPFloat(const fltSemantics &S, APFloat &&First, APFloat &&Second); |
616 | | DoubleAPFloat(const DoubleAPFloat &RHS); |
617 | | DoubleAPFloat(DoubleAPFloat &&RHS); |
618 | | |
619 | | DoubleAPFloat &operator=(const DoubleAPFloat &RHS); |
620 | | |
621 | 0 | DoubleAPFloat &operator=(DoubleAPFloat &&RHS) { |
622 | 0 | if (this != &RHS) { |
623 | 0 | this->~DoubleAPFloat(); |
624 | 0 | new (this) DoubleAPFloat(std::move(RHS)); |
625 | 0 | } |
626 | 0 | return *this; |
627 | 0 | } |
628 | | |
629 | 0 | bool needsCleanup() const { return Floats != nullptr; } |
630 | | |
631 | 0 | APFloat &getFirst() { return Floats[0]; } |
632 | 0 | const APFloat &getFirst() const { return Floats[0]; } |
633 | 0 | APFloat &getSecond() { return Floats[1]; } |
634 | 0 | const APFloat &getSecond() const { return Floats[1]; } |
635 | | |
636 | | opStatus add(const DoubleAPFloat &RHS, roundingMode RM); |
637 | | opStatus subtract(const DoubleAPFloat &RHS, roundingMode RM); |
638 | | opStatus multiply(const DoubleAPFloat &RHS, roundingMode RM); |
639 | | opStatus divide(const DoubleAPFloat &RHS, roundingMode RM); |
640 | | opStatus remainder(const DoubleAPFloat &RHS); |
641 | | opStatus mod(const DoubleAPFloat &RHS); |
642 | | opStatus fusedMultiplyAdd(const DoubleAPFloat &Multiplicand, |
643 | | const DoubleAPFloat &Addend, roundingMode RM); |
644 | | opStatus roundToIntegral(roundingMode RM); |
645 | | void changeSign(); |
646 | | cmpResult compareAbsoluteValue(const DoubleAPFloat &RHS) const; |
647 | | |
648 | | fltCategory getCategory() const; |
649 | | bool isNegative() const; |
650 | | |
651 | | void makeInf(bool Neg); |
652 | | void makeZero(bool Neg); |
653 | | void makeLargest(bool Neg); |
654 | | void makeSmallest(bool Neg); |
655 | | void makeSmallestNormalized(bool Neg); |
656 | | void makeNaN(bool SNaN, bool Neg, const APInt *fill); |
657 | | |
658 | | cmpResult compare(const DoubleAPFloat &RHS) const; |
659 | | bool bitwiseIsEqual(const DoubleAPFloat &RHS) const; |
660 | | APInt bitcastToAPInt() const; |
661 | | Expected<opStatus> convertFromString(StringRef, roundingMode); |
662 | | opStatus next(bool nextDown); |
663 | | |
664 | | opStatus convertToInteger(MutableArrayRef<integerPart> Input, |
665 | | unsigned int Width, bool IsSigned, roundingMode RM, |
666 | | bool *IsExact) const; |
667 | | opStatus convertFromAPInt(const APInt &Input, bool IsSigned, roundingMode RM); |
668 | | opStatus convertFromSignExtendedInteger(const integerPart *Input, |
669 | | unsigned int InputSize, bool IsSigned, |
670 | | roundingMode RM); |
671 | | opStatus convertFromZeroExtendedInteger(const integerPart *Input, |
672 | | unsigned int InputSize, bool IsSigned, |
673 | | roundingMode RM); |
674 | | unsigned int convertToHexString(char *DST, unsigned int HexDigits, |
675 | | bool UpperCase, roundingMode RM) const; |
676 | | |
677 | | bool isDenormal() const; |
678 | | bool isSmallest() const; |
679 | | bool isLargest() const; |
680 | | bool isInteger() const; |
681 | | |
682 | | void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision, |
683 | | unsigned FormatMaxPadding, bool TruncateZero = true) const; |
684 | | |
685 | | bool getExactInverse(APFloat *inv) const; |
686 | | |
687 | | friend int ilogb(const DoubleAPFloat &Arg); |
688 | | friend DoubleAPFloat scalbn(DoubleAPFloat X, int Exp, roundingMode); |
689 | | friend DoubleAPFloat frexp(const DoubleAPFloat &X, int &Exp, roundingMode); |
690 | | friend hash_code hash_value(const DoubleAPFloat &Arg); |
691 | | }; |
692 | | |
693 | | hash_code hash_value(const DoubleAPFloat &Arg); |
694 | | |
695 | | } // End detail namespace |
696 | | |
697 | | // This is a interface class that is currently forwarding functionalities from |
698 | | // detail::IEEEFloat. |
699 | | class APFloat : public APFloatBase { |
700 | | typedef detail::IEEEFloat IEEEFloat; |
701 | | typedef detail::DoubleAPFloat DoubleAPFloat; |
702 | | |
703 | | static_assert(std::is_standard_layout<IEEEFloat>::value, ""); |
704 | | |
705 | | union Storage { |
706 | | const fltSemantics *semantics; |
707 | | IEEEFloat IEEE; |
708 | | DoubleAPFloat Double; |
709 | | |
710 | | explicit Storage(IEEEFloat F, const fltSemantics &S); |
711 | | explicit Storage(DoubleAPFloat F, const fltSemantics &S) |
712 | 0 | : Double(std::move(F)) { |
713 | 0 | assert(&S == &PPCDoubleDouble()); |
714 | 0 | } |
715 | | |
716 | | template <typename... ArgTypes> |
717 | 0 | Storage(const fltSemantics &Semantics, ArgTypes &&... Args) { |
718 | 0 | if (usesLayout<IEEEFloat>(Semantics)) { |
719 | 0 | new (&IEEE) IEEEFloat(Semantics, std::forward<ArgTypes>(Args)...); |
720 | 0 | return; |
721 | 0 | } |
722 | 0 | if (usesLayout<DoubleAPFloat>(Semantics)) { |
723 | 0 | new (&Double) DoubleAPFloat(Semantics, std::forward<ArgTypes>(Args)...); |
724 | 0 | return; |
725 | 0 | } |
726 | 0 | llvm_unreachable("Unexpected semantics"); |
727 | 0 | } Unexecuted instantiation: _ZN4llvm7APFloat7StorageC2IJNS_11APFloatBase16uninitializedTagEEEERKNS_12fltSemanticsEDpOT_ Unexecuted instantiation: _ZN4llvm7APFloat7StorageC2IJRmEEERKNS_12fltSemanticsEDpOT_ Unexecuted instantiation: _ZN4llvm7APFloat7StorageC2IJRKNS_5APIntEEEERKNS_12fltSemanticsEDpOT_ Unexecuted instantiation: _ZN4llvm7APFloat7StorageC2IJEEERKNS_12fltSemanticsEDpOT_ |
728 | | |
729 | 0 | ~Storage() { |
730 | 0 | if (usesLayout<IEEEFloat>(*semantics)) { |
731 | 0 | IEEE.~IEEEFloat(); |
732 | 0 | return; |
733 | 0 | } |
734 | 0 | if (usesLayout<DoubleAPFloat>(*semantics)) { |
735 | 0 | Double.~DoubleAPFloat(); |
736 | 0 | return; |
737 | 0 | } |
738 | 0 | llvm_unreachable("Unexpected semantics"); |
739 | 0 | } |
740 | | |
741 | 0 | Storage(const Storage &RHS) { |
742 | 0 | if (usesLayout<IEEEFloat>(*RHS.semantics)) { |
743 | 0 | new (this) IEEEFloat(RHS.IEEE); |
744 | 0 | return; |
745 | 0 | } |
746 | 0 | if (usesLayout<DoubleAPFloat>(*RHS.semantics)) { |
747 | 0 | new (this) DoubleAPFloat(RHS.Double); |
748 | 0 | return; |
749 | 0 | } |
750 | 0 | llvm_unreachable("Unexpected semantics"); |
751 | 0 | } |
752 | | |
753 | 0 | Storage(Storage &&RHS) { |
754 | 0 | if (usesLayout<IEEEFloat>(*RHS.semantics)) { |
755 | 0 | new (this) IEEEFloat(std::move(RHS.IEEE)); |
756 | 0 | return; |
757 | 0 | } |
758 | 0 | if (usesLayout<DoubleAPFloat>(*RHS.semantics)) { |
759 | 0 | new (this) DoubleAPFloat(std::move(RHS.Double)); |
760 | 0 | return; |
761 | 0 | } |
762 | 0 | llvm_unreachable("Unexpected semantics"); |
763 | 0 | } |
764 | | |
765 | 0 | Storage &operator=(const Storage &RHS) { |
766 | 0 | if (usesLayout<IEEEFloat>(*semantics) && |
767 | 0 | usesLayout<IEEEFloat>(*RHS.semantics)) { |
768 | 0 | IEEE = RHS.IEEE; |
769 | 0 | } else if (usesLayout<DoubleAPFloat>(*semantics) && |
770 | 0 | usesLayout<DoubleAPFloat>(*RHS.semantics)) { |
771 | 0 | Double = RHS.Double; |
772 | 0 | } else if (this != &RHS) { |
773 | 0 | this->~Storage(); |
774 | 0 | new (this) Storage(RHS); |
775 | 0 | } |
776 | 0 | return *this; |
777 | 0 | } |
778 | | |
779 | 0 | Storage &operator=(Storage &&RHS) { |
780 | 0 | if (usesLayout<IEEEFloat>(*semantics) && |
781 | 0 | usesLayout<IEEEFloat>(*RHS.semantics)) { |
782 | 0 | IEEE = std::move(RHS.IEEE); |
783 | 0 | } else if (usesLayout<DoubleAPFloat>(*semantics) && |
784 | 0 | usesLayout<DoubleAPFloat>(*RHS.semantics)) { |
785 | 0 | Double = std::move(RHS.Double); |
786 | 0 | } else if (this != &RHS) { |
787 | 0 | this->~Storage(); |
788 | 0 | new (this) Storage(std::move(RHS)); |
789 | 0 | } |
790 | 0 | return *this; |
791 | 0 | } |
792 | | } U; |
793 | | |
794 | 0 | template <typename T> static bool usesLayout(const fltSemantics &Semantics) { |
795 | 0 | static_assert(std::is_same<T, IEEEFloat>::value || |
796 | 0 | std::is_same<T, DoubleAPFloat>::value, ""); |
797 | 0 | if (std::is_same<T, DoubleAPFloat>::value) { |
798 | 0 | return &Semantics == &PPCDoubleDouble(); |
799 | 0 | } |
800 | 0 | return &Semantics != &PPCDoubleDouble(); |
801 | 0 | } Unexecuted instantiation: _ZN4llvm7APFloat10usesLayoutINS_6detail9IEEEFloatEEEbRKNS_12fltSemanticsE Unexecuted instantiation: _ZN4llvm7APFloat10usesLayoutINS_6detail13DoubleAPFloatEEEbRKNS_12fltSemanticsE |
802 | | |
803 | 0 | IEEEFloat &getIEEE() { |
804 | 0 | if (usesLayout<IEEEFloat>(*U.semantics)) |
805 | 0 | return U.IEEE; |
806 | 0 | if (usesLayout<DoubleAPFloat>(*U.semantics)) |
807 | 0 | return U.Double.getFirst().U.IEEE; |
808 | 0 | llvm_unreachable("Unexpected semantics"); |
809 | 0 | } |
810 | | |
811 | 0 | const IEEEFloat &getIEEE() const { |
812 | 0 | if (usesLayout<IEEEFloat>(*U.semantics)) |
813 | 0 | return U.IEEE; |
814 | 0 | if (usesLayout<DoubleAPFloat>(*U.semantics)) |
815 | 0 | return U.Double.getFirst().U.IEEE; |
816 | 0 | llvm_unreachable("Unexpected semantics"); |
817 | 0 | } |
818 | | |
819 | 0 | void makeZero(bool Neg) { APFLOAT_DISPATCH_ON_SEMANTICS(makeZero(Neg)); } |
820 | | |
821 | 0 | void makeInf(bool Neg) { APFLOAT_DISPATCH_ON_SEMANTICS(makeInf(Neg)); } |
822 | | |
823 | 0 | void makeNaN(bool SNaN, bool Neg, const APInt *fill) { |
824 | 0 | APFLOAT_DISPATCH_ON_SEMANTICS(makeNaN(SNaN, Neg, fill)); |
825 | 0 | } |
826 | | |
827 | 0 | void makeLargest(bool Neg) { |
828 | 0 | APFLOAT_DISPATCH_ON_SEMANTICS(makeLargest(Neg)); |
829 | 0 | } |
830 | | |
831 | 0 | void makeSmallest(bool Neg) { |
832 | 0 | APFLOAT_DISPATCH_ON_SEMANTICS(makeSmallest(Neg)); |
833 | 0 | } |
834 | | |
835 | 0 | void makeSmallestNormalized(bool Neg) { |
836 | 0 | APFLOAT_DISPATCH_ON_SEMANTICS(makeSmallestNormalized(Neg)); |
837 | 0 | } |
838 | | |
839 | | // FIXME: This is due to clang 3.3 (or older version) always checks for the |
840 | | // default constructor in an array aggregate initialization, even if no |
841 | | // elements in the array is default initialized. |
842 | 0 | APFloat() : U(IEEEdouble()) { |
843 | 0 | llvm_unreachable("This is a workaround for old clang."); |
844 | 0 | } |
845 | | |
846 | 0 | explicit APFloat(IEEEFloat F, const fltSemantics &S) : U(std::move(F), S) {} |
847 | | explicit APFloat(DoubleAPFloat F, const fltSemantics &S) |
848 | 0 | : U(std::move(F), S) {} |
849 | | |
850 | 0 | cmpResult compareAbsoluteValue(const APFloat &RHS) const { |
851 | 0 | assert(&getSemantics() == &RHS.getSemantics() && |
852 | 0 | "Should only compare APFloats with the same semantics"); |
853 | 0 | if (usesLayout<IEEEFloat>(getSemantics())) |
854 | 0 | return U.IEEE.compareAbsoluteValue(RHS.U.IEEE); |
855 | 0 | if (usesLayout<DoubleAPFloat>(getSemantics())) |
856 | 0 | return U.Double.compareAbsoluteValue(RHS.U.Double); |
857 | 0 | llvm_unreachable("Unexpected semantics"); |
858 | 0 | } |
859 | | |
860 | | public: |
861 | 0 | APFloat(const fltSemantics &Semantics) : U(Semantics) {} |
862 | | APFloat(const fltSemantics &Semantics, StringRef S); |
863 | 0 | APFloat(const fltSemantics &Semantics, integerPart I) : U(Semantics, I) {} |
864 | | template <typename T, |
865 | | typename = std::enable_if_t<std::is_floating_point<T>::value>> |
866 | | APFloat(const fltSemantics &Semantics, T V) = delete; |
867 | | // TODO: Remove this constructor. This isn't faster than the first one. |
868 | | APFloat(const fltSemantics &Semantics, uninitializedTag) |
869 | 0 | : U(Semantics, uninitialized) {} |
870 | 0 | APFloat(const fltSemantics &Semantics, const APInt &I) : U(Semantics, I) {} |
871 | 0 | explicit APFloat(double d) : U(IEEEFloat(d), IEEEdouble()) {} |
872 | 0 | explicit APFloat(float f) : U(IEEEFloat(f), IEEEsingle()) {} |
873 | 0 | APFloat(const APFloat &RHS) = default; |
874 | 0 | APFloat(APFloat &&RHS) = default; |
875 | | |
876 | 0 | ~APFloat() = default; |
877 | | |
878 | 0 | bool needsCleanup() const { APFLOAT_DISPATCH_ON_SEMANTICS(needsCleanup()); } |
879 | | |
880 | | /// Factory for Positive and Negative Zero. |
881 | | /// |
882 | | /// \param Negative True iff the number should be negative. |
883 | 0 | static APFloat getZero(const fltSemantics &Sem, bool Negative = false) { |
884 | 0 | APFloat Val(Sem, uninitialized); |
885 | 0 | Val.makeZero(Negative); |
886 | 0 | return Val; |
887 | 0 | } |
888 | | |
889 | | /// Factory for Positive and Negative Infinity. |
890 | | /// |
891 | | /// \param Negative True iff the number should be negative. |
892 | 0 | static APFloat getInf(const fltSemantics &Sem, bool Negative = false) { |
893 | 0 | APFloat Val(Sem, uninitialized); |
894 | 0 | Val.makeInf(Negative); |
895 | 0 | return Val; |
896 | 0 | } |
897 | | |
898 | | /// Factory for NaN values. |
899 | | /// |
900 | | /// \param Negative - True iff the NaN generated should be negative. |
901 | | /// \param payload - The unspecified fill bits for creating the NaN, 0 by |
902 | | /// default. The value is truncated as necessary. |
903 | | static APFloat getNaN(const fltSemantics &Sem, bool Negative = false, |
904 | 0 | uint64_t payload = 0) { |
905 | 0 | if (payload) { |
906 | 0 | APInt intPayload(64, payload); |
907 | 0 | return getQNaN(Sem, Negative, &intPayload); |
908 | 0 | } else { |
909 | 0 | return getQNaN(Sem, Negative, nullptr); |
910 | 0 | } |
911 | 0 | } |
912 | | |
913 | | /// Factory for QNaN values. |
914 | | static APFloat getQNaN(const fltSemantics &Sem, bool Negative = false, |
915 | 0 | const APInt *payload = nullptr) { |
916 | 0 | APFloat Val(Sem, uninitialized); |
917 | 0 | Val.makeNaN(false, Negative, payload); |
918 | 0 | return Val; |
919 | 0 | } |
920 | | |
921 | | /// Factory for SNaN values. |
922 | | static APFloat getSNaN(const fltSemantics &Sem, bool Negative = false, |
923 | 0 | const APInt *payload = nullptr) { |
924 | 0 | APFloat Val(Sem, uninitialized); |
925 | 0 | Val.makeNaN(true, Negative, payload); |
926 | 0 | return Val; |
927 | 0 | } |
928 | | |
929 | | /// Returns the largest finite number in the given semantics. |
930 | | /// |
931 | | /// \param Negative - True iff the number should be negative |
932 | 0 | static APFloat getLargest(const fltSemantics &Sem, bool Negative = false) { |
933 | 0 | APFloat Val(Sem, uninitialized); |
934 | 0 | Val.makeLargest(Negative); |
935 | 0 | return Val; |
936 | 0 | } |
937 | | |
938 | | /// Returns the smallest (by magnitude) finite number in the given semantics. |
939 | | /// Might be denormalized, which implies a relative loss of precision. |
940 | | /// |
941 | | /// \param Negative - True iff the number should be negative |
942 | 0 | static APFloat getSmallest(const fltSemantics &Sem, bool Negative = false) { |
943 | 0 | APFloat Val(Sem, uninitialized); |
944 | 0 | Val.makeSmallest(Negative); |
945 | 0 | return Val; |
946 | 0 | } |
947 | | |
948 | | /// Returns the smallest (by magnitude) normalized finite number in the given |
949 | | /// semantics. |
950 | | /// |
951 | | /// \param Negative - True iff the number should be negative |
952 | | static APFloat getSmallestNormalized(const fltSemantics &Sem, |
953 | 0 | bool Negative = false) { |
954 | 0 | APFloat Val(Sem, uninitialized); |
955 | 0 | Val.makeSmallestNormalized(Negative); |
956 | 0 | return Val; |
957 | 0 | } |
958 | | |
959 | | /// Returns a float which is bitcasted from an all one value int. |
960 | | /// |
961 | | /// \param Semantics - type float semantics |
962 | | /// \param BitWidth - Select float type |
963 | | static APFloat getAllOnesValue(const fltSemantics &Semantics, |
964 | | unsigned BitWidth); |
965 | | |
966 | | /// Used to insert APFloat objects, or objects that contain APFloat objects, |
967 | | /// into FoldingSets. |
968 | | void Profile(FoldingSetNodeID &NID) const; |
969 | | |
970 | 0 | opStatus add(const APFloat &RHS, roundingMode RM) { |
971 | 0 | assert(&getSemantics() == &RHS.getSemantics() && |
972 | 0 | "Should only call on two APFloats with the same semantics"); |
973 | 0 | if (usesLayout<IEEEFloat>(getSemantics())) |
974 | 0 | return U.IEEE.add(RHS.U.IEEE, RM); |
975 | 0 | if (usesLayout<DoubleAPFloat>(getSemantics())) |
976 | 0 | return U.Double.add(RHS.U.Double, RM); |
977 | 0 | llvm_unreachable("Unexpected semantics"); |
978 | 0 | } |
979 | 0 | opStatus subtract(const APFloat &RHS, roundingMode RM) { |
980 | 0 | assert(&getSemantics() == &RHS.getSemantics() && |
981 | 0 | "Should only call on two APFloats with the same semantics"); |
982 | 0 | if (usesLayout<IEEEFloat>(getSemantics())) |
983 | 0 | return U.IEEE.subtract(RHS.U.IEEE, RM); |
984 | 0 | if (usesLayout<DoubleAPFloat>(getSemantics())) |
985 | 0 | return U.Double.subtract(RHS.U.Double, RM); |
986 | 0 | llvm_unreachable("Unexpected semantics"); |
987 | 0 | } |
988 | 0 | opStatus multiply(const APFloat &RHS, roundingMode RM) { |
989 | 0 | assert(&getSemantics() == &RHS.getSemantics() && |
990 | 0 | "Should only call on two APFloats with the same semantics"); |
991 | 0 | if (usesLayout<IEEEFloat>(getSemantics())) |
992 | 0 | return U.IEEE.multiply(RHS.U.IEEE, RM); |
993 | 0 | if (usesLayout<DoubleAPFloat>(getSemantics())) |
994 | 0 | return U.Double.multiply(RHS.U.Double, RM); |
995 | 0 | llvm_unreachable("Unexpected semantics"); |
996 | 0 | } |
997 | 0 | opStatus divide(const APFloat &RHS, roundingMode RM) { |
998 | 0 | assert(&getSemantics() == &RHS.getSemantics() && |
999 | 0 | "Should only call on two APFloats with the same semantics"); |
1000 | 0 | if (usesLayout<IEEEFloat>(getSemantics())) |
1001 | 0 | return U.IEEE.divide(RHS.U.IEEE, RM); |
1002 | 0 | if (usesLayout<DoubleAPFloat>(getSemantics())) |
1003 | 0 | return U.Double.divide(RHS.U.Double, RM); |
1004 | 0 | llvm_unreachable("Unexpected semantics"); |
1005 | 0 | } |
1006 | 0 | opStatus remainder(const APFloat &RHS) { |
1007 | 0 | assert(&getSemantics() == &RHS.getSemantics() && |
1008 | 0 | "Should only call on two APFloats with the same semantics"); |
1009 | 0 | if (usesLayout<IEEEFloat>(getSemantics())) |
1010 | 0 | return U.IEEE.remainder(RHS.U.IEEE); |
1011 | 0 | if (usesLayout<DoubleAPFloat>(getSemantics())) |
1012 | 0 | return U.Double.remainder(RHS.U.Double); |
1013 | 0 | llvm_unreachable("Unexpected semantics"); |
1014 | 0 | } |
1015 | 0 | opStatus mod(const APFloat &RHS) { |
1016 | 0 | assert(&getSemantics() == &RHS.getSemantics() && |
1017 | 0 | "Should only call on two APFloats with the same semantics"); |
1018 | 0 | if (usesLayout<IEEEFloat>(getSemantics())) |
1019 | 0 | return U.IEEE.mod(RHS.U.IEEE); |
1020 | 0 | if (usesLayout<DoubleAPFloat>(getSemantics())) |
1021 | 0 | return U.Double.mod(RHS.U.Double); |
1022 | 0 | llvm_unreachable("Unexpected semantics"); |
1023 | 0 | } |
1024 | | opStatus fusedMultiplyAdd(const APFloat &Multiplicand, const APFloat &Addend, |
1025 | 0 | roundingMode RM) { |
1026 | 0 | assert(&getSemantics() == &Multiplicand.getSemantics() && |
1027 | 0 | "Should only call on APFloats with the same semantics"); |
1028 | 0 | assert(&getSemantics() == &Addend.getSemantics() && |
1029 | 0 | "Should only call on APFloats with the same semantics"); |
1030 | 0 | if (usesLayout<IEEEFloat>(getSemantics())) |
1031 | 0 | return U.IEEE.fusedMultiplyAdd(Multiplicand.U.IEEE, Addend.U.IEEE, RM); |
1032 | 0 | if (usesLayout<DoubleAPFloat>(getSemantics())) |
1033 | 0 | return U.Double.fusedMultiplyAdd(Multiplicand.U.Double, Addend.U.Double, |
1034 | 0 | RM); |
1035 | 0 | llvm_unreachable("Unexpected semantics"); |
1036 | 0 | } |
1037 | 0 | opStatus roundToIntegral(roundingMode RM) { |
1038 | 0 | APFLOAT_DISPATCH_ON_SEMANTICS(roundToIntegral(RM)); |
1039 | 0 | } |
1040 | | |
1041 | | // TODO: bool parameters are not readable and a source of bugs. |
1042 | | // Do something. |
1043 | 0 | opStatus next(bool nextDown) { |
1044 | 0 | APFLOAT_DISPATCH_ON_SEMANTICS(next(nextDown)); |
1045 | 0 | } |
1046 | | |
1047 | | /// Negate an APFloat. |
1048 | 0 | APFloat operator-() const { |
1049 | 0 | APFloat Result(*this); |
1050 | 0 | Result.changeSign(); |
1051 | 0 | return Result; |
1052 | 0 | } |
1053 | | |
1054 | | /// Add two APFloats, rounding ties to the nearest even. |
1055 | | /// No error checking. |
1056 | 0 | APFloat operator+(const APFloat &RHS) const { |
1057 | 0 | APFloat Result(*this); |
1058 | 0 | (void)Result.add(RHS, rmNearestTiesToEven); |
1059 | 0 | return Result; |
1060 | 0 | } |
1061 | | |
1062 | | /// Subtract two APFloats, rounding ties to the nearest even. |
1063 | | /// No error checking. |
1064 | 0 | APFloat operator-(const APFloat &RHS) const { |
1065 | 0 | APFloat Result(*this); |
1066 | 0 | (void)Result.subtract(RHS, rmNearestTiesToEven); |
1067 | 0 | return Result; |
1068 | 0 | } |
1069 | | |
1070 | | /// Multiply two APFloats, rounding ties to the nearest even. |
1071 | | /// No error checking. |
1072 | 0 | APFloat operator*(const APFloat &RHS) const { |
1073 | 0 | APFloat Result(*this); |
1074 | 0 | (void)Result.multiply(RHS, rmNearestTiesToEven); |
1075 | 0 | return Result; |
1076 | 0 | } |
1077 | | |
1078 | | /// Divide the first APFloat by the second, rounding ties to the nearest even. |
1079 | | /// No error checking. |
1080 | 0 | APFloat operator/(const APFloat &RHS) const { |
1081 | 0 | APFloat Result(*this); |
1082 | 0 | (void)Result.divide(RHS, rmNearestTiesToEven); |
1083 | 0 | return Result; |
1084 | 0 | } |
1085 | | |
1086 | 0 | void changeSign() { APFLOAT_DISPATCH_ON_SEMANTICS(changeSign()); } |
1087 | 0 | void clearSign() { |
1088 | 0 | if (isNegative()) |
1089 | 0 | changeSign(); |
1090 | 0 | } |
1091 | 0 | void copySign(const APFloat &RHS) { |
1092 | 0 | if (isNegative() != RHS.isNegative()) |
1093 | 0 | changeSign(); |
1094 | 0 | } |
1095 | | |
1096 | | /// A static helper to produce a copy of an APFloat value with its sign |
1097 | | /// copied from some other APFloat. |
1098 | 0 | static APFloat copySign(APFloat Value, const APFloat &Sign) { |
1099 | 0 | Value.copySign(Sign); |
1100 | 0 | return Value; |
1101 | 0 | } |
1102 | | |
1103 | | opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, |
1104 | | bool *losesInfo); |
1105 | | opStatus convertToInteger(MutableArrayRef<integerPart> Input, |
1106 | | unsigned int Width, bool IsSigned, roundingMode RM, |
1107 | 0 | bool *IsExact) const { |
1108 | 0 | APFLOAT_DISPATCH_ON_SEMANTICS( |
1109 | 0 | convertToInteger(Input, Width, IsSigned, RM, IsExact)); |
1110 | 0 | } |
1111 | | opStatus convertToInteger(APSInt &Result, roundingMode RM, |
1112 | | bool *IsExact) const; |
1113 | | opStatus convertFromAPInt(const APInt &Input, bool IsSigned, |
1114 | 0 | roundingMode RM) { |
1115 | 0 | APFLOAT_DISPATCH_ON_SEMANTICS(convertFromAPInt(Input, IsSigned, RM)); |
1116 | 0 | } |
1117 | | opStatus convertFromSignExtendedInteger(const integerPart *Input, |
1118 | | unsigned int InputSize, bool IsSigned, |
1119 | 0 | roundingMode RM) { |
1120 | 0 | APFLOAT_DISPATCH_ON_SEMANTICS( |
1121 | 0 | convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM)); |
1122 | 0 | } |
1123 | | opStatus convertFromZeroExtendedInteger(const integerPart *Input, |
1124 | | unsigned int InputSize, bool IsSigned, |
1125 | 0 | roundingMode RM) { |
1126 | 0 | APFLOAT_DISPATCH_ON_SEMANTICS( |
1127 | 0 | convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM)); |
1128 | 0 | } |
1129 | | Expected<opStatus> convertFromString(StringRef, roundingMode); |
1130 | 0 | APInt bitcastToAPInt() const { |
1131 | 0 | APFLOAT_DISPATCH_ON_SEMANTICS(bitcastToAPInt()); |
1132 | 0 | } |
1133 | 0 | double convertToDouble() const { return getIEEE().convertToDouble(); } |
1134 | 0 | float convertToFloat() const { return getIEEE().convertToFloat(); } |
1135 | | |
1136 | 0 | bool operator==(const APFloat &RHS) const { return compare(RHS) == cmpEqual; } |
1137 | | |
1138 | 0 | bool operator!=(const APFloat &RHS) const { return compare(RHS) != cmpEqual; } |
1139 | | |
1140 | 0 | bool operator<(const APFloat &RHS) const { |
1141 | 0 | return compare(RHS) == cmpLessThan; |
1142 | 0 | } |
1143 | | |
1144 | 0 | bool operator>(const APFloat &RHS) const { |
1145 | 0 | return compare(RHS) == cmpGreaterThan; |
1146 | 0 | } |
1147 | | |
1148 | 0 | bool operator<=(const APFloat &RHS) const { |
1149 | 0 | cmpResult Res = compare(RHS); |
1150 | 0 | return Res == cmpLessThan || Res == cmpEqual; |
1151 | 0 | } |
1152 | | |
1153 | 0 | bool operator>=(const APFloat &RHS) const { |
1154 | 0 | cmpResult Res = compare(RHS); |
1155 | 0 | return Res == cmpGreaterThan || Res == cmpEqual; |
1156 | 0 | } |
1157 | | |
1158 | 0 | cmpResult compare(const APFloat &RHS) const { |
1159 | 0 | assert(&getSemantics() == &RHS.getSemantics() && |
1160 | 0 | "Should only compare APFloats with the same semantics"); |
1161 | 0 | if (usesLayout<IEEEFloat>(getSemantics())) |
1162 | 0 | return U.IEEE.compare(RHS.U.IEEE); |
1163 | 0 | if (usesLayout<DoubleAPFloat>(getSemantics())) |
1164 | 0 | return U.Double.compare(RHS.U.Double); |
1165 | 0 | llvm_unreachable("Unexpected semantics"); |
1166 | 0 | } |
1167 | | |
1168 | 0 | bool bitwiseIsEqual(const APFloat &RHS) const { |
1169 | 0 | if (&getSemantics() != &RHS.getSemantics()) |
1170 | 0 | return false; |
1171 | 0 | if (usesLayout<IEEEFloat>(getSemantics())) |
1172 | 0 | return U.IEEE.bitwiseIsEqual(RHS.U.IEEE); |
1173 | 0 | if (usesLayout<DoubleAPFloat>(getSemantics())) |
1174 | 0 | return U.Double.bitwiseIsEqual(RHS.U.Double); |
1175 | 0 | llvm_unreachable("Unexpected semantics"); |
1176 | 0 | } |
1177 | | |
1178 | | /// We don't rely on operator== working on double values, as |
1179 | | /// it returns true for things that are clearly not equal, like -0.0 and 0.0. |
1180 | | /// As such, this method can be used to do an exact bit-for-bit comparison of |
1181 | | /// two floating point values. |
1182 | | /// |
1183 | | /// We leave the version with the double argument here because it's just so |
1184 | | /// convenient to write "2.0" and the like. Without this function we'd |
1185 | | /// have to duplicate its logic everywhere it's called. |
1186 | 0 | bool isExactlyValue(double V) const { |
1187 | 0 | bool ignored; |
1188 | 0 | APFloat Tmp(V); |
1189 | 0 | Tmp.convert(getSemantics(), APFloat::rmNearestTiesToEven, &ignored); |
1190 | 0 | return bitwiseIsEqual(Tmp); |
1191 | 0 | } |
1192 | | |
1193 | | unsigned int convertToHexString(char *DST, unsigned int HexDigits, |
1194 | 0 | bool UpperCase, roundingMode RM) const { |
1195 | 0 | APFLOAT_DISPATCH_ON_SEMANTICS( |
1196 | 0 | convertToHexString(DST, HexDigits, UpperCase, RM)); |
1197 | 0 | } |
1198 | | |
1199 | 0 | bool isZero() const { return getCategory() == fcZero; } |
1200 | 0 | bool isInfinity() const { return getCategory() == fcInfinity; } |
1201 | 0 | bool isNaN() const { return getCategory() == fcNaN; } |
1202 | | |
1203 | 0 | bool isNegative() const { return getIEEE().isNegative(); } |
1204 | 0 | bool isDenormal() const { APFLOAT_DISPATCH_ON_SEMANTICS(isDenormal()); } |
1205 | 0 | bool isSignaling() const { return getIEEE().isSignaling(); } |
1206 | | |
1207 | 0 | bool isNormal() const { return !isDenormal() && isFiniteNonZero(); } |
1208 | 0 | bool isFinite() const { return !isNaN() && !isInfinity(); } |
1209 | | |
1210 | 0 | fltCategory getCategory() const { return getIEEE().getCategory(); } |
1211 | 0 | const fltSemantics &getSemantics() const { return *U.semantics; } |
1212 | 0 | bool isNonZero() const { return !isZero(); } |
1213 | 0 | bool isFiniteNonZero() const { return isFinite() && !isZero(); } |
1214 | 0 | bool isPosZero() const { return isZero() && !isNegative(); } |
1215 | 0 | bool isNegZero() const { return isZero() && isNegative(); } |
1216 | 0 | bool isSmallest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isSmallest()); } |
1217 | 0 | bool isLargest() const { APFLOAT_DISPATCH_ON_SEMANTICS(isLargest()); } |
1218 | 0 | bool isInteger() const { APFLOAT_DISPATCH_ON_SEMANTICS(isInteger()); } |
1219 | | |
1220 | 0 | APFloat &operator=(const APFloat &RHS) = default; |
1221 | 0 | APFloat &operator=(APFloat &&RHS) = default; |
1222 | | |
1223 | | void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0, |
1224 | 0 | unsigned FormatMaxPadding = 3, bool TruncateZero = true) const { |
1225 | 0 | APFLOAT_DISPATCH_ON_SEMANTICS( |
1226 | 0 | toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero)); |
1227 | 0 | } |
1228 | | |
1229 | | void print(raw_ostream &) const; |
1230 | | void dump() const; |
1231 | | |
1232 | 0 | bool getExactInverse(APFloat *inv) const { |
1233 | 0 | APFLOAT_DISPATCH_ON_SEMANTICS(getExactInverse(inv)); |
1234 | 0 | } |
1235 | | |
1236 | | friend hash_code hash_value(const APFloat &Arg); |
1237 | 0 | friend int ilogb(const APFloat &Arg) { return ilogb(Arg.getIEEE()); } |
1238 | | friend APFloat scalbn(APFloat X, int Exp, roundingMode RM); |
1239 | | friend APFloat frexp(const APFloat &X, int &Exp, roundingMode RM); |
1240 | | friend IEEEFloat; |
1241 | | friend DoubleAPFloat; |
1242 | | }; |
1243 | | |
1244 | | /// See friend declarations above. |
1245 | | /// |
1246 | | /// These additional declarations are required in order to compile LLVM with IBM |
1247 | | /// xlC compiler. |
1248 | | hash_code hash_value(const APFloat &Arg); |
1249 | 0 | inline APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM) { |
1250 | 0 | if (APFloat::usesLayout<detail::IEEEFloat>(X.getSemantics())) |
1251 | 0 | return APFloat(scalbn(X.U.IEEE, Exp, RM), X.getSemantics()); |
1252 | 0 | if (APFloat::usesLayout<detail::DoubleAPFloat>(X.getSemantics())) |
1253 | 0 | return APFloat(scalbn(X.U.Double, Exp, RM), X.getSemantics()); |
1254 | 0 | llvm_unreachable("Unexpected semantics"); |
1255 | 0 | } |
1256 | | |
1257 | | /// Equivalent of C standard library function. |
1258 | | /// |
1259 | | /// While the C standard says Exp is an unspecified value for infinity and nan, |
1260 | | /// this returns INT_MAX for infinities, and INT_MIN for NaNs. |
1261 | 0 | inline APFloat frexp(const APFloat &X, int &Exp, APFloat::roundingMode RM) { |
1262 | 0 | if (APFloat::usesLayout<detail::IEEEFloat>(X.getSemantics())) |
1263 | 0 | return APFloat(frexp(X.U.IEEE, Exp, RM), X.getSemantics()); |
1264 | 0 | if (APFloat::usesLayout<detail::DoubleAPFloat>(X.getSemantics())) |
1265 | 0 | return APFloat(frexp(X.U.Double, Exp, RM), X.getSemantics()); |
1266 | 0 | llvm_unreachable("Unexpected semantics"); |
1267 | 0 | } |
1268 | | /// Returns the absolute value of the argument. |
1269 | 0 | inline APFloat abs(APFloat X) { |
1270 | 0 | X.clearSign(); |
1271 | 0 | return X; |
1272 | 0 | } |
1273 | | |
1274 | | /// Returns the negated value of the argument. |
1275 | 0 | inline APFloat neg(APFloat X) { |
1276 | 0 | X.changeSign(); |
1277 | 0 | return X; |
1278 | 0 | } |
1279 | | |
1280 | | /// Implements IEEE minNum semantics. Returns the smaller of the 2 arguments if |
1281 | | /// both are not NaN. If either argument is a NaN, returns the other argument. |
1282 | | LLVM_READONLY |
1283 | 0 | inline APFloat minnum(const APFloat &A, const APFloat &B) { |
1284 | 0 | if (A.isNaN()) |
1285 | 0 | return B; |
1286 | 0 | if (B.isNaN()) |
1287 | 0 | return A; |
1288 | 0 | return B < A ? B : A; |
1289 | 0 | } |
1290 | | |
1291 | | /// Implements IEEE maxNum semantics. Returns the larger of the 2 arguments if |
1292 | | /// both are not NaN. If either argument is a NaN, returns the other argument. |
1293 | | LLVM_READONLY |
1294 | 0 | inline APFloat maxnum(const APFloat &A, const APFloat &B) { |
1295 | 0 | if (A.isNaN()) |
1296 | 0 | return B; |
1297 | 0 | if (B.isNaN()) |
1298 | 0 | return A; |
1299 | 0 | return A < B ? B : A; |
1300 | 0 | } |
1301 | | |
1302 | | /// Implements IEEE 754-2018 minimum semantics. Returns the smaller of 2 |
1303 | | /// arguments, propagating NaNs and treating -0 as less than +0. |
1304 | | LLVM_READONLY |
1305 | 0 | inline APFloat minimum(const APFloat &A, const APFloat &B) { |
1306 | 0 | if (A.isNaN()) |
1307 | 0 | return A; |
1308 | 0 | if (B.isNaN()) |
1309 | 0 | return B; |
1310 | 0 | if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative())) |
1311 | 0 | return A.isNegative() ? A : B; |
1312 | 0 | return B < A ? B : A; |
1313 | 0 | } |
1314 | | |
1315 | | /// Implements IEEE 754-2018 maximum semantics. Returns the larger of 2 |
1316 | | /// arguments, propagating NaNs and treating -0 as less than +0. |
1317 | | LLVM_READONLY |
1318 | 0 | inline APFloat maximum(const APFloat &A, const APFloat &B) { |
1319 | 0 | if (A.isNaN()) |
1320 | 0 | return A; |
1321 | 0 | if (B.isNaN()) |
1322 | 0 | return B; |
1323 | 0 | if (A.isZero() && B.isZero() && (A.isNegative() != B.isNegative())) |
1324 | 0 | return A.isNegative() ? B : A; |
1325 | 0 | return A < B ? B : A; |
1326 | 0 | } |
1327 | | |
1328 | | } // namespace llvm |
1329 | | |
1330 | | #undef APFLOAT_DISPATCH_ON_SEMANTICS |
1331 | | #endif // LLVM_ADT_APFLOAT_H |