Fix PR1816, by correcting the broken definition of APInt::countTrailingZeros.
[oota-llvm.git] / include / llvm / ADT / APFloat.h
index f5511f42805ea292f8d2fbd5e17ee9d23e0b95ab..e4d4c8eb4209de4f95f66c73347f5ea4ec8b19ad 100644 (file)
     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
 
     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
-    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.
 
 // APInt contains static functions implementing bignum arithmetic.
 #include "llvm/ADT/APInt.h"
+#include "llvm/Bitcode/SerializationFwd.h"
 #include "llvm/CodeGen/ValueTypes.h"
 
 namespace llvm {
@@ -126,6 +129,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. */
@@ -175,9 +179,15 @@ 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();
+    
+    /// @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);
@@ -185,10 +195,12 @@ 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);
@@ -227,6 +239,7 @@ namespace llvm {
     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 isNegative() const { return sign; }
     bool isPosZero() const { return isZero() && !isNegative(); }
     bool isNegZero() const { return isZero() && isNegative(); }
@@ -263,23 +276,32 @@ 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 convertToSignExtendedInteger(integerPart *, unsigned int, bool,
+                                          roundingMode) const;
     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 &);
@@ -306,6 +328,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 */