add a traits class for SmallPtrSet that allows us to stick things that are
[oota-llvm.git] / include / llvm / ADT / APFloat.h
index efd19d2c562bd64eaae92a1fe706e5b443ab2f20..29a89dd06c2d53acc14b42ec1e950f1acef7701a 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by Neil Booth and is distributed under the
-// University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 //
 //===----------------------------------------------------------------------===//
 //
     if the requested precision is less than the natural precision the
     output is correctly rounded for the specified rounding mode.
 
     if the requested precision is less than the natural precision the
     output is correctly rounded for the specified rounding mode.
 
-    Conversion to and from decimal text is not currently implemented.
+    It also reads decimal floating point numbers and correctly rounds
+    according to the specified rounding mode.
+
+    Conversion to decimal text is not currently implemented.
 
     Non-zero finite numbers are represented internally as a sign bit,
     a 16-bit signed exponent, and the significand as an array of
 
     Non-zero finite numbers are represented internally as a sign bit,
     a 16-bit signed exponent, and the significand as an array of
 
     Some features that may or may not be worth adding:
 
 
     Some features that may or may not be worth adding:
 
-    Conversions to and from decimal strings (hard).
+    Binary to decimal conversion (hard).
 
     Optional ability to detect underflow tininess before rounding.
 
     New formats: x87 in single and double precision mode (IEEE apart
 
     Optional ability to detect underflow tininess before rounding.
 
     New formats: x87 in single and double precision mode (IEEE apart
-    from extended exponent range) and IBM two-double extended
-    precision (hard).
+    from extended exponent range) (hard).
 
     New operations: sqrt, IEEE remainder, C90 fmod, nextafter,
     nexttoward.
 
     New operations: sqrt, IEEE remainder, C90 fmod, nextafter,
     nexttoward.
 
 // APInt contains static functions implementing bignum arithmetic.
 #include "llvm/ADT/APInt.h"
 
 // APInt contains static functions implementing bignum arithmetic.
 #include "llvm/ADT/APInt.h"
