1193323Sed//== llvm/Support/APFloat.h - Arbitrary Precision Floating Point -*- C++ -*-==//
2193323Sed//
3193323Sed//                     The LLVM Compiler Infrastructure
4193323Sed//
5193323Sed// This file is distributed under the University of Illinois Open Source
6193323Sed// License. See LICENSE.TXT for details.
7193323Sed//
8193323Sed//===----------------------------------------------------------------------===//
9263508Sdim///
10263508Sdim/// \file
11263508Sdim/// \brief
12263508Sdim/// This file declares a class to represent arbitrary precision floating point
13263508Sdim/// values and provide a variety of arithmetic operations on them.
14263508Sdim///
15193323Sed//===----------------------------------------------------------------------===//
16193323Sed
17263508Sdim#ifndef LLVM_ADT_APFLOAT_H
18263508Sdim#define LLVM_ADT_APFLOAT_H
19193323Sed
20263508Sdim#include "llvm/ADT/APInt.h"
21193323Sed
22263508Sdimnamespace llvm {
23193323Sed
24263508Sdimstruct fltSemantics;
25263508Sdimclass APSInt;
26263508Sdimclass StringRef;
27193323Sed
28263508Sdim/// Enum that represents what fraction of the LSB truncated bits of an fp number
29263508Sdim/// represent.
30263508Sdim///
31263508Sdim/// This essentially combines the roles of guard and sticky bits.
32263508Sdimenum lostFraction { // Example of truncated bits:
33263508Sdim  lfExactlyZero,    // 000000
34263508Sdim  lfLessThanHalf,   // 0xxxxx  x's not all zero
35263508Sdim  lfExactlyHalf,    // 100000
36263508Sdim  lfMoreThanHalf    // 1xxxxx  x's not all zero
37263508Sdim};
38193323Sed
39263508Sdim/// \brief A self-contained host- and target-independent arbitrary-precision
40263508Sdim/// floating-point software implementation.
41263508Sdim///
42263508Sdim/// APFloat uses bignum integer arithmetic as provided by static functions in
43263508Sdim/// the APInt class.  The library will work with bignum integers whose parts are
44263508Sdim/// any unsigned type at least 16 bits wide, but 64 bits is recommended.
45263508Sdim///
46263508Sdim/// Written for clarity rather than speed, in particular with a view to use in
47263508Sdim/// the front-end of a cross compiler so that target arithmetic can be correctly
48263508Sdim/// performed on the host.  Performance should nonetheless be reasonable,
49263508Sdim/// particularly for its intended use.  It may be useful as a base
50263508Sdim/// implementation for a run-time library during development of a faster
51263508Sdim/// target-specific one.
52263508Sdim///
53263508Sdim/// All 5 rounding modes in the IEEE-754R draft are handled correctly for all
54263508Sdim/// implemented operations.  Currently implemented operations are add, subtract,
55263508Sdim/// multiply, divide, fused-multiply-add, conversion-to-float,
56263508Sdim/// conversion-to-integer and conversion-from-integer.  New rounding modes
57263508Sdim/// (e.g. away from zero) can be added with three or four lines of code.
58263508Sdim///
59263508Sdim/// Four formats are built-in: IEEE single precision, double precision,
60263508Sdim/// quadruple precision, and x87 80-bit extended double (when operating with
61263508Sdim/// full extended precision).  Adding a new format that obeys IEEE semantics
62263508Sdim/// only requires adding two lines of code: a declaration and definition of the
63263508Sdim/// format.
64263508Sdim///
65263508Sdim/// All operations return the status of that operation as an exception bit-mask,
66263508Sdim/// so multiple operations can be done consecutively with their results or-ed
67263508Sdim/// together.  The returned status can be useful for compiler diagnostics; e.g.,
68263508Sdim/// inexact, underflow and overflow can be easily diagnosed on constant folding,
69263508Sdim/// and compiler optimizers can determine what exceptions would be raised by
70263508Sdim/// folding operations and optimize, or perhaps not optimize, accordingly.
71263508Sdim///
72263508Sdim/// At present, underflow tininess is detected after rounding; it should be
73263508Sdim/// straight forward to add support for the before-rounding case too.
74263508Sdim///
75263508Sdim/// The library reads hexadecimal floating point numbers as per C99, and
76263508Sdim/// correctly rounds if necessary according to the specified rounding mode.
77263508Sdim/// Syntax is required to have been validated by the caller.  It also converts
78263508Sdim/// floating point numbers to hexadecimal text as per the C99 %a and %A
79263508Sdim/// conversions.  The output precision (or alternatively the natural minimal
80263508Sdim/// precision) can be specified; if the requested precision is less than the
81263508Sdim/// natural precision the output is correctly rounded for the specified rounding
82263508Sdim/// mode.
83263508Sdim///
84263508Sdim/// It also reads decimal floating point numbers and correctly rounds according
85263508Sdim/// to the specified rounding mode.
86263508Sdim///
87263508Sdim/// Conversion to decimal text is not currently implemented.
88263508Sdim///
89263508Sdim/// Non-zero finite numbers are represented internally as a sign bit, a 16-bit
90263508Sdim/// signed exponent, and the significand as an array of integer parts.  After
91263508Sdim/// normalization of a number of precision P the exponent is within the range of
92263508Sdim/// the format, and if the number is not denormal the P-th bit of the
93263508Sdim/// significand is set as an explicit integer bit.  For denormals the most
94263508Sdim/// significant bit is shifted right so that the exponent is maintained at the
95263508Sdim/// format's minimum, so that the smallest denormal has just the least
96263508Sdim/// significant bit of the significand set.  The sign of zeroes and infinities
97263508Sdim/// is significant; the exponent and significand of such numbers is not stored,
98263508Sdim/// but has a known implicit (deterministic) value: 0 for the significands, 0
99263508Sdim/// for zero exponent, all 1 bits for infinity exponent.  For NaNs the sign and
100263508Sdim/// significand are deterministic, although not really meaningful, and preserved
101263508Sdim/// in non-conversion operations.  The exponent is implicitly all 1 bits.
102263508Sdim///
103263508Sdim/// APFloat does not provide any exception handling beyond default exception
104263508Sdim/// handling. We represent Signaling NaNs via IEEE-754R 2008 6.2.1 should clause
105263508Sdim/// by encoding Signaling NaNs with the first bit of its trailing significand as
106263508Sdim/// 0.
107263508Sdim///
108263508Sdim/// TODO
109263508Sdim/// ====
110263508Sdim///
111263508Sdim/// Some features that may or may not be worth adding:
112263508Sdim///
113263508Sdim/// Binary to decimal conversion (hard).
114263508Sdim///
115263508Sdim/// Optional ability to detect underflow tininess before rounding.
116263508Sdim///
117263508Sdim/// New formats: x87 in single and double precision mode (IEEE apart from
118263508Sdim/// extended exponent range) (hard).
119263508Sdim///
120263508Sdim/// New operations: sqrt, IEEE remainder, C90 fmod, nexttoward.
121263508Sdim///
122263508Sdimclass APFloat {
123263508Sdimpublic:
124193323Sed
125263508Sdim  /// A signed type to represent a floating point numbers unbiased exponent.
126263508Sdim  typedef signed short ExponentType;
127193323Sed
128263508Sdim  /// \name Floating Point Semantics.
129263508Sdim  /// @{
130193323Sed
131263508Sdim  static const fltSemantics IEEEhalf;
132263508Sdim  static const fltSemantics IEEEsingle;
133263508Sdim  static const fltSemantics IEEEdouble;
134263508Sdim  static const fltSemantics IEEEquad;
135263508Sdim  static const fltSemantics PPCDoubleDouble;
136263508Sdim  static const fltSemantics x87DoubleExtended;
137193323Sed
138263508Sdim  /// A Pseudo fltsemantic used to construct APFloats that cannot conflict with
139263508Sdim  /// anything real.
140263508Sdim  static const fltSemantics Bogus;
141193323Sed
142263508Sdim  /// @}
143193323Sed
144263508Sdim  static unsigned int semanticsPrecision(const fltSemantics &);
145193323Sed
146263508Sdim  /// IEEE-754R 5.11: Floating Point Comparison Relations.
147263508Sdim  enum cmpResult {
148263508Sdim    cmpLessThan,
149263508Sdim    cmpEqual,
150263508Sdim    cmpGreaterThan,
151263508Sdim    cmpUnordered
152263508Sdim  };
153193323Sed
154263508Sdim  /// IEEE-754R 4.3: Rounding-direction attributes.
155263508Sdim  enum roundingMode {
156263508Sdim    rmNearestTiesToEven,
157263508Sdim    rmTowardPositive,
158263508Sdim    rmTowardNegative,
159263508Sdim    rmTowardZero,
160263508Sdim    rmNearestTiesToAway
161263508Sdim  };
162193323Sed
163263508Sdim  /// IEEE-754R 7: Default exception handling.
164263508Sdim  ///
165263508Sdim  /// opUnderflow or opOverflow are always returned or-ed with opInexact.
166263508Sdim  enum opStatus {
167263508Sdim    opOK = 0x00,
168263508Sdim    opInvalidOp = 0x01,
169263508Sdim    opDivByZero = 0x02,
170263508Sdim    opOverflow = 0x04,
171263508Sdim    opUnderflow = 0x08,
172263508Sdim    opInexact = 0x10
173263508Sdim  };
174193323Sed
175263508Sdim  /// Category of internally-represented number.
176263508Sdim  enum fltCategory {
177263508Sdim    fcInfinity,
178263508Sdim    fcNaN,
179263508Sdim    fcNormal,
180263508Sdim    fcZero
181263508Sdim  };
182193323Sed
183263508Sdim  /// Convenience enum used to construct an uninitialized APFloat.
184263508Sdim  enum uninitializedTag {
185263508Sdim    uninitialized
186263508Sdim  };
187193323Sed
188263508Sdim  /// \name Constructors
189263508Sdim  /// @{
190193323Sed
191263508Sdim  APFloat(const fltSemantics &); // Default construct to 0.0
192263508Sdim  APFloat(const fltSemantics &, StringRef);
193263508Sdim  APFloat(const fltSemantics &, integerPart);
194263508Sdim  APFloat(const fltSemantics &, uninitializedTag);
195263508Sdim  APFloat(const fltSemantics &, const APInt &);
196263508Sdim  explicit APFloat(double d);
197263508Sdim  explicit APFloat(float f);
198263508Sdim  APFloat(const APFloat &);
199263508Sdim  ~APFloat();
200193323Sed
201263508Sdim  /// @}
202193323Sed
203263508Sdim  /// \brief Returns whether this instance allocated memory.
204263508Sdim  bool needsCleanup() const { return partCount() > 1; }
205193323Sed
206263508Sdim  /// \name Convenience "constructors"
207263508Sdim  /// @{
208193323Sed
209263508Sdim  /// Factory for Positive and Negative Zero.
210263508Sdim  ///
211263508Sdim  /// \param Negative True iff the number should be negative.
212263508Sdim  static APFloat getZero(const fltSemantics &Sem, bool Negative = false) {
213263508Sdim    APFloat Val(Sem, uninitialized);
214263508Sdim    Val.makeZero(Negative);
215263508Sdim    return Val;
216263508Sdim  }
217193323Sed
218263508Sdim  /// Factory for Positive and Negative Infinity.
219263508Sdim  ///
220263508Sdim  /// \param Negative True iff the number should be negative.
221263508Sdim  static APFloat getInf(const fltSemantics &Sem, bool Negative = false) {
222263508Sdim    APFloat Val(Sem, uninitialized);
223263508Sdim    Val.makeInf(Negative);
224263508Sdim    return Val;
225263508Sdim  }
226193323Sed
227263508Sdim  /// Factory for QNaN values.
228263508Sdim  ///
229263508Sdim  /// \param Negative - True iff the NaN generated should be negative.
230263508Sdim  /// \param type - The unspecified fill bits for creating the NaN, 0 by
231263508Sdim  /// default.  The value is truncated as necessary.
232263508Sdim  static APFloat getNaN(const fltSemantics &Sem, bool Negative = false,
233263508Sdim                        unsigned type = 0) {
234263508Sdim    if (type) {
235263508Sdim      APInt fill(64, type);
236263508Sdim      return getQNaN(Sem, Negative, &fill);
237263508Sdim    } else {
238263508Sdim      return getQNaN(Sem, Negative, 0);
239263508Sdim    }
240263508Sdim  }
241193323Sed
242263508Sdim  /// Factory for QNaN values.
243263508Sdim  static APFloat getQNaN(const fltSemantics &Sem, bool Negative = false,
244263508Sdim                         const APInt *payload = 0) {
245263508Sdim    return makeNaN(Sem, false, Negative, payload);
246263508Sdim  }
247193323Sed
248263508Sdim  /// Factory for SNaN values.
249263508Sdim  static APFloat getSNaN(const fltSemantics &Sem, bool Negative = false,
250263508Sdim                         const APInt *payload = 0) {
251263508Sdim    return makeNaN(Sem, true, Negative, payload);
252263508Sdim  }
253193323Sed
254263508Sdim  /// Returns the largest finite number in the given semantics.
255263508Sdim  ///
256263508Sdim  /// \param Negative - True iff the number should be negative
257263508Sdim  static APFloat getLargest(const fltSemantics &Sem, bool Negative = false);
258193323Sed
259263508Sdim  /// Returns the smallest (by magnitude) finite number in the given semantics.
260263508Sdim  /// Might be denormalized, which implies a relative loss of precision.
261263508Sdim  ///
262263508Sdim  /// \param Negative - True iff the number should be negative
263263508Sdim  static APFloat getSmallest(const fltSemantics &Sem, bool Negative = false);
264193323Sed
265263508Sdim  /// Returns the smallest (by magnitude) normalized finite number in the given
266263508Sdim  /// semantics.
267263508Sdim  ///
268263508Sdim  /// \param Negative - True iff the number should be negative
269263508Sdim  static APFloat getSmallestNormalized(const fltSemantics &Sem,
270263508Sdim                                       bool Negative = false);
271204642Srdivacky
272263508Sdim  /// Returns a float which is bitcasted from an all one value int.
273263508Sdim  ///
274263508Sdim  /// \param BitWidth - Select float type
275263508Sdim  /// \param isIEEE   - If 128 bit number, select between PPC and IEEE
276263508Sdim  static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false);
277193323Sed
278263508Sdim  /// @}
279201360Srdivacky
280263508Sdim  /// Used to insert APFloat objects, or objects that contain APFloat objects,
281263508Sdim  /// into FoldingSets.
282263508Sdim  void Profile(FoldingSetNodeID &NID) const;
283193323Sed
284263508Sdim  /// \brief Used by the Bitcode serializer to emit APInts to Bitcode.
285263508Sdim  void Emit(Serializer &S) const;
286204642Srdivacky
287263508Sdim  /// \brief Used by the Bitcode deserializer to deserialize APInts.
288263508Sdim  static APFloat ReadVal(Deserializer &D);
289204642Srdivacky
290263508Sdim  /// \name Arithmetic
291263508Sdim  /// @{
292201360Srdivacky
293263508Sdim  opStatus add(const APFloat &, roundingMode);
294263508Sdim  opStatus subtract(const APFloat &, roundingMode);
295263508Sdim  opStatus multiply(const APFloat &, roundingMode);
296263508Sdim  opStatus divide(const APFloat &, roundingMode);
297263508Sdim  /// IEEE remainder.
298263508Sdim  opStatus remainder(const APFloat &);
299263508Sdim  /// C fmod, or llvm frem.
300263508Sdim  opStatus mod(const APFloat &, roundingMode);
301263508Sdim  opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode);
302263508Sdim  opStatus roundToIntegral(roundingMode);
303263508Sdim  /// IEEE-754R 5.3.1: nextUp/nextDown.
304263508Sdim  opStatus next(bool nextDown);
305201360Srdivacky
306263508Sdim  /// @}
307201360Srdivacky
308263508Sdim  /// \name Sign operations.
309263508Sdim  /// @{
310218893Sdim
311263508Sdim  void changeSign();
312263508Sdim  void clearSign();
313263508Sdim  void copySign(const APFloat &);
314193323Sed
315263508Sdim  /// @}
316193323Sed
317263508Sdim  /// \name Conversions
318263508Sdim  /// @{
319193323Sed
320263508Sdim  opStatus convert(const fltSemantics &, roundingMode, bool *);
321263508Sdim  opStatus convertToInteger(integerPart *, unsigned int, bool, roundingMode,
322263508Sdim                            bool *) const;
323263508Sdim  opStatus convertToInteger(APSInt &, roundingMode, bool *) const;
324263508Sdim  opStatus convertFromAPInt(const APInt &, bool, roundingMode);
325263508Sdim  opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
326263508Sdim                                          bool, roundingMode);
327263508Sdim  opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
328263508Sdim                                          bool, roundingMode);
329263508Sdim  opStatus convertFromString(StringRef, roundingMode);
330263508Sdim  APInt bitcastToAPInt() const;
331263508Sdim  double convertToDouble() const;
332263508Sdim  float convertToFloat() const;
333193323Sed
334263508Sdim  /// @}
335193323Sed
336263508Sdim  /// The definition of equality is not straightforward for floating point, so
337263508Sdim  /// we won't use operator==.  Use one of the following, or write whatever it
338263508Sdim  /// is you really mean.
339263508Sdim  bool operator==(const APFloat &) const LLVM_DELETED_FUNCTION;
340193323Sed
341263508Sdim  /// IEEE comparison with another floating point number (NaNs compare
342263508Sdim  /// unordered, 0==-0).
343263508Sdim  cmpResult compare(const APFloat &) const;
344193323Sed
345263508Sdim  /// Bitwise comparison for equality (QNaNs compare equal, 0!=-0).
346263508Sdim  bool bitwiseIsEqual(const APFloat &) const;
347193323Sed
348263508Sdim  /// Write out a hexadecimal representation of the floating point value to DST,
349263508Sdim  /// which must be of sufficient size, in the C99 form [-]0xh.hhhhp[+-]d.
350263508Sdim  /// Return the number of characters written, excluding the terminating NUL.
351263508Sdim  unsigned int convertToHexString(char *dst, unsigned int hexDigits,
352263508Sdim                                  bool upperCase, roundingMode) const;
353193323Sed
354263508Sdim  /// \name IEEE-754R 5.7.2 General operations.
355263508Sdim  /// @{
356193323Sed
357263508Sdim  /// IEEE-754R isSignMinus: Returns true if and only if the current value is
358263508Sdim  /// negative.
359263508Sdim  ///
360263508Sdim  /// This applies to zeros and NaNs as well.
361263508Sdim  bool isNegative() const { return sign; }
362193323Sed
363263508Sdim  /// IEEE-754R isNormal: Returns true if and only if the current value is normal.
364263508Sdim  ///
365263508Sdim  /// This implies that the current value of the float is not zero, subnormal,
366263508Sdim  /// infinite, or NaN following the definition of normality from IEEE-754R.
367263508Sdim  bool isNormal() const { return !isDenormal() && isFiniteNonZero(); }
368193323Sed
369263508Sdim  /// Returns true if and only if the current value is zero, subnormal, or
370263508Sdim  /// normal.
371263508Sdim  ///
372263508Sdim  /// This means that the value is not infinite or NaN.
373263508Sdim  bool isFinite() const { return !isNaN() && !isInfinity(); }
374193323Sed
375263508Sdim  /// Returns true if and only if the float is plus or minus zero.
376263508Sdim  bool isZero() const { return category == fcZero; }
377201360Srdivacky
378263508Sdim  /// IEEE-754R isSubnormal(): Returns true if and only if the float is a
379263508Sdim  /// denormal.
380263508Sdim  bool isDenormal() const;
381221345Sdim
382263508Sdim  /// IEEE-754R isInfinite(): Returns true if and only if the float is infinity.
383263508Sdim  bool isInfinity() const { return category == fcInfinity; }
384193323Sed
385263508Sdim  /// Returns true if and only if the float is a quiet or signaling NaN.
386263508Sdim  bool isNaN() const { return category == fcNaN; }
387193323Sed
388263508Sdim  /// Returns true if and only if the float is a signaling NaN.
389263508Sdim  bool isSignaling() const;
390193323Sed
391263508Sdim  /// @}
392193323Sed
393263508Sdim  /// \name Simple Queries
394263508Sdim  /// @{
395193323Sed
396263508Sdim  fltCategory getCategory() const { return category; }
397263508Sdim  const fltSemantics &getSemantics() const { return *semantics; }
398263508Sdim  bool isNonZero() const { return category != fcZero; }
399263508Sdim  bool isFiniteNonZero() const { return isFinite() && !isZero(); }
400263508Sdim  bool isPosZero() const { return isZero() && !isNegative(); }
401263508Sdim  bool isNegZero() const { return isZero() && isNegative(); }
402193323Sed
403263508Sdim  /// Returns true if and only if the number has the smallest possible non-zero
404263508Sdim  /// magnitude in the current semantics.
405263508Sdim  bool isSmallest() const;
406193323Sed
407263508Sdim  /// Returns true if and only if the number has the largest possible finite
408263508Sdim  /// magnitude in the current semantics.
409263508Sdim  bool isLargest() const;
410193323Sed
411263508Sdim  /// @}
412193323Sed
413263508Sdim  APFloat &operator=(const APFloat &);
414193323Sed
415263508Sdim  /// \brief Overload to compute a hash code for an APFloat value.
416263508Sdim  ///
417263508Sdim  /// Note that the use of hash codes for floating point values is in general
418263508Sdim  /// frought with peril. Equality is hard to define for these values. For
419263508Sdim  /// example, should negative and positive zero hash to different codes? Are
420263508Sdim  /// they equal or not? This hash value implementation specifically
421263508Sdim  /// emphasizes producing different codes for different inputs in order to
422263508Sdim  /// be used in canonicalization and memoization. As such, equality is
423263508Sdim  /// bitwiseIsEqual, and 0 != -0.
424263508Sdim  friend hash_code hash_value(const APFloat &Arg);
425193323Sed
426263508Sdim  /// Converts this value into a decimal string.
427263508Sdim  ///
428263508Sdim  /// \param FormatPrecision The maximum number of digits of
429263508Sdim  ///   precision to output.  If there are fewer digits available,
430263508Sdim  ///   zero padding will not be used unless the value is
431263508Sdim  ///   integral and small enough to be expressed in
432263508Sdim  ///   FormatPrecision digits.  0 means to use the natural
433263508Sdim  ///   precision of the number.
434263508Sdim  /// \param FormatMaxPadding The maximum number of zeros to
435263508Sdim  ///   consider inserting before falling back to scientific
436263508Sdim  ///   notation.  0 means to always use scientific notation.
437263508Sdim  ///
438263508Sdim  /// Number       Precision    MaxPadding      Result
439263508Sdim  /// ------       ---------    ----------      ------
440263508Sdim  /// 1.01E+4              5             2       10100
441263508Sdim  /// 1.01E+4              4             2       1.01E+4
442263508Sdim  /// 1.01E+4              5             1       1.01E+4
443263508Sdim  /// 1.01E-2              5             2       0.0101
444263508Sdim  /// 1.01E-2              4             2       0.0101
445263508Sdim  /// 1.01E-2              4             1       1.01E-2
446263508Sdim  void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
447263508Sdim                unsigned FormatMaxPadding = 3) const;
448193323Sed
449263508Sdim  /// If this value has an exact multiplicative inverse, store it in inv and
450263508Sdim  /// return true.
451263508Sdim  bool getExactInverse(APFloat *inv) const;
452193323Sed
453263508Sdimprivate:
454263508Sdim
455263508Sdim  /// \name Simple Queries
456263508Sdim  /// @{
457263508Sdim
458263508Sdim  integerPart *significandParts();
459263508Sdim  const integerPart *significandParts() const;
460263508Sdim  unsigned int partCount() const;
461263508Sdim
462263508Sdim  /// @}
463263508Sdim
464263508Sdim  /// \name Significand operations.
465263508Sdim  /// @{
466263508Sdim
467263508Sdim  integerPart addSignificand(const APFloat &);
468263508Sdim  integerPart subtractSignificand(const APFloat &, integerPart);
469263508Sdim  lostFraction addOrSubtractSignificand(const APFloat &, bool subtract);
470263508Sdim  lostFraction multiplySignificand(const APFloat &, const APFloat *);
471263508Sdim  lostFraction divideSignificand(const APFloat &);
472263508Sdim  void incrementSignificand();
473263508Sdim  void initialize(const fltSemantics *);
474263508Sdim  void shiftSignificandLeft(unsigned int);
475263508Sdim  lostFraction shiftSignificandRight(unsigned int);
476263508Sdim  unsigned int significandLSB() const;
477263508Sdim  unsigned int significandMSB() const;
478263508Sdim  void zeroSignificand();
479263508Sdim  /// Return true if the significand excluding the integral bit is all ones.
480263508Sdim  bool isSignificandAllOnes() const;
481263508Sdim  /// Return true if the significand excluding the integral bit is all zeros.
482263508Sdim  bool isSignificandAllZeros() const;
483263508Sdim
484263508Sdim  /// @}
485263508Sdim
486263508Sdim  /// \name Arithmetic on special values.
487263508Sdim  /// @{
488263508Sdim
489263508Sdim  opStatus addOrSubtractSpecials(const APFloat &, bool subtract);
490263508Sdim  opStatus divideSpecials(const APFloat &);
491263508Sdim  opStatus multiplySpecials(const APFloat &);
492263508Sdim  opStatus modSpecials(const APFloat &);
493263508Sdim
494263508Sdim  /// @}
495263508Sdim
496263508Sdim  /// \name Special value setters.
497263508Sdim  /// @{
498263508Sdim
499263508Sdim  void makeLargest(bool Neg = false);
500263508Sdim  void makeSmallest(bool Neg = false);
501263508Sdim  void makeNaN(bool SNaN = false, bool Neg = false, const APInt *fill = 0);
502263508Sdim  static APFloat makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative,
503263508Sdim                         const APInt *fill);
504263508Sdim  void makeInf(bool Neg = false);
505263508Sdim  void makeZero(bool Neg = false);
506263508Sdim
507263508Sdim  /// @}
508263508Sdim
509263508Sdim  /// \name Miscellany
510263508Sdim  /// @{
511263508Sdim
512263508Sdim  bool convertFromStringSpecials(StringRef str);
513263508Sdim  opStatus normalize(roundingMode, lostFraction);
514263508Sdim  opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract);
515263508Sdim  cmpResult compareAbsoluteValue(const APFloat &) const;
516263508Sdim  opStatus handleOverflow(roundingMode);
517263508Sdim  bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
518263508Sdim  opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool,
519263508Sdim                                        roundingMode, bool *) const;
520263508Sdim  opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
521263508Sdim                                    roundingMode);
522263508Sdim  opStatus convertFromHexadecimalString(StringRef, roundingMode);
523263508Sdim  opStatus convertFromDecimalString(StringRef, roundingMode);
524263508Sdim  char *convertNormalToHexString(char *, unsigned int, bool,
525263508Sdim                                 roundingMode) const;
526263508Sdim  opStatus roundSignificandWithExponent(const integerPart *, unsigned int, int,
527263508Sdim                                        roundingMode);
528263508Sdim
529263508Sdim  /// @}
530263508Sdim
531263508Sdim  APInt convertHalfAPFloatToAPInt() const;
532263508Sdim  APInt convertFloatAPFloatToAPInt() const;
533263508Sdim  APInt convertDoubleAPFloatToAPInt() const;
534263508Sdim  APInt convertQuadrupleAPFloatToAPInt() const;
535263508Sdim  APInt convertF80LongDoubleAPFloatToAPInt() const;
536263508Sdim  APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
537263508Sdim  void initFromAPInt(const fltSemantics *Sem, const APInt &api);
538263508Sdim  void initFromHalfAPInt(const APInt &api);
539263508Sdim  void initFromFloatAPInt(const APInt &api);
540263508Sdim  void initFromDoubleAPInt(const APInt &api);
541263508Sdim  void initFromQuadrupleAPInt(const APInt &api);
542263508Sdim  void initFromF80LongDoubleAPInt(const APInt &api);
543263508Sdim  void initFromPPCDoubleDoubleAPInt(const APInt &api);
544263508Sdim
545263508Sdim  void assign(const APFloat &);
546263508Sdim  void copySignificand(const APFloat &);
547263508Sdim  void freeSignificand();
548263508Sdim
549263508Sdim  /// The semantics that this value obeys.
550263508Sdim  const fltSemantics *semantics;
551263508Sdim
552263508Sdim  /// A binary fraction with an explicit integer bit.
553263508Sdim  ///
554263508Sdim  /// The significand must be at least one bit wider than the target precision.
555263508Sdim  union Significand {
556263508Sdim    integerPart part;
557263508Sdim    integerPart *parts;
558263508Sdim  } significand;
559263508Sdim
560263508Sdim  /// The signed unbiased exponent of the value.
561263508Sdim  ExponentType exponent;
562263508Sdim
563263508Sdim  /// What kind of floating point number this is.
564263508Sdim  ///
565263508Sdim  /// Only 2 bits are required, but VisualStudio incorrectly sign extends it.
566263508Sdim  /// Using the extra bit keeps it from failing under VisualStudio.
567263508Sdim  fltCategory category : 3;
568263508Sdim
569263508Sdim  /// Sign bit of the number.
570263508Sdim  unsigned int sign : 1;
571263508Sdim};
572263508Sdim
573263508Sdim/// See friend declaration above.
574263508Sdim///
575263508Sdim/// This additional declaration is required in order to compile LLVM with IBM
576263508Sdim/// xlC compiler.
577263508Sdimhash_code hash_value(const APFloat &Arg);
578263508Sdim} // namespace llvm
579263508Sdim
580263508Sdim#endif // LLVM_ADT_APFLOAT_H
581