X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=include%2Fllvm%2FADT%2FAPFloat.h;h=c28e8e61e01b230f6cb054b45936458787d147be;hp=411d8add25f6f2e686603303a41c2f26c55d7e33;hb=674be02d525d4e24bc6943ed9274958c580bcfbc;hpb=93c276e1c92da03ce9805fd3f3814b5e9b8cd57c diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index 411d8add25f..c28e8e61e01 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -97,8 +97,8 @@ nexttoward. */ -#ifndef LLVM_FLOAT_H -#define LLVM_FLOAT_H +#ifndef LLVM_ADT_APFLOAT_H +#define LLVM_ADT_APFLOAT_H // APInt contains static functions implementing bignum arithmetic. #include "llvm/ADT/APInt.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,12 +126,13 @@ 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; static const fltSemantics PPCDoubleDouble; 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; @@ -152,8 +155,8 @@ namespace llvm { 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, @@ -163,7 +166,7 @@ namespace llvm { opInexact = 0x10 }; - /* Category of internally-represented number. */ + // Category of internally-represented number. enum fltCategory { fcInfinity, fcNaN, @@ -171,23 +174,93 @@ namespace llvm { fcZero }; - /* Constructors. */ - APFloat(const fltSemantics &, const char *); + enum uninitializedTag { + uninitialized + }; + + // Constructors. + 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); 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); + } + + /// 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; - + /// @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); @@ -196,8 +269,12 @@ namespace llvm { 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 fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode); + opStatus roundToIntegral(roundingMode); /* Sign operations. */ void changeSign(); @@ -205,17 +282,18 @@ namespace llvm { void copySign(const APFloat &); /* Conversions. */ - opStatus convert(const fltSemantics &, roundingMode); + opStatus convert(const fltSemantics &, roundingMode, bool *); opStatus convertToInteger(integerPart *, unsigned int, bool, - roundingMode) const; + 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); - APInt convertToAPInt() const; + opStatus convertFromString(StringRef, roundingMode); + APInt bitcastToAPInt() const; double convertToDouble() const; float convertToFloat() const; @@ -228,6 +306,9 @@ namespace llvm { 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, @@ -235,23 +316,59 @@ namespace llvm { 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; } + bool isNormal() const { return category == fcNormal; } 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 isDenormal() const; 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: @@ -278,32 +395,39 @@ namespace llvm { opStatus addOrSubtractSpecials(const APFloat &, bool subtract); opStatus divideSpecials(const APFloat &); opStatus multiplySpecials(const APFloat &); + 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; opStatus handleOverflow(roundingMode); bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const; opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool, - roundingMode) const; + 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); @@ -332,14 +456,11 @@ 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; }; + + // See friend declaration above. This additional declaration is required in + // order to compile LLVM with IBM xlC compiler. + hash_code hash_value(const APFloat &Arg); } /* namespace llvm */ -#endif /* LLVM_FLOAT_H */ +#endif /* LLVM_ADT_APFLOAT_H */