-#include "llvm/CodeGen/ValueTypes.h"
 
 namespace llvm {
 
 
 namespace llvm {
 
@@ -112,11 +113,11 @@ namespace llvm {
   /* When bits of a floating point number are truncated, this enum is
      used to indicate what fraction of the LSB those bits represented.
      It essentially combines the roles of guard and sticky bits.  */
   /* When bits of a floating point number are truncated, this enum is
      used to indicate what fraction of the LSB those bits represented.
      It essentially combines the roles of guard and sticky bits.  */
-  enum lostFraction {          // Example of truncated bits:
-    lfExactlyZero,             // 000000
-    lfLessThanHalf,            // 0xxxxx  x's not all zero
-    lfExactlyHalf,             // 100000
-    lfMoreThanHalf             // 1xxxxx  x's not all zero
+  enum lostFraction {           // Example of truncated bits:
+    lfExactlyZero,              // 000000
+    lfLessThanHalf,             // 0xxxxx  x's not all zero
+    lfExactlyHalf,              // 100000
+    lfMoreThanHalf              // 1xxxxx  x's not all zero
   };
 
   class APFloat {
   };
 
   class APFloat {
@@ -126,8 +127,9 @@ namespace llvm {
     static const fltSemantics IEEEsingle;
     static const fltSemantics IEEEdouble;
     static const fltSemantics IEEEquad;
     static const fltSemantics IEEEsingle;
     static const fltSemantics IEEEdouble;
     static const fltSemantics IEEEquad;
+    static const fltSemantics PPCDoubleDouble;
     static const fltSemantics x87DoubleExtended;
     static const fltSemantics x87DoubleExtended;
-    /* And this psuedo, used to construct APFloats that cannot
+    /* And this pseudo, used to construct APFloats that cannot
        conflict with anything real. */
     static const fltSemantics Bogus;
 
        conflict with anything real. */
     static const fltSemantics Bogus;
 
@@ -150,8 +152,8 @@ namespace llvm {
       rmNearestTiesToAway
     };
 
       rmNearestTiesToAway
     };
 
-    /* Operation status.  opUnderflow or opOverflow are always returned
-       or-ed with opInexact.  */
+    // Operation status.  opUnderflow or opOverflow are always returned
+    // or-ed with opInexact.
     enum opStatus {
       opOK          = 0x00,
       opInvalidOp   = 0x01,
     enum opStatus {
       opOK          = 0x00,
       opInvalidOp   = 0x01,
@@ -161,7 +163,7 @@ namespace llvm {
       opInexact     = 0x10
     };
 
       opInexact     = 0x10
     };
 
-    /* Category of internally-represented number.  */
+    // Category of internally-represented number.
     enum fltCategory {
       fcInfinity,
       fcNaN,
     enum fltCategory {
       fcInfinity,
       fcNaN,
@@ -169,35 +171,65 @@ namespace llvm {
       fcZero
     };
 
       fcZero
     };
 
-    /* Constructors.  */
+    // Constructors.
     APFloat(const fltSemantics &, const char *);
     APFloat(const fltSemantics &, integerPart);
     APFloat(const fltSemantics &, fltCategory, bool negative);
     explicit APFloat(double d);
     explicit APFloat(float f);
     APFloat(const fltSemantics &, const char *);
     APFloat(const fltSemantics &, integerPart);
     APFloat(const fltSemantics &, fltCategory, bool negative);
     explicit APFloat(double d);
     explicit APFloat(float f);
-    explicit APFloat(const APInt &);
+    explicit APFloat(const APInt &, bool isIEEE = false);
     APFloat(const APFloat &);
     ~APFloat();
 
     APFloat(const APFloat &);
     ~APFloat();
 
+    // Convenience "constructors"
+    static APFloat getZero(const fltSemantics &Sem, bool Negative = false) {
+      return APFloat(Sem, fcZero, Negative);
+    }
+    static APFloat getInf(const fltSemantics &Sem, bool Negative = false) {
+      return APFloat(Sem, fcInfinity, Negative);
+    }
+    static APFloat getNaN(const fltSemantics &Sem, bool Negative = false) {
+      return APFloat(Sem, fcNaN, Negative);
+    }
+
+    /// Profile - Used to insert APFloat objects, or objects that contain
+    ///  APFloat objects, into FoldingSets.
+    void Profile(FoldingSetNodeID& NID) const;
+
+    /// @brief Used by the Bitcode serializer to emit APInts to Bitcode.
+    void Emit(Serializer& S) const;
+
+    /// @brief Used by the Bitcode deserializer to deserialize APInts.
+    static APFloat ReadVal(Deserializer& D);
+
     /* Arithmetic.  */
     opStatus add(const APFloat &, roundingMode);
     opStatus subtract(const APFloat &, roundingMode);
     opStatus multiply(const APFloat &, roundingMode);
     opStatus divide(const APFloat &, roundingMode);
     /* Arithmetic.  */
     opStatus add(const APFloat &, roundingMode);
     opStatus subtract(const APFloat &, roundingMode);
     opStatus multiply(const APFloat &, roundingMode);
     opStatus divide(const APFloat &, roundingMode);
+    /* IEEE remainder. */
+    opStatus remainder(const APFloat &);
+    /* C fmod, or llvm frem. */
     opStatus mod(const APFloat &, roundingMode);
     opStatus mod(const APFloat &, roundingMode);
-    void copySign(const APFloat &);
     opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode);
     opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode);
-    void changeSign();    // neg
-    void clearSign();     // abs
+
+    /* Sign operations.  */
+    void changeSign();
+    void clearSign();
+    void copySign(const APFloat &);
 
     /* Conversions.  */
 
     /* Conversions.  */
-    opStatus convert(const fltSemantics &, roundingMode);
+    opStatus convert(const fltSemantics &, roundingMode, bool *);
     opStatus convertToInteger(integerPart *, unsigned int, bool,
     opStatus convertToInteger(integerPart *, unsigned int, bool,
-                             roundingMode) const;
-    opStatus convertFromInteger(const integerPart *, unsigned int, bool,
-                               roundingMode);
+                              roundingMode, bool *) const;
+    opStatus convertFromAPInt(const APInt &,
+                              bool, roundingMode);
+    opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
+                                            bool, roundingMode);
+    opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
+                                            bool, roundingMode);
     opStatus convertFromString(const char *, roundingMode);
     opStatus convertFromString(const char *, roundingMode);
-    APInt convertToAPInt() const;
+    APInt bitcastToAPInt() const;
     double convertToDouble() const;
     float convertToFloat() const;
 
     double convertToDouble() const;
     float convertToFloat() const;
 
@@ -210,6 +242,9 @@ namespace llvm {
        compare unordered, 0==-0). */
     cmpResult compare(const APFloat &) const;
 
        compare unordered, 0==-0). */
     cmpResult compare(const APFloat &) const;
 
+    /* Bitwise comparison for equality (QNaNs compare equal, 0!=-0). */
+    bool bitwiseIsEqual(const APFloat &) const;
+
     /* Write out a hexadecimal representation of the floating point
        value to DST, which must be of sufficient size, in the C99 form
        [-]0xh.hhhhp[+-]d.  Return the number of characters written,
     /* Write out a hexadecimal representation of the floating point
        value to DST, which must be of sufficient size, in the C99 form
        [-]0xh.hhhhp[+-]d.  Return the number of characters written,
@@ -217,14 +252,13 @@ namespace llvm {
     unsigned int convertToHexString(char *dst, unsigned int hexDigits,
                                     bool upperCase, roundingMode) const;
 
     unsigned int convertToHexString(char *dst, unsigned int hexDigits,
                                     bool upperCase, roundingMode) const;
 
-    /* Bitwise comparison for equality (QNaNs compare equal, 0!=-0). */
-    bool bitwiseIsEqual(const APFloat &) const;
-
     /* Simple queries.  */
     fltCategory getCategory() const { return category; }
     const fltSemantics &getSemantics() const { return *semantics; }
     bool isZero() const { return category == fcZero; }
     bool isNonZero() const { return category != fcZero; }
     /* Simple queries.  */
     fltCategory getCategory() const { return category; }
     const fltSemantics &getSemantics() const { return *semantics; }
     bool isZero() const { return category == fcZero; }
     bool isNonZero() const { return category != fcZero; }
+    bool isNaN() const { return category == fcNaN; }
+    bool isInfinity() const { return category == fcInfinity; }
     bool isNegative() const { return sign; }
     bool isPosZero() const { return isZero() && !isNegative(); }
     bool isNegZero() const { return isZero() && isNegative(); }
     bool isNegative() const { return sign; }
     bool isPosZero() const { return isZero() && !isNegative(); }
     bool isNegZero() const { return isZero() && isNegative(); }
@@ -259,26 +293,35 @@ namespace llvm {
     opStatus addOrSubtractSpecials(const APFloat &, bool subtract);
     opStatus divideSpecials(const APFloat &);
     opStatus multiplySpecials(const APFloat &);
     opStatus addOrSubtractSpecials(const APFloat &, bool subtract);
     opStatus divideSpecials(const APFloat &);
     opStatus multiplySpecials(const APFloat &);
+    opStatus modSpecials(const APFloat &);
 
     /* Miscellany.  */
 
     /* Miscellany.  */
+    void makeNaN(void);
     opStatus normalize(roundingMode, lostFraction);
     opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract);
     cmpResult compareAbsoluteValue(const APFloat &) const;
     opStatus handleOverflow(roundingMode);
     bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
     opStatus normalize(roundingMode, lostFraction);
     opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract);
     cmpResult compareAbsoluteValue(const APFloat &) const;
     opStatus handleOverflow(roundingMode);
     bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
-    opStatus convertFromUnsignedInteger(integerPart *, unsigned int,
-                                        roundingMode);
-    lostFraction combineLostFractions(lostFraction, lostFraction);
+    opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool,
+                                          roundingMode, bool *) const;
+    opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
+                                      roundingMode);
     opStatus convertFromHexadecimalString(const char *, roundingMode);
     opStatus convertFromHexadecimalString(const char *, roundingMode);
