ImutAVLTree now allocates tree nodes from the BumpPtrAllocator using
[oota-llvm.git] / include / llvm / ADT / APFloat.h
index c6b62dc7f8cba2d03bce6839634f17a93986d975..9037ef5f727337d98e9335a6416b2c5374c5b2ee 100644 (file)
 //===----------------------------------------------------------------------===//
 
 /*  A self-contained host- and target-independent arbitrary-precision
-    floating-point software implementation using bignum integer
-    arithmetic, as provided by static functions in the APInt class.
+    floating-point software implementation.  It uses bignum integer
+    arithmetic as provided by static functions in the APInt class.
     The library will work with bignum integers whose parts are any
-    unsigned type at least 16 bits wide 64 bits is recommended.
+    unsigned type at least 16 bits wide, but 64 bits is recommended.
 
     Written for clarity rather than speed, in particular with a view
     to use in the front-end of a cross compiler so that target
     are add, subtract, multiply, divide, fused-multiply-add,
     conversion-to-float, conversion-to-integer and
     conversion-from-integer.  New rounding modes (e.g. away from zero)
-    can be added with three or four lines of code.  The library reads
-    and correctly rounds hexadecimal floating point numbers as per
-    C99; syntax is required to have been validated by the caller.
-    Conversion from decimal is not currently implemented.
+    can be added with three or four lines of code.
 
     Four formats are built-in: IEEE single precision, double
     precision, quadruple precision, and x87 80-bit extended double
     should be straight forward to add support for the before-rounding
     case too.
 
+    The library reads hexadecimal floating point numbers as per C99,
+    and correctly rounds if necessary according to the specified
+    rounding mode.  Syntax is required to have been validated by the
+    caller.  It also converts floating point numbers to hexadecimal
+    text as per the C99 %a and %A conversions.  The output precision
+    (or alternatively the natural minimal precision) can be specified;
+    if the requested precision is less than the natural precision the
+    output is correctly rounded for the specified rounding mode.
+
+    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
     integer parts.  After normalization of a number of precision P the
 
     Some features that may or may not be worth adding:
 
-    Conversions to and from decimal strings (hard).
-
-    Conversions to hexadecimal string.
-
-    Read and write IEEE-format in-memory representations.
+    Binary to decimal conversion (hard).
 
     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, nextafter, nexttoward.
+    New operations: sqrt, IEEE remainder, C90 fmod, nextafter,
+    nexttoward.
 */
 
 #ifndef LLVM_FLOAT_H
@@ -121,6 +128,7 @@ namespace llvm {
     static const fltSemantics IEEEsingle;
     static const fltSemantics IEEEdouble;
     static const fltSemantics IEEEquad;
+    static const fltSemantics PPCDoubleDouble;
     static const fltSemantics x87DoubleExtended;
     /* And this psuedo, used to construct APFloats that cannot
        conflict with anything real. */
@@ -170,7 +178,7 @@ namespace llvm {
     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();
 
@@ -180,17 +188,21 @@ namespace llvm {
     opStatus multiply(const APFloat &, roundingMode);
     opStatus divide(const APFloat &, roundingMode);
     opStatus mod(const APFloat &, roundingMode);
-    void copySign(const APFloat &);
     opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode);
-    void changeSign();    // neg
-    void clearSign();     // abs
+
+    /* Sign operations.  */
+    void changeSign();
+    void clearSign();
+    void copySign(const APFloat &);
 
     /* Conversions.  */
     opStatus convert(const fltSemantics &, roundingMode);
     opStatus convertToInteger(integerPart *, unsigned int, bool,
                              roundingMode) const;
-    opStatus convertFromInteger(const integerPart *, unsigned int, bool,
-                               roundingMode);
+    opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
+                                            bool, roundingMode);
+    opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
+                                            bool, roundingMode);
     opStatus convertFromString(const char *, roundingMode);
     APInt convertToAPInt() const;
     double convertToDouble() const;
@@ -205,6 +217,13 @@ namespace llvm {
        compare unordered, 0==-0). */
     cmpResult compare(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,
+       excluding the terminating NUL.  */
+    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;
 
@@ -249,22 +268,30 @@ namespace llvm {
     opStatus multiplySpecials(const APFloat &);
 
     /* 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 convertFromUnsignedInteger(integerPart *, unsigned int,
-                                       roundingMode);
-    lostFraction combineLostFractions(lostFraction, lostFraction);
+    opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
+                                      roundingMode);
     opStatus convertFromHexadecimalString(const char *, roundingMode);
+    opStatus convertFromDecimalString (const char *, roundingMode);
+    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;
-    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 initFromPPCDoubleDoubleAPInt(const APInt& api);
 
     void assign(const APFloat &);
     void copySignificand(const APFloat &);
@@ -291,6 +318,13 @@ namespace llvm {
 
     /* 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 */