Reformat to untabify.
[oota-llvm.git] / include / llvm / ADT / APFloat.h
index 87d230bc182068a4ac23679560dfec577aa4acc9..3fe04060fd591712a5c810e51e54e0e809e16cb9 100644 (file)
@@ -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
 //
 #ifndef LLVM_ADT_APFLOAT_H
 #define LLVM_ADT_APFLOAT_H
 
-// APInt contains static functions implementing bignum arithmetic.
 #include "llvm/ADT/APInt.h"
 
 namespace llvm {
 
-/// A signed type to represent a floating point numbers unbiased exponent.
-typedef signed short exponent_t;
-
 struct fltSemantics;
 class APSInt;
 class StringRef;
@@ -121,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.
   /// @{
 
@@ -140,7 +139,12 @@ public:
   /// anything real.
   static const fltSemantics Bogus;
 
+  /// @}
+
   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 {
@@ -190,24 +194,38 @@ 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();
 
   /// @}
 
+  /// \brief Returns whether this instance allocated memory.
+  bool needsCleanup() const { return partCount() > 1; }
+
   /// \name Convenience "constructors"
   /// @{
 
+  /// Factory for Positive and Negative Zero.
+  ///
+  /// \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.
@@ -221,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);
   }
 
@@ -261,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
   /// @{
 
@@ -283,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.
   /// @{
 
@@ -296,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
@@ -320,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).
@@ -335,26 +392,70 @@ public:
   unsigned int convertToHexString(char *dst, unsigned int hexDigits,
                                   bool upperCase, roundingMode) const;
 
+  /// \name IEEE-754R 5.7.2 General operations.
+  /// @{
+
+  /// IEEE-754R isSignMinus: Returns true if and only if the current value is
+  /// negative.
+  ///
+  /// This applies to zeros and NaNs as well.
+  bool isNegative() const { return sign; }
+
+  /// IEEE-754R isNormal: Returns true if and only if the current value is normal.
+  ///
+  /// This implies that the current value of the float is not zero, subnormal,
+  /// infinite, or NaN following the definition of normality from IEEE-754R.
+  bool isNormal() const { return !isDenormal() && isFiniteNonZero(); }
+
+  /// Returns true if and only if the current value is zero, subnormal, or
+  /// normal.
+  ///
+  /// This means that the value is not infinite or NaN.
+  bool isFinite() const { return !isNaN() && !isInfinity(); }
+
+  /// Returns true if and only if the float is plus or minus zero.
+  bool isZero() const { return category == fcZero; }
+
+  /// IEEE-754R isSubnormal(): Returns true if and only if the float is a
+  /// denormal.
+  bool isDenormal() const;
+
+  /// IEEE-754R isInfinite(): Returns true if and only if the float is infinity.
+  bool isInfinity() const { return category == fcInfinity; }
+
+  /// Returns true if and only if the float is a quiet or signaling NaN.
+  bool isNaN() const { return category == fcNaN; }
+
+  /// Returns true if and only if the float is a signaling NaN.
+  bool isSignaling() const;
+
+  /// @}
+
   /// \name 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 isFiniteNonZero() const { return isFinite() && !isZero(); }
   bool isPosZero() const { return isZero() && !isNegative(); }
   bool isNegZero() const { return isZero() && isNegative(); }
-  bool isDenormal() const;
-  /// IEEE-754R 5.7.2: isSignaling. Returns true if this is a signaling NaN.
-  bool isSignaling() const;
+
+  /// Returns true if and only if the number has the smallest possible non-zero
+  /// magnitude in the current semantics.
+  bool isSmallest() const;
+
+  /// 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.
   ///
@@ -394,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
@@ -442,27 +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);
-
-  /// @}
-
-  /// \name Special value queries only useful internally to APFloat
-  /// @{
-
-  /// Returns true if and only if the number has the smallest possible non-zero
-  /// magnitude in the current semantics.
-  bool isSmallest() const;
-  /// Returns true if and only if the number has the largest possible finite
-  /// magnitude in the current semantics.
-  bool isLargest() const;
+  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;
@@ -511,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.
   ///
@@ -523,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