Index: llvm/include/llvm/ADT/APFloat.h =================================================================== --- llvm/include/llvm/ADT/APFloat.h +++ llvm/include/llvm/ADT/APFloat.h @@ -121,9 +121,10 @@ /// /// New operations: sqrt, IEEE remainder, C90 fmod, nexttoward. /// -class APFloat { -public: +// This is the common type definitions shared by APFloat and its internal +// implementation classes. +struct APFloatStatic { /// A signed type to represent a floating point numbers unbiased exponent. typedef signed short ExponentType; @@ -143,11 +144,6 @@ /// @} - 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 { cmpLessThan, @@ -190,19 +186,40 @@ uninitialized }; + /// \brief Enumeration of \c ilogb error results. + enum IlogbErrorKinds { + IEK_Zero = INT_MIN + 1, + IEK_NaN = INT_MIN, + IEK_Inf = INT_MAX + }; + + static unsigned int semanticsPrecision(const fltSemantics &); + static ExponentType semanticsMinExponent(const fltSemantics &); + static ExponentType semanticsMaxExponent(const fltSemantics &); + static unsigned int semanticsSizeInBits(const fltSemantics &); + + /// Returns the size of the floating point number (in bits) in the given + /// semantics. + static unsigned getSizeInBits(const fltSemantics &Sem); +}; + +namespace detail { + +class IEEEFloat : public APFloatStatic { +public: /// \name Constructors /// @{ - APFloat(const fltSemantics &); // Default construct to 0.0 - APFloat(const fltSemantics &, StringRef); - APFloat(const fltSemantics &, integerPart); - APFloat(const fltSemantics &, uninitializedTag); - APFloat(const fltSemantics &, const APInt &); - explicit APFloat(double d); - explicit APFloat(float f); - APFloat(const APFloat &); - APFloat(APFloat &&); - ~APFloat(); + IEEEFloat(const fltSemantics &); // Default construct to 0.0 + IEEEFloat(const fltSemantics &, StringRef); + IEEEFloat(const fltSemantics &, integerPart); + IEEEFloat(const fltSemantics &, uninitializedTag); + IEEEFloat(const fltSemantics &, const APInt &); + explicit IEEEFloat(double d); + explicit IEEEFloat(float f); + IEEEFloat(const IEEEFloat &); + IEEEFloat(IEEEFloat &&); + ~IEEEFloat(); /// @} @@ -215,8 +232,8 @@ /// Factory for Positive and Negative Zero. /// /// \param Negative True iff the number should be negative. - static APFloat getZero(const fltSemantics &Sem, bool Negative = false) { - APFloat Val(Sem, uninitialized); + static IEEEFloat getZero(const fltSemantics &Sem, bool Negative = false) { + IEEEFloat Val(Sem, uninitialized); Val.makeZero(Negative); return Val; } @@ -224,8 +241,8 @@ /// Factory for Positive and Negative Infinity. /// /// \param Negative True iff the number should be negative. - static APFloat getInf(const fltSemantics &Sem, bool Negative = false) { - APFloat Val(Sem, uninitialized); + static IEEEFloat getInf(const fltSemantics &Sem, bool Negative = false) { + IEEEFloat Val(Sem, uninitialized); Val.makeInf(Negative); return Val; } @@ -235,8 +252,8 @@ /// \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) { + static IEEEFloat getNaN(const fltSemantics &Sem, bool Negative = false, + unsigned type = 0) { if (type) { APInt fill(64, type); return getQNaN(Sem, Negative, &fill); @@ -246,44 +263,40 @@ } /// Factory for QNaN values. - static APFloat getQNaN(const fltSemantics &Sem, bool Negative = false, - const APInt *payload = nullptr) { + static IEEEFloat getQNaN(const fltSemantics &Sem, bool Negative = false, + 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 = nullptr) { + static IEEEFloat getSNaN(const fltSemantics &Sem, bool Negative = false, + const APInt *payload = nullptr) { return makeNaN(Sem, true, Negative, payload); } /// 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); + static IEEEFloat getLargest(const fltSemantics &Sem, bool Negative = false); /// 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); + static IEEEFloat getSmallest(const fltSemantics &Sem, bool Negative = false); /// 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); + static IEEEFloat getSmallestNormalized(const fltSemantics &Sem, + bool Negative = false); /// 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); - - /// Returns the size of the floating point number (in bits) in the given - /// semantics. - static unsigned getSizeInBits(const fltSemantics &Sem); + static IEEEFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false); /// @} @@ -294,47 +307,47 @@ /// \name Arithmetic /// @{ - opStatus add(const APFloat &, roundingMode); - opStatus subtract(const APFloat &, roundingMode); - opStatus multiply(const APFloat &, roundingMode); - opStatus divide(const APFloat &, roundingMode); + opStatus add(const IEEEFloat &, roundingMode); + opStatus subtract(const IEEEFloat &, roundingMode); + opStatus multiply(const IEEEFloat &, roundingMode); + opStatus divide(const IEEEFloat &, roundingMode); /// IEEE remainder. - opStatus remainder(const APFloat &); + opStatus remainder(const IEEEFloat &); /// C fmod, or llvm frem. - opStatus mod(const APFloat &); - opStatus fusedMultiplyAdd(const APFloat &, const APFloat &, roundingMode); + opStatus mod(const IEEEFloat &); + opStatus fusedMultiplyAdd(const IEEEFloat &, const IEEEFloat &, 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; + IEEEFloat operator+(const IEEEFloat &RHS) const { + IEEEFloat 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; + IEEEFloat operator-(const IEEEFloat &RHS) const { + IEEEFloat 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; + IEEEFloat operator*(const IEEEFloat &RHS) const { + IEEEFloat 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; + IEEEFloat operator/(const IEEEFloat &RHS) const { + IEEEFloat Result = *this; Result.divide(RHS, rmNearestTiesToEven); return Result; } @@ -346,11 +359,11 @@ void changeSign(); void clearSign(); - void copySign(const APFloat &); + void copySign(const IEEEFloat &); /// \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) { + static IEEEFloat copySign(IEEEFloat Value, const IEEEFloat &Sign) { Value.copySign(Sign); return Value; } @@ -379,14 +392,14 @@ /// 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 = delete; + bool operator==(const IEEEFloat &) const = delete; /// IEEE comparison with another floating point number (NaNs compare /// unordered, 0==-0). - cmpResult compare(const APFloat &) const; + cmpResult compare(const IEEEFloat &) const; /// Bitwise comparison for equality (QNaNs compare equal, 0!=-0). - bool bitwiseIsEqual(const APFloat &) const; + bool bitwiseIsEqual(const IEEEFloat &) 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. @@ -456,8 +469,8 @@ /// @} - APFloat &operator=(const APFloat &); - APFloat &operator=(APFloat &&); + IEEEFloat &operator=(const IEEEFloat &); + IEEEFloat &operator=(IEEEFloat &&); /// \brief Overload to compute a hash code for an APFloat value. /// @@ -468,7 +481,7 @@ /// 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); + friend hash_code hash_value(const IEEEFloat &Arg); /// Converts this value into a decimal string. /// @@ -495,14 +508,7 @@ /// If this value has an exact multiplicative inverse, store it in inv and /// 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 - }; + bool getExactInverse(IEEEFloat *inv) const; /// \brief Returns the exponent of the internal representation of the APFloat. /// @@ -513,15 +519,14 @@ /// 0 -> \c IEK_Zero /// Inf -> \c IEK_Inf /// - friend int ilogb(const APFloat &Arg); + friend int ilogb(const IEEEFloat &Arg); /// \brief Returns: X * 2^Exp for integral exponents. - friend APFloat scalbn(APFloat X, int Exp, roundingMode); + friend IEEEFloat scalbn(IEEEFloat X, int Exp, roundingMode); - friend APFloat frexp(const APFloat &X, int &Exp, roundingMode); + friend IEEEFloat frexp(const IEEEFloat &X, int &Exp, roundingMode); private: - /// \name Simple Queries /// @{ @@ -534,11 +539,11 @@ /// \name Significand operations. /// @{ - integerPart addSignificand(const APFloat &); - integerPart subtractSignificand(const APFloat &, integerPart); - lostFraction addOrSubtractSignificand(const APFloat &, bool subtract); - lostFraction multiplySignificand(const APFloat &, const APFloat *); - lostFraction divideSignificand(const APFloat &); + integerPart addSignificand(const IEEEFloat &); + integerPart subtractSignificand(const IEEEFloat &, integerPart); + lostFraction addOrSubtractSignificand(const IEEEFloat &, bool subtract); + lostFraction multiplySignificand(const IEEEFloat &, const IEEEFloat *); + lostFraction divideSignificand(const IEEEFloat &); void incrementSignificand(); void initialize(const fltSemantics *); void shiftSignificandLeft(unsigned int); @@ -556,10 +561,10 @@ /// \name Arithmetic on special values. /// @{ - opStatus addOrSubtractSpecials(const APFloat &, bool subtract); - opStatus divideSpecials(const APFloat &); - opStatus multiplySpecials(const APFloat &); - opStatus modSpecials(const APFloat &); + opStatus addOrSubtractSpecials(const IEEEFloat &, bool subtract); + opStatus divideSpecials(const IEEEFloat &); + opStatus multiplySpecials(const IEEEFloat &); + opStatus modSpecials(const IEEEFloat &); /// @} @@ -570,8 +575,8 @@ void makeSmallest(bool Neg = false); 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); + static IEEEFloat makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative, + const APInt *fill); void makeInf(bool Neg = false); void makeZero(bool Neg = false); void makeQuiet(); @@ -583,8 +588,8 @@ bool convertFromStringSpecials(StringRef str); opStatus normalize(roundingMode, lostFraction); - opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract); - cmpResult compareAbsoluteValue(const APFloat &) const; + opStatus addOrSubtract(const IEEEFloat &, roundingMode, bool subtract); + cmpResult compareAbsoluteValue(const IEEEFloat &) const; opStatus handleOverflow(roundingMode); bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const; opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool, @@ -614,8 +619,8 @@ void initFromF80LongDoubleAPInt(const APInt &api); void initFromPPCDoubleDoubleAPInt(const APInt &api); - void assign(const APFloat &); - void copySignificand(const APFloat &); + void assign(const IEEEFloat &); + void copySignificand(const IEEEFloat &); void freeSignificand(); /// The semantics that this value obeys. @@ -642,20 +647,238 @@ unsigned int sign : 1; }; +hash_code hash_value(const IEEEFloat &Arg); +int ilogb(const IEEEFloat &Arg); +IEEEFloat scalbn(IEEEFloat X, int Exp, IEEEFloat::roundingMode); +IEEEFloat frexp(const IEEEFloat &Val, int &Exp, IEEEFloat::roundingMode RM); + +} // End detail namespace + +// This is a interface class that is currently forwarding functionalities from +// detail::IEEEFloat. +class APFloat : public APFloatStatic { + typedef detail::IEEEFloat IEEEFloat; + + static_assert(std::is_standard_layout::value, ""); + + union { + const fltSemantics *semantics; + IEEEFloat IEEE; + }; + + explicit APFloat(IEEEFloat F) : IEEE(std::move(F)) {} + +public: + APFloat(const fltSemantics &Semantics) : APFloat(IEEEFloat(Semantics)) {} + APFloat(const fltSemantics &Semantics, StringRef S); + APFloat(const fltSemantics &Semantics, integerPart I) + : APFloat(IEEEFloat(Semantics, I)) {} + APFloat(const fltSemantics &Semantics, uninitializedTag U) + : APFloat(IEEEFloat(Semantics, U)) {} + APFloat(const fltSemantics &Semantics, const APInt &I) + : APFloat(IEEEFloat(Semantics, I)) {} + explicit APFloat(double d) : APFloat(IEEEFloat(d)) {} + explicit APFloat(float f) : APFloat(IEEEFloat(f)) {} + APFloat(const APFloat &RHS) : APFloat(IEEEFloat(RHS.IEEE)) {} + APFloat(APFloat &&RHS) : APFloat(IEEEFloat(std::move(RHS.IEEE))) {} + + ~APFloat() { IEEE.~IEEEFloat(); } + + bool needsCleanup() const { return IEEE.needsCleanup(); } + + static APFloat getZero(const fltSemantics &Sem, bool Negative = false) { + return APFloat(IEEEFloat::getZero(Sem, Negative)); + } + + static APFloat getInf(const fltSemantics &Sem, bool Negative = false) { + return APFloat(IEEEFloat::getInf(Sem, Negative)); + } + + static APFloat getNaN(const fltSemantics &Sem, bool Negative = false, + unsigned type = 0) { + return APFloat(IEEEFloat::getNaN(Sem, Negative, type)); + } + + static APFloat getQNaN(const fltSemantics &Sem, bool Negative = false, + const APInt *payload = nullptr) { + return APFloat(IEEEFloat::getQNaN(Sem, Negative, payload)); + } + + static APFloat getSNaN(const fltSemantics &Sem, bool Negative = false, + const APInt *payload = nullptr) { + return APFloat(IEEEFloat::getSNaN(Sem, Negative, payload)); + } + + static APFloat getLargest(const fltSemantics &Sem, bool Negative = false) { + return APFloat(IEEEFloat::getLargest(Sem, Negative)); + } + + static APFloat getSmallest(const fltSemantics &Sem, bool Negative = false) { + return APFloat(IEEEFloat::getSmallest(Sem, Negative)); + } + + static APFloat getSmallestNormalized(const fltSemantics &Sem, + bool Negative = false) { + return APFloat(IEEEFloat::getSmallestNormalized(Sem, Negative)); + } + + static APFloat getAllOnesValue(unsigned BitWidth, bool isIEEE = false) { + return APFloat(IEEEFloat::getAllOnesValue(BitWidth, isIEEE)); + } + + void Profile(FoldingSetNodeID &NID) const { IEEE.Profile(NID); } + + opStatus add(const APFloat &RHS, roundingMode RM) { + return IEEE.add(RHS.IEEE, RM); + } + opStatus subtract(const APFloat &RHS, roundingMode RM) { + return IEEE.subtract(RHS.IEEE, RM); + } + opStatus multiply(const APFloat &RHS, roundingMode RM) { + return IEEE.multiply(RHS.IEEE, RM); + } + opStatus divide(const APFloat &RHS, roundingMode RM) { + return IEEE.divide(RHS.IEEE, RM); + } + opStatus remainder(const APFloat &RHS) { return IEEE.remainder(RHS.IEEE); } + opStatus mod(const APFloat &RHS) { return IEEE.mod(RHS.IEEE); } + opStatus fusedMultiplyAdd(const APFloat &Multiplicand, const APFloat &Addend, + roundingMode RM) { + return IEEE.fusedMultiplyAdd(Multiplicand.IEEE, Addend.IEEE, RM); + } + opStatus roundToIntegral(roundingMode RM) { return IEEE.roundToIntegral(RM); } + opStatus next(bool nextDown) { return IEEE.next(nextDown); } + + APFloat operator+(const APFloat &RHS) const { + return APFloat(IEEE + RHS.IEEE); + } + + APFloat operator-(const APFloat &RHS) const { + return APFloat(IEEE - RHS.IEEE); + } + + APFloat operator*(const APFloat &RHS) const { + return APFloat(IEEE * RHS.IEEE); + } + + APFloat operator/(const APFloat &RHS) const { + return APFloat(IEEE / RHS.IEEE); + } + + void changeSign() { IEEE.changeSign(); } + void clearSign() { IEEE.clearSign(); } + void copySign(const APFloat &RHS) { IEEE.copySign(RHS.IEEE); } + + static APFloat copySign(APFloat Value, const APFloat &Sign) { + return APFloat(IEEEFloat::copySign(Value.IEEE, Sign.IEEE)); + } + + opStatus convert(const fltSemantics &ToSemantics, roundingMode RM, + bool *losesInfo) { + return IEEE.convert(ToSemantics, RM, losesInfo); + } + opStatus convertToInteger(integerPart *Input, unsigned int Width, + bool IsSigned, roundingMode RM, + bool *IsExact) const { + return IEEE.convertToInteger(Input, Width, IsSigned, RM, IsExact); + } + opStatus convertToInteger(APSInt &Result, roundingMode RM, + bool *IsExact) const { + return IEEE.convertToInteger(Result, RM, IsExact); + } + opStatus convertFromAPInt(const APInt &Input, bool IsSigned, + roundingMode RM) { + return IEEE.convertFromAPInt(Input, IsSigned, RM); + } + opStatus convertFromSignExtendedInteger(const integerPart *Input, + unsigned int InputSize, bool IsSigned, + roundingMode RM) { + return IEEE.convertFromSignExtendedInteger(Input, InputSize, IsSigned, RM); + } + opStatus convertFromZeroExtendedInteger(const integerPart *Input, + unsigned int InputSize, bool IsSigned, + roundingMode RM) { + return IEEE.convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM); + } + opStatus convertFromString(StringRef, roundingMode); + APInt bitcastToAPInt() const { return IEEE.bitcastToAPInt(); } + double convertToDouble() const { return IEEE.convertToDouble(); } + float convertToFloat() const { return IEEE.convertToFloat(); } + + bool operator==(const APFloat &) const = delete; + + cmpResult compare(const APFloat &RHS) const { return IEEE.compare(RHS.IEEE); } + + bool bitwiseIsEqual(const APFloat &RHS) const { + return IEEE.bitwiseIsEqual(RHS.IEEE); + } + + unsigned int convertToHexString(char *DST, unsigned int HexDigits, + bool UpperCase, roundingMode RM) const { + return IEEE.convertToHexString(DST, HexDigits, UpperCase, RM); + } + + bool isZero() const { return getCategory() == fcZero; } + bool isInfinity() const { return getCategory() == fcInfinity; } + bool isNaN() const { return getCategory() == fcNaN; } + + bool isNegative() const { return IEEE.isNegative(); } + bool isDenormal() const { return IEEE.isDenormal(); } + bool isSignaling() const { return IEEE.isSignaling(); } + + bool isNormal() const { return !isDenormal() && isFiniteNonZero(); } + bool isFinite() const { return !isNaN() && !isInfinity(); } + + fltCategory getCategory() const { return IEEE.getCategory(); } + const fltSemantics &getSemantics() const { return *semantics; } + bool isNonZero() const { return !isZero(); } + bool isFiniteNonZero() const { return isFinite() && !isZero(); } + bool isPosZero() const { return isZero() && !isNegative(); } + bool isNegZero() const { return isZero() && isNegative(); } + bool isSmallest() const { return IEEE.isSmallest(); } + bool isLargest() const { return IEEE.isLargest(); } + bool isInteger() const { return IEEE.isInteger(); } + + APFloat &operator=(const APFloat &RHS) { + IEEE = RHS.IEEE; + return *this; + } + APFloat &operator=(APFloat &&RHS) { + IEEE = std::move(RHS.IEEE); + return *this; + } + + void toString(SmallVectorImpl &Str, unsigned FormatPrecision = 0, + unsigned FormatMaxPadding = 3) const { + return IEEE.toString(Str, FormatPrecision, FormatMaxPadding); + } + + bool getExactInverse(APFloat *inv) const { + return IEEE.getExactInverse(&inv->IEEE); + } + + friend hash_code hash_value(const APFloat &Arg); + friend int ilogb(const APFloat &Arg) { return ilogb(Arg.IEEE); } + friend APFloat scalbn(APFloat X, int Exp, roundingMode RM); + friend APFloat frexp(const APFloat &X, int &Exp, roundingMode RM); +}; + /// See friend declarations above. /// /// These additional declarations are required in order to compile LLVM with IBM /// xlC compiler. hash_code hash_value(const APFloat &Arg); -int ilogb(const APFloat &Arg); -APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode); +inline APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM) { + return APFloat(scalbn(X.IEEE, Exp, RM)); +} /// \brief Equivalent of C standard library function. /// /// While the C standard says Exp is an unspecified value for infinity and nan, /// this returns INT_MAX for infinities, and INT_MIN for NaNs. -APFloat frexp(const APFloat &Val, int &Exp, APFloat::roundingMode RM); - +inline APFloat frexp(const APFloat &X, int &Exp, APFloat::roundingMode RM) { + return APFloat(frexp(X.IEEE, Exp, RM)); +} /// \brief Returns the absolute value of the argument. inline APFloat abs(APFloat X) { X.clearSign(); Index: llvm/lib/Support/APFloat.cpp =================================================================== --- llvm/lib/Support/APFloat.cpp +++ llvm/lib/Support/APFloat.cpp @@ -39,16 +39,15 @@ static_assert(integerPartWidth % 4 == 0, "Part width must be divisible by 4!"); namespace llvm { - /* Represents floating point arithmetic semantics. */ struct fltSemantics { /* The largest E such that 2^E is representable; this matches the definition of IEEE 754. */ - APFloat::ExponentType maxExponent; + APFloatStatic::ExponentType maxExponent; /* The smallest E such that 2^E is a normalized number; this matches the definition of IEEE 754. */ - APFloat::ExponentType minExponent; + APFloatStatic::ExponentType minExponent; /* Number of bits in the significand. This includes the integer bit. */ @@ -58,12 +57,12 @@ unsigned int sizeInBits; }; - const fltSemantics APFloat::IEEEhalf = { 15, -14, 11, 16 }; - const fltSemantics APFloat::IEEEsingle = { 127, -126, 24, 32 }; - const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53, 64 }; - const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, 128 }; - const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64, 80 }; - const fltSemantics APFloat::Bogus = { 0, 0, 0, 0 }; + const fltSemantics APFloatStatic::IEEEhalf = {15, -14, 11, 16}; + const fltSemantics APFloatStatic::IEEEsingle = {127, -126, 24, 32}; + const fltSemantics APFloatStatic::IEEEdouble = {1023, -1022, 53, 64}; + const fltSemantics APFloatStatic::IEEEquad = {16383, -16382, 113, 128}; + const fltSemantics APFloatStatic::x87DoubleExtended = {16383, -16382, 64, 80}; + const fltSemantics APFloatStatic::Bogus = {0, 0, 0, 0}; /* The PowerPC format consists of two doubles. It does not map cleanly onto the usual format above. It is approximated using twice the @@ -76,7 +75,8 @@ to represent all possible values held by a PPC double-double number, for example: (long double) 1.0 + (long double) 0x1p-106 Should this be replaced by a full emulation of PPC double-double? */ - const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022 + 53, 53 + 53, 128 }; + const fltSemantics APFloatStatic::PPCDoubleDouble = {1023, -1022 + 53, + 53 + 53, 128}; /* A tight upper bound on number of parts required to hold the value pow(5, power) is @@ -94,6 +94,26 @@ const unsigned int maxPowerOfFiveExponent = maxExponent + maxPrecision - 1; const unsigned int maxPowerOfFiveParts = 2 + ((maxPowerOfFiveExponent * 815) / (351 * integerPartWidth)); + + unsigned int + APFloatStatic::semanticsPrecision(const fltSemantics &semantics) { + return semantics.precision; + } + APFloatStatic::ExponentType + APFloatStatic::semanticsMaxExponent(const fltSemantics &semantics) { + return semantics.maxExponent; + } + APFloatStatic::ExponentType + APFloatStatic::semanticsMinExponent(const fltSemantics &semantics) { + return semantics.minExponent; + } + unsigned int + APFloatStatic::semanticsSizeInBits(const fltSemantics &semantics) { + return semantics.sizeInBits; + } + + unsigned APFloatStatic::getSizeInBits(const fltSemantics &Sem) { + return Sem.sizeInBits; } /* A bunch of private, handy routines. */ @@ -576,10 +596,9 @@ return dst; } +namespace detail { /* Constructors. */ -void -APFloat::initialize(const fltSemantics *ourSemantics) -{ +void IEEEFloat::initialize(const fltSemantics *ourSemantics) { unsigned int count; semantics = ourSemantics; @@ -588,16 +607,12 @@ significand.parts = new integerPart[count]; } -void -APFloat::freeSignificand() -{ +void IEEEFloat::freeSignificand() { if (needsCleanup()) delete [] significand.parts; } -void -APFloat::assign(const APFloat &rhs) -{ +void IEEEFloat::assign(const IEEEFloat &rhs) { assert(semantics == rhs.semantics); sign = rhs.sign; @@ -607,9 +622,7 @@ copySignificand(rhs); } -void -APFloat::copySignificand(const APFloat &rhs) -{ +void IEEEFloat::copySignificand(const IEEEFloat &rhs) { assert(isFiniteNonZero() || category == fcNaN); assert(rhs.partCount() >= partCount()); @@ -620,8 +633,7 @@ /* Make this number a NaN, with an arbitrary but deterministic value for the significand. If double or longer, this is a signalling NaN, which may not be ideal. If float, this is QNaN(0). */ -void APFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill) -{ +void IEEEFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill) { category = fcNaN; sign = Negative; @@ -667,16 +679,14 @@ APInt::tcSetBit(significand, QNaNBit + 1); } -APFloat APFloat::makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative, - const APInt *fill) { - APFloat value(Sem, uninitialized); +IEEEFloat IEEEFloat::makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative, + const APInt *fill) { + IEEEFloat value(Sem, uninitialized); value.makeNaN(SNaN, Negative, fill); return value; } -APFloat & -APFloat::operator=(const APFloat &rhs) -{ +IEEEFloat &IEEEFloat::operator=(const IEEEFloat &rhs) { if (this != &rhs) { if (semantics != rhs.semantics) { freeSignificand(); @@ -688,8 +698,7 @@ return *this; } -APFloat & -APFloat::operator=(APFloat &&rhs) { +IEEEFloat &IEEEFloat::operator=(IEEEFloat &&rhs) { freeSignificand(); semantics = rhs.semantics; @@ -702,15 +711,13 @@ return *this; } -bool -APFloat::isDenormal() const { +bool IEEEFloat::isDenormal() const { return isFiniteNonZero() && (exponent == semantics->minExponent) && (APInt::tcExtractBit(significandParts(), semantics->precision - 1) == 0); } -bool -APFloat::isSmallest() const { +bool IEEEFloat::isSmallest() const { // The smallest number by magnitude in our format will be the smallest // denormal, i.e. the floating point number with exponent being minimum // exponent and significand bitwise equal to 1 (i.e. with MSB equal to 0). @@ -718,7 +725,7 @@ significandMSB() == 0; } -bool APFloat::isSignificandAllOnes() const { +bool IEEEFloat::isSignificandAllOnes() const { // Test if the significand excluding the integral bit is all ones. This allows // us to test for binade boundaries. const integerPart *Parts = significandParts(); @@ -740,7 +747,7 @@ return true; } -bool APFloat::isSignificandAllZeros() const { +bool IEEEFloat::isSignificandAllZeros() const { // Test if the significand excluding the integral bit is all zeros. This // allows us to test for binade boundaries. const integerPart *Parts = significandParts(); @@ -762,25 +769,22 @@ return true; } -bool -APFloat::isLargest() const { +bool IEEEFloat::isLargest() const { // The largest number by magnitude in our format will be the floating point // number with maximum exponent and with significand that is all ones. return isFiniteNonZero() && exponent == semantics->maxExponent && isSignificandAllOnes(); } -bool -APFloat::isInteger() const { +bool IEEEFloat::isInteger() const { // This could be made more efficient; I'm going for obviously correct. if (!isFinite()) return false; - APFloat truncated = *this; + IEEEFloat truncated = *this; truncated.roundToIntegral(rmTowardZero); return compare(truncated) == cmpEqual; } -bool -APFloat::bitwiseIsEqual(const APFloat &rhs) const { +bool IEEEFloat::bitwiseIsEqual(const IEEEFloat &rhs) const { if (this == &rhs) return true; if (semantics != rhs.semantics || @@ -797,7 +801,7 @@ rhs.significandParts()); } -APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) { +IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, integerPart value) { initialize(&ourSemantics); sign = 0; category = fcNormal; @@ -807,93 +811,59 @@ normalize(rmNearestTiesToEven, lfExactlyZero); } -APFloat::APFloat(const fltSemantics &ourSemantics) { +IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics) { initialize(&ourSemantics); category = fcZero; sign = false; } -APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) { +IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, uninitializedTag tag) { // Allocates storage if necessary but does not initialize it. initialize(&ourSemantics); } -APFloat::APFloat(const fltSemantics &ourSemantics, StringRef text) { +IEEEFloat::IEEEFloat(const fltSemantics &ourSemantics, StringRef text) { initialize(&ourSemantics); convertFromString(text, rmNearestTiesToEven); } -APFloat::APFloat(const APFloat &rhs) { +IEEEFloat::IEEEFloat(const IEEEFloat &rhs) { initialize(rhs.semantics); assign(rhs); } -APFloat::APFloat(APFloat &&rhs) : semantics(&Bogus) { +IEEEFloat::IEEEFloat(IEEEFloat &&rhs) : semantics(&Bogus) { *this = std::move(rhs); } -APFloat::~APFloat() -{ - freeSignificand(); -} +IEEEFloat::~IEEEFloat() { freeSignificand(); } // Profile - This method 'profiles' an APFloat for use with FoldingSet. -void APFloat::Profile(FoldingSetNodeID& ID) const { +void IEEEFloat::Profile(FoldingSetNodeID &ID) const { ID.Add(bitcastToAPInt()); } -unsigned int -APFloat::partCount() const -{ +unsigned int IEEEFloat::partCount() const { return partCountForBits(semantics->precision + 1); } -unsigned int -APFloat::semanticsPrecision(const fltSemantics &semantics) -{ - return semantics.precision; -} -APFloat::ExponentType -APFloat::semanticsMaxExponent(const fltSemantics &semantics) -{ - return semantics.maxExponent; -} -APFloat::ExponentType -APFloat::semanticsMinExponent(const fltSemantics &semantics) -{ - return semantics.minExponent; -} -unsigned int -APFloat::semanticsSizeInBits(const fltSemantics &semantics) -{ - return semantics.sizeInBits; -} - -const integerPart * -APFloat::significandParts() const -{ - return const_cast(this)->significandParts(); +const integerPart *IEEEFloat::significandParts() const { + return const_cast(this)->significandParts(); } -integerPart * -APFloat::significandParts() -{ +integerPart *IEEEFloat::significandParts() { if (partCount() > 1) return significand.parts; else return &significand.part; } -void -APFloat::zeroSignificand() -{ +void IEEEFloat::zeroSignificand() { APInt::tcSet(significandParts(), 0, partCount()); } /* Increment an fcNormal floating point number's significand. */ -void -APFloat::incrementSignificand() -{ +void IEEEFloat::incrementSignificand() { integerPart carry; carry = APInt::tcIncrement(significandParts(), partCount()); @@ -904,9 +874,7 @@ } /* Add the significand of the RHS. Returns the carry flag. */ -integerPart -APFloat::addSignificand(const APFloat &rhs) -{ +integerPart IEEEFloat::addSignificand(const IEEEFloat &rhs) { integerPart *parts; parts = significandParts(); @@ -919,9 +887,8 @@ /* Subtract the significand of the RHS with a borrow flag. Returns the borrow flag. */ -integerPart -APFloat::subtractSignificand(const APFloat &rhs, integerPart borrow) -{ +integerPart IEEEFloat::subtractSignificand(const IEEEFloat &rhs, + integerPart borrow) { integerPart *parts; parts = significandParts(); @@ -936,9 +903,8 @@ /* Multiply the significand of the RHS. If ADDEND is non-NULL, add it on to the full-precision result of the multiplication. Returns the lost fraction. */ -lostFraction -APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) -{ +lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs, + const IEEEFloat *addend) { unsigned int omsb; // One, not zero, based MSB. unsigned int partsCount, newPartsCount, precision; integerPart *lhsSignificand; @@ -1011,7 +977,7 @@ significand.parts = fullSignificand; semantics = &extendedSemantics; - APFloat extendedAddend(*addend); + IEEEFloat extendedAddend(*addend); status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored); assert(status == opOK); (void)status; @@ -1045,7 +1011,8 @@ // the radix point (i.e. "MSB . rest-significant-bits"). // // Note that the result is not normalized when "omsb < precision". So, the - // caller needs to call APFloat::normalize() if normalized value is expected. + // caller needs to call IEEEFloat::normalize() if normalized value is + // expected. if (omsb > precision) { unsigned int bits, significantParts; lostFraction lf; @@ -1066,9 +1033,7 @@ } /* Multiply the significands of LHS and RHS to DST. */ -lostFraction -APFloat::divideSignificand(const APFloat &rhs) -{ +lostFraction IEEEFloat::divideSignificand(const IEEEFloat &rhs) { unsigned int bit, i, partsCount; const integerPart *rhsSignificand; integerPart *lhsSignificand, *dividend, *divisor; @@ -1150,22 +1115,16 @@ return lost_fraction; } -unsigned int -APFloat::significandMSB() const -{ +unsigned int IEEEFloat::significandMSB() const { return APInt::tcMSB(significandParts(), partCount()); } -unsigned int -APFloat::significandLSB() const -{ +unsigned int IEEEFloat::significandLSB() const { return APInt::tcLSB(significandParts(), partCount()); } /* Note that a zero result is NOT normalized to fcZero. */ -lostFraction -APFloat::shiftSignificandRight(unsigned int bits) -{ +lostFraction IEEEFloat::shiftSignificandRight(unsigned int bits) { /* Our exponent should not overflow. */ assert((ExponentType) (exponent + bits) >= exponent); @@ -1175,9 +1134,7 @@ } /* Shift the significand left BITS bits, subtract BITS from its exponent. */ -void -APFloat::shiftSignificandLeft(unsigned int bits) -{ +void IEEEFloat::shiftSignificandLeft(unsigned int bits) { assert(bits < semantics->precision); if (bits) { @@ -1190,9 +1147,8 @@ } } -APFloat::cmpResult -APFloat::compareAbsoluteValue(const APFloat &rhs) const -{ +IEEEFloat::cmpResult +IEEEFloat::compareAbsoluteValue(const IEEEFloat &rhs) const { int compare; assert(semantics == rhs.semantics); @@ -1217,9 +1173,7 @@ /* Handle overflow. Sign is preserved. We either become infinity or the largest finite number. */ -APFloat::opStatus -APFloat::handleOverflow(roundingMode rounding_mode) -{ +IEEEFloat::opStatus IEEEFloat::handleOverflow(roundingMode rounding_mode) { /* Infinity? */ if (rounding_mode == rmNearestTiesToEven || rounding_mode == rmNearestTiesToAway || @@ -1243,11 +1197,9 @@ would need to be rounded away from zero (i.e., by increasing the signficand). This routine must work for fcZero of both signs, and fcNormal numbers. */ -bool -APFloat::roundAwayFromZero(roundingMode rounding_mode, - lostFraction lost_fraction, - unsigned int bit) const -{ +bool IEEEFloat::roundAwayFromZero(roundingMode rounding_mode, + lostFraction lost_fraction, + unsigned int bit) const { /* NaNs and infinities should not have lost fractions. */ assert(isFiniteNonZero() || category == fcZero); @@ -1280,10 +1232,8 @@ llvm_unreachable("Invalid rounding mode found"); } -APFloat::opStatus -APFloat::normalize(roundingMode rounding_mode, - lostFraction lost_fraction) -{ +IEEEFloat::opStatus IEEEFloat::normalize(roundingMode rounding_mode, + lostFraction lost_fraction) { unsigned int omsb; /* One, not zero, based MSB. */ int exponentChange; @@ -1388,9 +1338,8 @@ return (opStatus) (opUnderflow | opInexact); } -APFloat::opStatus -APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract) -{ +IEEEFloat::opStatus IEEEFloat::addOrSubtractSpecials(const IEEEFloat &rhs, + bool subtract) { switch (PackCategoriesIntoKey(category, rhs.category)) { default: llvm_unreachable(nullptr); @@ -1445,9 +1394,8 @@ } /* Add or subtract two normal numbers. */ -lostFraction -APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract) -{ +lostFraction IEEEFloat::addOrSubtractSignificand(const IEEEFloat &rhs, + bool subtract) { integerPart carry; lostFraction lost_fraction; int bits; @@ -1461,7 +1409,7 @@ /* Subtraction is more subtle than one might naively expect. */ if (subtract) { - APFloat temp_rhs(rhs); + IEEEFloat temp_rhs(rhs); bool reverse; if (bits == 0) { @@ -1500,7 +1448,7 @@ (void)carry; } else { if (bits > 0) { - APFloat temp_rhs(rhs); + IEEEFloat temp_rhs(rhs); lost_fraction = temp_rhs.shiftSignificandRight(bits); carry = addSignificand(temp_rhs); @@ -1517,9 +1465,7 @@ return lost_fraction; } -APFloat::opStatus -APFloat::multiplySpecials(const APFloat &rhs) -{ +IEEEFloat::opStatus IEEEFloat::multiplySpecials(const IEEEFloat &rhs) { switch (PackCategoriesIntoKey(category, rhs.category)) { default: llvm_unreachable(nullptr); @@ -1561,9 +1507,7 @@ } } -APFloat::opStatus -APFloat::divideSpecials(const APFloat &rhs) -{ +IEEEFloat::opStatus IEEEFloat::divideSpecials(const IEEEFloat &rhs) { switch (PackCategoriesIntoKey(category, rhs.category)) { default: llvm_unreachable(nullptr); @@ -1602,9 +1546,7 @@ } } -APFloat::opStatus -APFloat::modSpecials(const APFloat &rhs) -{ +IEEEFloat::opStatus IEEEFloat::modSpecials(const IEEEFloat &rhs) { switch (PackCategoriesIntoKey(category, rhs.category)) { default: llvm_unreachable(nullptr); @@ -1640,32 +1582,25 @@ } /* Change sign. */ -void -APFloat::changeSign() -{ +void IEEEFloat::changeSign() { /* Look mummy, this one's easy. */ sign = !sign; } -void -APFloat::clearSign() -{ +void IEEEFloat::clearSign() { /* So is this one. */ sign = 0; } -void -APFloat::copySign(const APFloat &rhs) -{ +void IEEEFloat::copySign(const IEEEFloat &rhs) { /* And this one. */ sign = rhs.sign; } /* Normalized addition or subtraction. */ -APFloat::opStatus -APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode, - bool subtract) -{ +IEEEFloat::opStatus IEEEFloat::addOrSubtract(const IEEEFloat &rhs, + roundingMode rounding_mode, + bool subtract) { opStatus fs; fs = addOrSubtractSpecials(rhs, subtract); @@ -1693,23 +1628,20 @@ } /* Normalized addition. */ -APFloat::opStatus -APFloat::add(const APFloat &rhs, roundingMode rounding_mode) -{ +IEEEFloat::opStatus IEEEFloat::add(const IEEEFloat &rhs, + roundingMode rounding_mode) { return addOrSubtract(rhs, rounding_mode, false); } /* Normalized subtraction. */ -APFloat::opStatus -APFloat::subtract(const APFloat &rhs, roundingMode rounding_mode) -{ +IEEEFloat::opStatus IEEEFloat::subtract(const IEEEFloat &rhs, + roundingMode rounding_mode) { return addOrSubtract(rhs, rounding_mode, true); } /* Normalized multiply. */ -APFloat::opStatus -APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode) -{ +IEEEFloat::opStatus IEEEFloat::multiply(const IEEEFloat &rhs, + roundingMode rounding_mode) { opStatus fs; sign ^= rhs.sign; @@ -1726,9 +1658,8 @@ } /* Normalized divide. */ -APFloat::opStatus -APFloat::divide(const APFloat &rhs, roundingMode rounding_mode) -{ +IEEEFloat::opStatus IEEEFloat::divide(const IEEEFloat &rhs, + roundingMode rounding_mode) { opStatus fs; sign ^= rhs.sign; @@ -1745,11 +1676,9 @@ } /* Normalized remainder. This is not currently correct in all cases. */ -APFloat::opStatus -APFloat::remainder(const APFloat &rhs) -{ +IEEEFloat::opStatus IEEEFloat::remainder(const IEEEFloat &rhs) { opStatus fs; - APFloat V = *this; + IEEEFloat V = *this; unsigned int origSign = sign; fs = V.divide(rhs, rmNearestTiesToEven); @@ -1782,14 +1711,12 @@ /* Normalized llvm frem (C fmod). This is not currently correct in all cases. */ -APFloat::opStatus -APFloat::mod(const APFloat &rhs) -{ +IEEEFloat::opStatus IEEEFloat::mod(const IEEEFloat &rhs) { opStatus fs; fs = modSpecials(rhs); if (isFiniteNonZero() && rhs.isFiniteNonZero()) { - APFloat V = *this; + IEEEFloat V = *this; unsigned int origSign = sign; fs = V.divide(rhs, rmNearestTiesToEven); @@ -1822,11 +1749,9 @@ } /* Normalized fused-multiply-add. */ -APFloat::opStatus -APFloat::fusedMultiplyAdd(const APFloat &multiplicand, - const APFloat &addend, - roundingMode rounding_mode) -{ +IEEEFloat::opStatus IEEEFloat::fusedMultiplyAdd(const IEEEFloat &multiplicand, + const IEEEFloat &addend, + roundingMode rounding_mode) { opStatus fs; /* Post-multiplication sign, before addition. */ @@ -1867,7 +1792,7 @@ } /* Rounding-mode corrrect round to integral value. */ -APFloat::opStatus APFloat::roundToIntegral(roundingMode rounding_mode) { +IEEEFloat::opStatus IEEEFloat::roundToIntegral(roundingMode rounding_mode) { opStatus fs; // If the exponent is large enough, we know that this value is already @@ -1884,7 +1809,7 @@ // addition instead. APInt IntegerConstant(NextPowerOf2(semanticsPrecision(*semantics)), 1); IntegerConstant <<= semanticsPrecision(*semantics)-1; - APFloat MagicConstant(*semantics); + IEEEFloat MagicConstant(*semantics); fs = MagicConstant.convertFromAPInt(IntegerConstant, false, rmNearestTiesToEven); MagicConstant.copySign(*this); @@ -1910,9 +1835,7 @@ /* Comparison requires normalized numbers. */ -APFloat::cmpResult -APFloat::compare(const APFloat &rhs) const -{ +IEEEFloat::cmpResult IEEEFloat::compare(const IEEEFloat &rhs) const { cmpResult result; assert(semantics == rhs.semantics); @@ -1982,17 +1905,16 @@ return result; } -/// APFloat::convert - convert a value of one floating point type to another. +/// IEEEFloat::convert - convert a value of one floating point type to another. /// The return value corresponds to the IEEE754 exceptions. *losesInfo /// records whether the transformation lost information, i.e. whether /// converting the result back to the original type will produce the /// original value (this is almost the same as return value==fsOK, but there /// are edge cases where this is not so). -APFloat::opStatus -APFloat::convert(const fltSemantics &toSemantics, - roundingMode rounding_mode, bool *losesInfo) -{ +IEEEFloat::opStatus IEEEFloat::convert(const fltSemantics &toSemantics, + roundingMode rounding_mode, + bool *losesInfo) { lostFraction lostFraction; unsigned int newPartCount, oldPartCount; opStatus fs; @@ -2005,8 +1927,8 @@ shift = toSemantics.precision - fromSemantics.precision; bool X86SpecialNan = false; - if (&fromSemantics == &APFloat::x87DoubleExtended && - &toSemantics != &APFloat::x87DoubleExtended && category == fcNaN && + if (&fromSemantics == &IEEEFloat::x87DoubleExtended && + &toSemantics != &IEEEFloat::x87DoubleExtended && category == fcNaN && (!(*significandParts() & 0x8000000000000000ULL) || !(*significandParts() & 0x4000000000000000ULL))) { // x86 has some unusual NaNs which cannot be represented in any other @@ -2070,7 +1992,7 @@ // For x87 extended precision, we want to make a NaN, not a special NaN if // the input wasn't special either. - if (!X86SpecialNan && semantics == &APFloat::x87DoubleExtended) + if (!X86SpecialNan && semantics == &IEEEFloat::x87DoubleExtended) APInt::tcSetBit(significandParts(), semantics->precision - 1); // gcc forces the Quiet bit on, which means (float)(double)(float_sNan) @@ -2096,12 +2018,9 @@ Note that for conversions to integer type the C standard requires round-to-zero to always be used. */ -APFloat::opStatus -APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width, - bool isSigned, - roundingMode rounding_mode, - bool *isExact) const -{ +IEEEFloat::opStatus IEEEFloat::convertToSignExtendedInteger( + integerPart *parts, unsigned int width, bool isSigned, + roundingMode rounding_mode, bool *isExact) const { lostFraction lost_fraction; const integerPart *src; unsigned int dstPartsCount, truncatedBits; @@ -2208,11 +2127,11 @@ the original value. This is almost equivalent to result==opOK, except for negative zeroes. */ -APFloat::opStatus -APFloat::convertToInteger(integerPart *parts, unsigned int width, - bool isSigned, - roundingMode rounding_mode, bool *isExact) const -{ +IEEEFloat::opStatus IEEEFloat::convertToInteger(integerPart *parts, + unsigned int width, + bool isSigned, + roundingMode rounding_mode, + bool *isExact) const { opStatus fs; fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode, @@ -2242,10 +2161,9 @@ an APSInt, whose initial bit-width and signed-ness are used to determine the precision of the conversion. */ -APFloat::opStatus -APFloat::convertToInteger(APSInt &result, - roundingMode rounding_mode, bool *isExact) const -{ +IEEEFloat::opStatus IEEEFloat::convertToInteger(APSInt &result, + roundingMode rounding_mode, + bool *isExact) const { unsigned bitWidth = result.getBitWidth(); SmallVector parts(result.getNumWords()); opStatus status = convertToInteger( @@ -2258,11 +2176,8 @@ /* Convert an unsigned integer SRC to a floating point number, rounding according to ROUNDING_MODE. The sign of the floating point number is not modified. */ -APFloat::opStatus -APFloat::convertFromUnsignedParts(const integerPart *src, - unsigned int srcCount, - roundingMode rounding_mode) -{ +IEEEFloat::opStatus IEEEFloat::convertFromUnsignedParts( + const integerPart *src, unsigned int srcCount, roundingMode rounding_mode) { unsigned int omsb, precision, dstCount; integerPart *dst; lostFraction lost_fraction; @@ -2289,11 +2204,8 @@ return normalize(rounding_mode, lost_fraction); } -APFloat::opStatus -APFloat::convertFromAPInt(const APInt &Val, - bool isSigned, - roundingMode rounding_mode) -{ +IEEEFloat::opStatus IEEEFloat::convertFromAPInt(const APInt &Val, bool isSigned, + roundingMode rounding_mode) { unsigned int partCount = Val.getNumWords(); APInt api = Val; @@ -2309,12 +2221,10 @@ /* Convert a two's complement integer SRC to a floating point number, rounding according to ROUNDING_MODE. ISSIGNED is true if the integer is signed, in which case it must be sign-extended. */ -APFloat::opStatus -APFloat::convertFromSignExtendedInteger(const integerPart *src, - unsigned int srcCount, - bool isSigned, - roundingMode rounding_mode) -{ +IEEEFloat::opStatus +IEEEFloat::convertFromSignExtendedInteger(const integerPart *src, + unsigned int srcCount, bool isSigned, + roundingMode rounding_mode) { opStatus status; if (isSigned && @@ -2337,11 +2247,10 @@ } /* FIXME: should this just take a const APInt reference? */ -APFloat::opStatus -APFloat::convertFromZeroExtendedInteger(const integerPart *parts, - unsigned int width, bool isSigned, - roundingMode rounding_mode) -{ +IEEEFloat::opStatus +IEEEFloat::convertFromZeroExtendedInteger(const integerPart *parts, + unsigned int width, bool isSigned, + roundingMode rounding_mode) { unsigned int partCount = partCountForBits(width); APInt api = APInt(width, makeArrayRef(parts, partCount)); @@ -2354,9 +2263,9 @@ return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode); } -APFloat::opStatus -APFloat::convertFromHexadecimalString(StringRef s, roundingMode rounding_mode) -{ +IEEEFloat::opStatus +IEEEFloat::convertFromHexadecimalString(StringRef s, + roundingMode rounding_mode) { lostFraction lost_fraction = lfExactlyZero; category = fcNormal; @@ -2434,11 +2343,10 @@ return normalize(rounding_mode, lost_fraction); } -APFloat::opStatus -APFloat::roundSignificandWithExponent(const integerPart *decSigParts, - unsigned sigPartCount, int exp, - roundingMode rounding_mode) -{ +IEEEFloat::opStatus +IEEEFloat::roundSignificandWithExponent(const integerPart *decSigParts, + unsigned sigPartCount, int exp, + roundingMode rounding_mode) { unsigned int parts, pow5PartCount; fltSemantics calcSemantics = { 32767, -32767, 0, 0 }; integerPart pow5Parts[maxPowerOfFiveParts]; @@ -2460,8 +2368,8 @@ excessPrecision = calcSemantics.precision - semantics->precision; truncatedBits = excessPrecision; - APFloat decSig = APFloat::getZero(calcSemantics, sign); - APFloat pow5(calcSemantics); + IEEEFloat decSig = IEEEFloat::getZero(calcSemantics, sign); + IEEEFloat pow5(calcSemantics); sigStatus = decSig.convertFromUnsignedParts(decSigParts, sigPartCount, rmNearestTiesToEven); @@ -2519,9 +2427,8 @@ } } -APFloat::opStatus -APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) -{ +IEEEFloat::opStatus +IEEEFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) { decimalInfo D; opStatus fs; @@ -2637,8 +2544,7 @@ return fs; } -bool -APFloat::convertFromStringSpecials(StringRef str) { +bool IEEEFloat::convertFromStringSpecials(StringRef str) { if (str.equals("inf") || str.equals("INFINITY")) { makeInf(false); return true; @@ -2662,9 +2568,8 @@ return false; } -APFloat::opStatus -APFloat::convertFromString(StringRef str, roundingMode rounding_mode) -{ +IEEEFloat::opStatus IEEEFloat::convertFromString(StringRef str, + roundingMode rounding_mode) { assert(!str.empty() && "Invalid string length"); // Handle special cases. @@ -2714,10 +2619,9 @@ 1 (normal numbers) or 2 (normal numbers rounded-away-from-zero with any other digits zero). */ -unsigned int -APFloat::convertToHexString(char *dst, unsigned int hexDigits, - bool upperCase, roundingMode rounding_mode) const -{ +unsigned int IEEEFloat::convertToHexString(char *dst, unsigned int hexDigits, + bool upperCase, + roundingMode rounding_mode) const { char *p; p = dst; @@ -2762,11 +2666,9 @@ form of a normal floating point number with the specified number of hexadecimal digits. If HEXDIGITS is zero the minimum number of digits necessary to print the value precisely is output. */ -char * -APFloat::convertNormalToHexString(char *dst, unsigned int hexDigits, - bool upperCase, - roundingMode rounding_mode) const -{ +char *IEEEFloat::convertNormalToHexString(char *dst, unsigned int hexDigits, + bool upperCase, + roundingMode rounding_mode) const { unsigned int count, valueBits, shift, partsCount, outputDigits; const char *hexDigitChars; const integerPart *significand; @@ -2866,7 +2768,7 @@ return writeSignedDecimal (dst, exponent); } -hash_code llvm::hash_value(const APFloat &Arg) { +hash_code hash_value(const IEEEFloat &Arg) { if (!Arg.isFiniteNonZero()) return hash_combine((uint8_t)Arg.category, // NaN has no sign, fix it at zero. @@ -2890,9 +2792,7 @@ // Denormals have exponent minExponent in APFloat, but minExponent-1 in // the actual IEEE respresentations. We compensate for that here. -APInt -APFloat::convertF80LongDoubleAPFloatToAPInt() const -{ +APInt IEEEFloat::convertF80LongDoubleAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended); assert(partCount()==2); @@ -2922,9 +2822,7 @@ return APInt(80, words); } -APInt -APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const -{ +APInt IEEEFloat::convertPPCDoubleDoubleAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&PPCDoubleDouble); assert(partCount()==2); @@ -2940,12 +2838,12 @@ // saves pointer to it) to ensure correct destruction order. fltSemantics extendedSemantics = *semantics; extendedSemantics.minExponent = IEEEdouble.minExponent; - APFloat extended(*this); + IEEEFloat extended(*this); fs = extended.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo); assert(fs == opOK && !losesInfo); (void)fs; - APFloat u(extended); + IEEEFloat u(extended); fs = u.convert(IEEEdouble, rmNearestTiesToEven, &losesInfo); assert(fs == opOK || fs == opInexact); (void)fs; @@ -2960,7 +2858,7 @@ assert(fs == opOK && !losesInfo); (void)fs; - APFloat v(extended); + IEEEFloat v(extended); v.subtract(u, rmNearestTiesToEven); fs = v.convert(IEEEdouble, rmNearestTiesToEven, &losesInfo); assert(fs == opOK && !losesInfo); @@ -2973,9 +2871,7 @@ return APInt(128, words); } -APInt -APFloat::convertQuadrupleAPFloatToAPInt() const -{ +APInt IEEEFloat::convertQuadrupleAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&IEEEquad); assert(partCount()==2); @@ -3009,9 +2905,7 @@ return APInt(128, words); } -APInt -APFloat::convertDoubleAPFloatToAPInt() const -{ +APInt IEEEFloat::convertDoubleAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&IEEEdouble); assert(partCount()==1); @@ -3039,9 +2933,7 @@ (mysignificand & 0xfffffffffffffLL)))); } -APInt -APFloat::convertFloatAPFloatToAPInt() const -{ +APInt IEEEFloat::convertFloatAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&IEEEsingle); assert(partCount()==1); @@ -3068,9 +2960,7 @@ (mysignificand & 0x7fffff))); } -APInt -APFloat::convertHalfAPFloatToAPInt() const -{ +APInt IEEEFloat::convertHalfAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&IEEEhalf); assert(partCount()==1); @@ -3101,9 +2991,7 @@ // point constant as it would appear in memory. It is not a conversion, // and treating the result as a normal integer is unlikely to be useful. -APInt -APFloat::bitcastToAPInt() const -{ +APInt IEEEFloat::bitcastToAPInt() const { if (semantics == (const llvm::fltSemantics*)&IEEEhalf) return convertHalfAPFloatToAPInt(); @@ -3124,18 +3012,14 @@ return convertF80LongDoubleAPFloatToAPInt(); } -float -APFloat::convertToFloat() const -{ +float IEEEFloat::convertToFloat() const { assert(semantics == (const llvm::fltSemantics*)&IEEEsingle && "Float semantics are not IEEEsingle"); APInt api = bitcastToAPInt(); return api.bitsToFloat(); } -double -APFloat::convertToDouble() const -{ +double IEEEFloat::convertToDouble() const { assert(semantics == (const llvm::fltSemantics*)&IEEEdouble && "Float semantics are not IEEEdouble"); APInt api = bitcastToAPInt(); @@ -3149,16 +3033,14 @@ /// exponent = 0, integer bit 1 ("pseudodenormal") /// exponent!=0 nor all 1's, integer bit 0 ("unnormal") /// At the moment, the first two are treated as NaNs, the second two as Normal. -void -APFloat::initFromF80LongDoubleAPInt(const APInt &api) -{ +void IEEEFloat::initFromF80LongDoubleAPInt(const APInt &api) { assert(api.getBitWidth()==80); uint64_t i1 = api.getRawData()[0]; uint64_t i2 = api.getRawData()[1]; uint64_t myexponent = (i2 & 0x7fff); uint64_t mysignificand = i1; - initialize(&APFloat::x87DoubleExtended); + initialize(&IEEEFloat::x87DoubleExtended); assert(partCount()==2); sign = static_cast(i2>>15); @@ -3183,9 +3065,7 @@ } } -void -APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) -{ +void IEEEFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) { assert(api.getBitWidth()==128); uint64_t i1 = api.getRawData()[0]; uint64_t i2 = api.getRawData()[1]; @@ -3200,7 +3080,7 @@ // Unless we have a special case, add in second double. if (isFiniteNonZero()) { - APFloat v(IEEEdouble, APInt(64, i2)); + IEEEFloat v(IEEEdouble, APInt(64, i2)); fs = v.convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo); assert(fs == opOK && !losesInfo); (void)fs; @@ -3209,9 +3089,7 @@ } } -void -APFloat::initFromQuadrupleAPInt(const APInt &api) -{ +void IEEEFloat::initFromQuadrupleAPInt(const APInt &api) { assert(api.getBitWidth()==128); uint64_t i1 = api.getRawData()[0]; uint64_t i2 = api.getRawData()[1]; @@ -3219,7 +3097,7 @@ uint64_t mysignificand = i1; uint64_t mysignificand2 = i2 & 0xffffffffffffLL; - initialize(&APFloat::IEEEquad); + initialize(&IEEEFloat::IEEEquad); assert(partCount()==2); sign = static_cast(i2>>63); @@ -3249,15 +3127,13 @@ } } -void -APFloat::initFromDoubleAPInt(const APInt &api) -{ +void IEEEFloat::initFromDoubleAPInt(const APInt &api) { assert(api.getBitWidth()==64); uint64_t i = *api.getRawData(); uint64_t myexponent = (i >> 52) & 0x7ff; uint64_t mysignificand = i & 0xfffffffffffffLL; - initialize(&APFloat::IEEEdouble); + initialize(&IEEEFloat::IEEEdouble); assert(partCount()==1); sign = static_cast(i>>63); @@ -3282,15 +3158,13 @@ } } -void -APFloat::initFromFloatAPInt(const APInt & api) -{ +void IEEEFloat::initFromFloatAPInt(const APInt &api) { assert(api.getBitWidth()==32); uint32_t i = (uint32_t)*api.getRawData(); uint32_t myexponent = (i >> 23) & 0xff; uint32_t mysignificand = i & 0x7fffff; - initialize(&APFloat::IEEEsingle); + initialize(&IEEEFloat::IEEEsingle); assert(partCount()==1); sign = i >> 31; @@ -3315,15 +3189,13 @@ } } -void -APFloat::initFromHalfAPInt(const APInt & api) -{ +void IEEEFloat::initFromHalfAPInt(const APInt &api) { assert(api.getBitWidth()==16); uint32_t i = (uint32_t)*api.getRawData(); uint32_t myexponent = (i >> 10) & 0x1f; uint32_t mysignificand = i & 0x3ff; - initialize(&APFloat::IEEEhalf); + initialize(&IEEEFloat::IEEEhalf); assert(partCount()==1); sign = i >> 15; @@ -3352,9 +3224,7 @@ /// we infer the floating point type from the size of the APInt. The /// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful /// when the size is anything else). -void -APFloat::initFromAPInt(const fltSemantics* Sem, const APInt& api) -{ +void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) { if (Sem == &IEEEhalf) return initFromHalfAPInt(api); if (Sem == &IEEEsingle) @@ -3371,34 +3241,28 @@ llvm_unreachable(nullptr); } -APFloat -APFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE) -{ +IEEEFloat IEEEFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE) { switch (BitWidth) { case 16: - return APFloat(IEEEhalf, APInt::getAllOnesValue(BitWidth)); + return IEEEFloat(IEEEhalf, APInt::getAllOnesValue(BitWidth)); case 32: - return APFloat(IEEEsingle, APInt::getAllOnesValue(BitWidth)); + return IEEEFloat(IEEEsingle, APInt::getAllOnesValue(BitWidth)); case 64: - return APFloat(IEEEdouble, APInt::getAllOnesValue(BitWidth)); + return IEEEFloat(IEEEdouble, APInt::getAllOnesValue(BitWidth)); case 80: - return APFloat(x87DoubleExtended, APInt::getAllOnesValue(BitWidth)); + return IEEEFloat(x87DoubleExtended, APInt::getAllOnesValue(BitWidth)); case 128: if (isIEEE) - return APFloat(IEEEquad, APInt::getAllOnesValue(BitWidth)); - return APFloat(PPCDoubleDouble, APInt::getAllOnesValue(BitWidth)); + return IEEEFloat(IEEEquad, APInt::getAllOnesValue(BitWidth)); + return IEEEFloat(PPCDoubleDouble, APInt::getAllOnesValue(BitWidth)); default: llvm_unreachable("Unknown floating bit width"); } } -unsigned APFloat::getSizeInBits(const fltSemantics &Sem) { - return Sem.sizeInBits; -} - /// Make this number the largest magnitude normal number in the given /// semantics. -void APFloat::makeLargest(bool Negative) { +void IEEEFloat::makeLargest(bool Negative) { // We want (in interchange format): // sign = {Negative} // exponent = 1..10 @@ -3423,7 +3287,7 @@ /// Make this number the smallest magnitude denormal number in the given /// semantics. -void APFloat::makeSmallest(bool Negative) { +void IEEEFloat::makeSmallest(bool Negative) { // We want (in interchange format): // sign = {Negative} // exponent = 0..0 @@ -3434,29 +3298,29 @@ APInt::tcSet(significandParts(), 1, partCount()); } - -APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) { +IEEEFloat IEEEFloat::getLargest(const fltSemantics &Sem, bool Negative) { // We want (in interchange format): // sign = {Negative} // exponent = 1..10 // significand = 1..1 - APFloat Val(Sem, uninitialized); + IEEEFloat Val(Sem, uninitialized); Val.makeLargest(Negative); return Val; } -APFloat APFloat::getSmallest(const fltSemantics &Sem, bool Negative) { +IEEEFloat IEEEFloat::getSmallest(const fltSemantics &Sem, bool Negative) { // We want (in interchange format): // sign = {Negative} // exponent = 0..0 // significand = 0..01 - APFloat Val(Sem, uninitialized); + IEEEFloat Val(Sem, uninitialized); Val.makeSmallest(Negative); return Val; } -APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) { - APFloat Val(Sem, uninitialized); +IEEEFloat IEEEFloat::getSmallestNormalized(const fltSemantics &Sem, + bool Negative) { + IEEEFloat Val(Sem, uninitialized); // We want (in interchange format): // sign = {Negative} @@ -3473,15 +3337,15 @@ return Val; } -APFloat::APFloat(const fltSemantics &Sem, const APInt &API) { +IEEEFloat::IEEEFloat(const fltSemantics &Sem, const APInt &API) { initFromAPInt(&Sem, API); } -APFloat::APFloat(float f) { +IEEEFloat::IEEEFloat(float f) { initFromAPInt(&IEEEsingle, APInt::floatToBits(f)); } -APFloat::APFloat(double d) { +IEEEFloat::IEEEFloat(double d) { initFromAPInt(&IEEEdouble, APInt::doubleToBits(d)); } @@ -3569,9 +3433,8 @@ } } -void APFloat::toString(SmallVectorImpl &Str, - unsigned FormatPrecision, - unsigned FormatMaxPadding) const { +void IEEEFloat::toString(SmallVectorImpl &Str, unsigned FormatPrecision, + unsigned FormatMaxPadding) const { switch (category) { case fcInfinity: if (isNegative()) @@ -3772,7 +3635,7 @@ Str.push_back(buffer[NDigits-I-1]); } -bool APFloat::getExactInverse(APFloat *inv) const { +bool IEEEFloat::getExactInverse(IEEEFloat *inv) const { // Special floats and denormals have no exact inverse. if (!isFiniteNonZero()) return false; @@ -3783,7 +3646,7 @@ return false; // Get the inverse. - APFloat reciprocal(*semantics, 1ULL); + IEEEFloat reciprocal(*semantics, 1ULL); if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK) return false; @@ -3801,7 +3664,7 @@ return true; } -bool APFloat::isSignaling() const { +bool IEEEFloat::isSignaling() const { if (!isNaN()) return false; @@ -3814,7 +3677,7 @@ /// /// *NOTE* since nextDown(x) = -nextUp(-x), we only implement nextUp with /// appropriate sign switching before/after the computation. -APFloat::opStatus APFloat::next(bool nextDown) { +IEEEFloat::opStatus IEEEFloat::next(bool nextDown) { // If we are performing nextDown, swap sign so we have -x. if (nextDown) changeSign(); @@ -3930,46 +3793,44 @@ return result; } -void -APFloat::makeInf(bool Negative) { +void IEEEFloat::makeInf(bool Negative) { category = fcInfinity; sign = Negative; exponent = semantics->maxExponent + 1; APInt::tcSet(significandParts(), 0, partCount()); } -void -APFloat::makeZero(bool Negative) { +void IEEEFloat::makeZero(bool Negative) { category = fcZero; sign = Negative; exponent = semantics->minExponent-1; APInt::tcSet(significandParts(), 0, partCount()); } -void APFloat::makeQuiet() { +void IEEEFloat::makeQuiet() { assert(isNaN()); APInt::tcSetBit(significandParts(), semantics->precision - 2); } -int llvm::ilogb(const APFloat &Arg) { +int ilogb(const IEEEFloat &Arg) { if (Arg.isNaN()) - return APFloat::IEK_NaN; + return IEEEFloat::IEK_NaN; if (Arg.isZero()) - return APFloat::IEK_Zero; + return IEEEFloat::IEK_Zero; if (Arg.isInfinity()) - return APFloat::IEK_Inf; + return IEEEFloat::IEK_Inf; if (!Arg.isDenormal()) return Arg.exponent; - APFloat Normalized(Arg); + IEEEFloat Normalized(Arg); int SignificandBits = Arg.getSemantics().precision - 1; Normalized.exponent += SignificandBits; - Normalized.normalize(APFloat::rmNearestTiesToEven, lfExactlyZero); + Normalized.normalize(IEEEFloat::rmNearestTiesToEven, lfExactlyZero); return Normalized.exponent - SignificandBits; } -APFloat llvm::scalbn(APFloat X, int Exp, APFloat::roundingMode RoundingMode) { +IEEEFloat scalbn(IEEEFloat X, int Exp, IEEEFloat::roundingMode RoundingMode) { auto MaxExp = X.getSemantics().maxExponent; auto MinExp = X.getSemantics().minExponent; @@ -3990,21 +3851,34 @@ return X; } -APFloat llvm::frexp(const APFloat &Val, int &Exp, APFloat::roundingMode RM) { +IEEEFloat frexp(const IEEEFloat &Val, int &Exp, IEEEFloat::roundingMode RM) { Exp = ilogb(Val); // Quiet signalling nans. - if (Exp == APFloat::IEK_NaN) { - APFloat Quiet(Val); + if (Exp == IEEEFloat::IEK_NaN) { + IEEEFloat Quiet(Val); Quiet.makeQuiet(); return Quiet; } - if (Exp == APFloat::IEK_Inf) + if (Exp == IEEEFloat::IEK_Inf) return Val; // 1 is added because frexp is defined to return a normalized fraction in // +/-[0.5, 1.0), rather than the usual +/-[1.0, 2.0). - Exp = Exp == APFloat::IEK_Zero ? 0 : Exp + 1; + Exp = Exp == IEEEFloat::IEK_Zero ? 0 : Exp + 1; return scalbn(Val, -Exp, RM); } + +} // End detail namespace + +APFloat::opStatus APFloat::convertFromString(StringRef Str, roundingMode RM) { + return IEEE.convertFromString(Str, RM); +} + +hash_code hash_value(const APFloat &Arg) { return hash_value(Arg.IEEE); } + +APFloat::APFloat(const fltSemantics &Semantics, StringRef S) + : APFloat(IEEEFloat(Semantics, S)) {} + +} // End llvm namespace