X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FAPFloat.h;h=5a625a4c832f78fcbc0ded400e426bf4eecb7cdc;hb=e19f11215d8fa29635b28317dd1cfd1915d048d4;hp=29a89dd06c2d53acc14b42ec1e950f1acef7701a;hpb=ed6af24e146a5d358115123f0d2be694c1fa3a84;p=oota-llvm.git diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index 29a89dd06c2..5a625a4c832 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -109,6 +109,8 @@ namespace llvm { typedef signed short exponent_t; struct fltSemantics; + class APSInt; + class StringRef; /* When bits of a floating point number are truncated, this enum is used to indicate what fraction of the LSB those bits represented. @@ -124,6 +126,7 @@ namespace llvm { public: /* We support the following floating point semantics. */ + static const fltSemantics IEEEhalf; static const fltSemantics IEEEsingle; static const fltSemantics IEEEdouble; static const fltSemantics IEEEquad; @@ -171,10 +174,16 @@ namespace llvm { fcZero }; + enum uninitializedTag { + uninitialized + }; + // Constructors. - APFloat(const fltSemantics &, const char *); + APFloat(const fltSemantics &); // Default construct to 0.0 + APFloat(const fltSemantics &, StringRef); APFloat(const fltSemantics &, integerPart); APFloat(const fltSemantics &, fltCategory, bool negative); + APFloat(const fltSemantics &, uninitializedTag); explicit APFloat(double d); explicit APFloat(float f); explicit APFloat(const APInt &, bool isIEEE = false); @@ -188,10 +197,63 @@ namespace llvm { 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); + + /// getNaN - Factory for QNaN values. + /// + /// \param Negative - True iff the NaN generated should be negative. + /// \param type - The unspecified fill bits for creating the NaN, 0 by + /// default. The value is truncated as necessary. + static APFloat getNaN(const fltSemantics &Sem, bool Negative = false, + unsigned type = 0) { + if (type) { + APInt fill(64, type); + return getQNaN(Sem, Negative, &fill); + } else { + return getQNaN(Sem, Negative, 0); + } + } + + /// getQNan - Factory for QNaN values. + static APFloat getQNaN(const fltSemantics &Sem, + bool Negative = false, + const APInt *payload = 0) { + return makeNaN(Sem, false, Negative, payload); + } + + /// getSNan - Factory for SNaN values. + static APFloat getSNaN(const fltSemantics &Sem, + bool Negative = false, + const APInt *payload = 0) { + return makeNaN(Sem, true, Negative, payload); } + /// getLargest - Returns the largest finite number in the given + /// semantics. + /// + /// \param Negative - True iff the number should be negative + static APFloat getLargest(const fltSemantics &Sem, bool Negative = false); + + /// getSmallest - Returns the smallest (by magnitude) finite number + /// in the given semantics. Might be denormalized, which implies a + /// relative loss of precision. + /// + /// \param Negative - True iff the number should be negative + static APFloat getSmallest(const fltSemantics &Sem, bool Negative = false); + + /// getSmallestNormalized - Returns the smallest (by magnitude) + /// normalized finite number in the given semantics. + /// + /// \param Negative - True iff the number should be negative + static APFloat getSmallestNormalized(const fltSemantics &Sem, + bool Negative = false); + + /// getAllOnesValue - Returns a float which is bitcasted from + /// an all one value int. + /// + /// \param BitWidth - Select float type + /// \param isIEEE - If 128 bit number, select between PPC and IEEE + static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false); + /// Profile - Used to insert APFloat objects, or objects that contain /// APFloat objects, into FoldingSets. void Profile(FoldingSetNodeID& NID) const; @@ -212,6 +274,7 @@ namespace llvm { /* C fmod, or llvm frem. */ opStatus mod(const APFloat &, roundingMode); opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode); + opStatus roundToIntegral(roundingMode); /* Sign operations. */ void changeSign(); @@ -222,13 +285,14 @@ namespace llvm { opStatus convert(const fltSemantics &, roundingMode, bool *); opStatus convertToInteger(integerPart *, unsigned int, bool, roundingMode, bool *) const; + opStatus convertToInteger(APSInt&, 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(StringRef, roundingMode); APInt bitcastToAPInt() const; double convertToDouble() const; float convertToFloat() const; @@ -257,6 +321,7 @@ namespace llvm { const fltSemantics &getSemantics() const { return *semantics; } bool isZero() const { return category == fcZero; } bool isNonZero() const { return category != fcZero; } + bool isNormal() const { return category == fcNormal; } bool isNaN() const { return category == fcNaN; } bool isInfinity() const { return category == fcInfinity; } bool isNegative() const { return sign; } @@ -265,8 +330,44 @@ namespace llvm { APFloat& operator=(const APFloat &); - /* Return an arbitrary integer value usable for hashing. */ - uint32_t getHashValue() const; + /// \brief Overload to compute a hash code for an APFloat value. + /// + /// Note that the use of hash codes for floating point values is in general + /// frought with peril. Equality is hard to define for these values. For + /// example, should negative and positive zero hash to different codes? Are + /// they equal or not? This hash value implementation specifically + /// emphasizes producing different codes for different inputs in order to + /// be used in canonicalization and memoization. As such, equality is + /// bitwiseIsEqual, and 0 != -0. + friend hash_code hash_value(const APFloat &Arg); + + /// Converts this value into a decimal string. + /// + /// \param FormatPrecision The maximum number of digits of + /// precision to output. If there are fewer digits available, + /// zero padding will not be used unless the value is + /// integral and small enough to be expressed in + /// FormatPrecision digits. 0 means to use the natural + /// precision of the number. + /// \param FormatMaxPadding The maximum number of zeros to + /// consider inserting before falling back to scientific + /// notation. 0 means to always use scientific notation. + /// + /// Number Precision MaxPadding Result + /// ------ --------- ---------- ------ + /// 1.01E+4 5 2 10100 + /// 1.01E+4 4 2 1.01E+4 + /// 1.01E+4 5 1 1.01E+4 + /// 1.01E-2 5 2 0.0101 + /// 1.01E-2 4 2 0.0101 + /// 1.01E-2 4 1 1.01E-2 + void toString(SmallVectorImpl &Str, + unsigned FormatPrecision = 0, + unsigned FormatMaxPadding = 3) const; + + /// getExactInverse - If this value has an exact multiplicative inverse, + /// store it in inv and return true. + bool getExactInverse(APFloat *inv) const; private: @@ -296,7 +397,9 @@ namespace llvm { opStatus modSpecials(const APFloat &); /* Miscellany. */ - void makeNaN(void); + static APFloat makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative, + const APInt *fill); + void makeNaN(bool SNaN = false, bool Neg = false, const APInt *fill = 0); opStatus normalize(roundingMode, lostFraction); opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract); cmpResult compareAbsoluteValue(const APFloat &) const; @@ -306,20 +409,24 @@ namespace llvm { roundingMode, bool *) const; opStatus convertFromUnsignedParts(const integerPart *, unsigned int, roundingMode); - opStatus convertFromHexadecimalString(const char *, roundingMode); - opStatus convertFromDecimalString (const char *, roundingMode); + opStatus convertFromHexadecimalString(StringRef, roundingMode); + opStatus convertFromDecimalString(StringRef, roundingMode); char *convertNormalToHexString(char *, unsigned int, bool, roundingMode) const; opStatus roundSignificandWithExponent(const integerPart *, unsigned int, int, roundingMode); + APInt convertHalfAPFloatToAPInt() const; APInt convertFloatAPFloatToAPInt() const; APInt convertDoubleAPFloatToAPInt() const; + APInt convertQuadrupleAPFloatToAPInt() const; APInt convertF80LongDoubleAPFloatToAPInt() const; APInt convertPPCDoubleDoubleAPFloatToAPInt() const; void initFromAPInt(const APInt& api, bool isIEEE = false); + void initFromHalfAPInt(const APInt& api); void initFromFloatAPInt(const APInt& api); void initFromDoubleAPInt(const APInt& api); + void initFromQuadrupleAPInt(const APInt &api); void initFromF80LongDoubleAPInt(const APInt& api); void initFromPPCDoubleDoubleAPInt(const APInt& api);