+    opStatus convertFromDecimalString (const char *, roundingMode);
     char *convertNormalToHexString(char *, unsigned int, bool,
                                    roundingMode) const;
     char *convertNormalToHexString(char *, unsigned int, bool,
                                    roundingMode) const;
+    opStatus roundSignificandWithExponent(const integerPart *, unsigned int,
+                                          int, roundingMode);
+
     APInt convertFloatAPFloatToAPInt() const;
     APInt convertDoubleAPFloatToAPInt() const;
     APInt convertF80LongDoubleAPFloatToAPInt() const;
     APInt convertFloatAPFloatToAPInt() const;
     APInt convertDoubleAPFloatToAPInt() const;
     APInt convertF80LongDoubleAPFloatToAPInt() const;
-    void initFromAPInt(const APInt& api);
+    APInt convertPPCDoubleDoubleAPFloatToAPInt() const;
+    void initFromAPInt(const APInt& api, bool isIEEE = false);
     void initFromFloatAPInt(const APInt& api);
     void initFromDoubleAPInt(const APInt& api);
     void initFromF80LongDoubleAPInt(const APInt& api);
     void initFromFloatAPInt(const APInt& api);
     void initFromDoubleAPInt(const APInt& api);
     void initFromF80LongDoubleAPInt(const APInt& api);
+    void initFromPPCDoubleDoubleAPInt(const APInt& api);
 
     void assign(const APFloat &);
     void copySignificand(const APFloat &);
 
     void assign(const APFloat &);
     void copySignificand(const APFloat &);
@@ -305,6 +348,13 @@ namespace llvm {
 
     /* The sign bit of this number.  */
     unsigned int sign: 1;
 
     /* The sign bit of this number.  */
     unsigned int sign: 1;
+
+    /* For PPCDoubleDouble, we have a second exponent and sign (the second
+       significand is appended to the first one, although it would be wrong to
+       regard these as a single number for arithmetic purposes).  These fields
+       are not meaningful for any other type. */
+    exponent_t exponent2 : 11;
+    unsigned int sign2: 1;
   };
 } /* namespace llvm */
 
   };
 } /* namespace llvm */