X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=include%2Fllvm%2FADT%2FAPFloat.h;h=3fe04060fd591712a5c810e51e54e0e809e16cb9;hb=HEAD;hp=d1043438442db4b4209dd68998413567ca0c1c30;hpb=7032c883cdf8da579fbf9bf499d36a711eef676f;p=oota-llvm.git diff --git a/include/llvm/ADT/APFloat.h b/include/llvm/ADT/APFloat.h index d1043438442..3fe04060fd5 100644 --- a/include/llvm/ADT/APFloat.h +++ b/include/llvm/ADT/APFloat.h @@ -1,4 +1,4 @@ -//== llvm/Support/APFloat.h - Arbitrary Precision Floating Point -*- C++ -*-==// +//===- llvm/ADT/APFloat.h - Arbitrary Precision Floating Point ---*- C++ -*-==// // // The LLVM Compiler Infrastructure // @@ -21,9 +21,6 @@ namespace llvm { -/// A signed type to represent a floating point numbers unbiased exponent. -typedef signed short exponent_t; - struct fltSemantics; class APSInt; class StringRef; @@ -120,11 +117,14 @@ enum lostFraction { // Example of truncated bits: /// New formats: x87 in single and double precision mode (IEEE apart from /// extended exponent range) (hard). /// -/// New operations: sqrt, IEEE remainder, C90 fmod, nextafter, nexttoward. +/// New operations: sqrt, IEEE remainder, C90 fmod, nexttoward. /// class APFloat { public: + /// A signed type to represent a floating point numbers unbiased exponent. + typedef signed short ExponentType; + /// \name Floating Point Semantics. /// @{ @@ -142,6 +142,9 @@ public: /// @} static unsigned int semanticsPrecision(const fltSemantics &); + static ExponentType semanticsMinExponent(const fltSemantics &); + static ExponentType semanticsMaxExponent(const fltSemantics &); + static unsigned int semanticsSizeInBits(const fltSemantics &); /// IEEE-754R 5.11: Floating Point Comparison Relations. enum cmpResult { @@ -191,12 +194,12 @@ public: 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); APFloat(const fltSemantics &, const APInt &); explicit APFloat(double d); explicit APFloat(float f); APFloat(const APFloat &); + APFloat(APFloat &&); ~APFloat(); /// @} @@ -211,14 +214,18 @@ public: /// /// \param Negative True iff the number should be negative. static APFloat getZero(const fltSemantics &Sem, bool Negative = false) { - return APFloat(Sem, fcZero, Negative); + APFloat Val(Sem, uninitialized); + Val.makeZero(Negative); + return Val; } /// Factory for Positive and Negative Infinity. /// /// \param Negative True iff the number should be negative. static APFloat getInf(const fltSemantics &Sem, bool Negative = false) { - return APFloat(Sem, fcInfinity, Negative); + APFloat Val(Sem, uninitialized); + Val.makeInf(Negative); + return Val; } /// Factory for QNaN values. @@ -232,19 +239,19 @@ public: APInt fill(64, type); return getQNaN(Sem, Negative, &fill); } else { - return getQNaN(Sem, Negative, 0); + return getQNaN(Sem, Negative, nullptr); } } /// Factory for QNaN values. static APFloat getQNaN(const fltSemantics &Sem, bool Negative = false, - const APInt *payload = 0) { + const APInt *payload = nullptr) { return makeNaN(Sem, false, Negative, payload); } /// Factory for SNaN values. static APFloat getSNaN(const fltSemantics &Sem, bool Negative = false, - const APInt *payload = 0) { + const APInt *payload = nullptr) { return makeNaN(Sem, true, Negative, payload); } @@ -272,18 +279,16 @@ public: /// \param isIEEE - If 128 bit number, select between PPC and IEEE static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false); + /// Returns the size of the floating point number (in bits) in the given + /// semantics. + static unsigned getSizeInBits(const fltSemantics &Sem); + /// @} /// 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); - /// \name Arithmetic /// @{ @@ -294,12 +299,46 @@ public: /// IEEE remainder. opStatus remainder(const APFloat &); /// C fmod, or llvm frem. - opStatus mod(const APFloat &, roundingMode); + opStatus mod(const APFloat &); opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode); opStatus roundToIntegral(roundingMode); /// IEEE-754R 5.3.1: nextUp/nextDown. opStatus next(bool nextDown); + /// \brief Operator+ overload which provides the default + /// \c nmNearestTiesToEven rounding mode and *no* error checking. + APFloat operator+(const APFloat &RHS) const { + APFloat Result = *this; + Result.add(RHS, rmNearestTiesToEven); + return Result; + } + + /// \brief Operator- overload which provides the default + /// \c nmNearestTiesToEven rounding mode and *no* error checking. + APFloat operator-(const APFloat &RHS) const { + APFloat Result = *this; + Result.subtract(RHS, rmNearestTiesToEven); + return Result; + } + + /// \brief Operator* overload which provides the default + /// \c nmNearestTiesToEven rounding mode and *no* error checking. + APFloat operator*(const APFloat &RHS) const { + APFloat Result = *this; + Result.multiply(RHS, rmNearestTiesToEven); + return Result; + } + + /// \brief Operator/ overload which provides the default + /// \c nmNearestTiesToEven rounding mode and *no* error checking. + APFloat operator/(const APFloat &RHS) const { + APFloat Result = *this; + Result.divide(RHS, rmNearestTiesToEven); + return Result; + } + + /// @} + /// \name Sign operations. /// @{ @@ -307,6 +346,13 @@ public: void clearSign(); void copySign(const APFloat &); + /// \brief A static helper to produce a copy of an APFloat value with its sign + /// copied from some other APFloat. + static APFloat copySign(APFloat Value, const APFloat &Sign) { + Value.copySign(Sign); + return Value; + } + /// @} /// \name Conversions @@ -331,7 +377,7 @@ public: /// The definition of equality is not straightforward for floating point, so /// we won't use operator==. Use one of the following, or write whatever it /// is you really mean. - bool operator==(const APFloat &) const LLVM_DELETED_FUNCTION; + bool operator==(const APFloat &) const = delete; /// IEEE comparison with another floating point number (NaNs compare /// unordered, 0==-0). @@ -359,10 +405,7 @@ public: /// /// This implies that the current value of the float is not zero, subnormal, /// infinite, or NaN following the definition of normality from IEEE-754R. - /// - /// The current implementation of isNormal() differs from this by treating - /// subnormal values as normal values. - bool isIEEENormal() const { return !isDenormal() && isNormal(); } + bool isNormal() const { return !isDenormal() && isFiniteNonZero(); } /// Returns true if and only if the current value is zero, subnormal, or /// normal. @@ -394,7 +437,6 @@ public: fltCategory getCategory() const { return category; } const fltSemantics &getSemantics() const { return *semantics; } bool isNonZero() const { return category != fcZero; } - bool isNormal() const { return category == fcNormal; } bool isFiniteNonZero() const { return isFinite() && !isZero(); } bool isPosZero() const { return isZero() && !isNegative(); } bool isNegZero() const { return isZero() && isNegative(); } @@ -406,10 +448,14 @@ public: /// Returns true if and only if the number has the largest possible finite /// magnitude in the current semantics. bool isLargest() const; + + /// Returns true if and only if the number is an exact integer. + bool isInteger() const; /// @} APFloat &operator=(const APFloat &); + APFloat &operator=(APFloat &&); /// \brief Overload to compute a hash code for an APFloat value. /// @@ -449,6 +495,36 @@ public: /// return true. bool getExactInverse(APFloat *inv) const; + /// \brief Enumeration of \c ilogb error results. + enum IlogbErrorKinds { + IEK_Zero = INT_MIN+1, + IEK_NaN = INT_MIN, + IEK_Inf = INT_MAX + }; + + /// \brief Returns the exponent of the internal representation of the APFloat. + /// + /// Because the radix of APFloat is 2, this is equivalent to floor(log2(x)). + /// For special APFloat values, this returns special error codes: + /// + /// NaN -> \c IEK_NaN + /// 0 -> \c IEK_Zero + /// Inf -> \c IEK_Inf + /// + friend int ilogb(const APFloat &Arg) { + if (Arg.isNaN()) + return IEK_NaN; + if (Arg.isZero()) + return IEK_Zero; + if (Arg.isInfinity()) + return IEK_Inf; + + return Arg.exponent; + } + + /// \brief Returns: X * 2^Exp for integral exponents. + friend APFloat scalbn(APFloat X, int Exp); + private: /// \name Simple Queries @@ -497,15 +573,19 @@ private: void makeLargest(bool Neg = false); void makeSmallest(bool Neg = false); - void makeNaN(bool SNaN = false, bool Neg = false, const APInt *fill = 0); + void makeNaN(bool SNaN = false, bool Neg = false, + const APInt *fill = nullptr); static APFloat makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative, const APInt *fill); + void makeInf(bool Neg = false); + void makeZero(bool Neg = false); /// @} /// \name Miscellany /// @{ + bool convertFromStringSpecials(StringRef str); opStatus normalize(roundingMode, lostFraction); opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract); cmpResult compareAbsoluteValue(const APFloat &) const; @@ -554,7 +634,7 @@ private: } significand; /// The signed unbiased exponent of the value. - exponent_t exponent; + ExponentType exponent; /// What kind of floating point number this is. /// @@ -566,11 +646,41 @@ private: unsigned int sign : 1; }; -/// See friend declaration above. +/// See friend declarations above. /// -/// This additional declaration is required in order to compile LLVM with IBM +/// These additional declarations are required in order to compile LLVM with IBM /// xlC compiler. hash_code hash_value(const APFloat &Arg); +APFloat scalbn(APFloat X, int Exp); + +/// \brief Returns the absolute value of the argument. +inline APFloat abs(APFloat X) { + X.clearSign(); + return X; +} + +/// Implements IEEE minNum semantics. Returns the smaller of the 2 arguments if +/// both are not NaN. If either argument is a NaN, returns the other argument. +LLVM_READONLY +inline APFloat minnum(const APFloat &A, const APFloat &B) { + if (A.isNaN()) + return B; + if (B.isNaN()) + return A; + return (B.compare(A) == APFloat::cmpLessThan) ? B : A; +} + +/// Implements IEEE maxNum semantics. Returns the larger of the 2 arguments if +/// both are not NaN. If either argument is a NaN, returns the other argument. +LLVM_READONLY +inline APFloat maxnum(const APFloat &A, const APFloat &B) { + if (A.isNaN()) + return B; + if (B.isNaN()) + return A; + return (A.compare(B) == APFloat::cmpLessThan) ? B : A; +} + } // namespace llvm #endif // LLVM_ADT_APFLOAT_H