Aggressively prune the DFS when inserting phi-defs.
[oota-llvm.git] / include / llvm / ADT / APFloat.h
index fc5203c546f33d11a014c01d112ab66755623e40..dfe4e0f49adb2836f7202fcd2d551e662691495b 100644 (file)
@@ -109,6 +109,7 @@ namespace llvm {
   typedef signed short exponent_t;
 
   struct fltSemantics;
+  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 +125,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;
 
@@ -171,10 +173,16 @@ namespace llvm {
       fcZero
     };
 
+    enum uninitializedTag {
+      uninitialized
+    };
+
     // Constructors.
-    APFloat(const fltSemantics &, const char *);
+    APFloat(const fltSemantics &); // Default construct to 0.0
+    APFloat(const fltSemantics &, StringRef);
     APFloat(const fltSemantics &, integerPart);
     APFloat(const fltSemantics &, fltCategory, bool negative);
+    APFloat(const fltSemantics &, uninitializedTag);
     explicit APFloat(double d);
     explicit APFloat(float f);
     explicit APFloat(const APInt &, bool isIEEE = false);
@@ -188,17 +196,63 @@ namespace llvm {
     static APFloat getInf(const fltSemantics &Sem, bool Negative = false) {
       return APFloat(Sem, fcInfinity, Negative);
     }
-    static APFloat getNaN(const fltSemantics &Sem, bool Negative = false) {
-      return APFloat(Sem, fcNaN, Negative);
+
+    /// getNaN - Factory for QNaN values.
+    ///
+    /// \param Negative - True iff the NaN generated should be negative.
+    /// \param type - The unspecified fill bits for creating the NaN, 0 by
+    /// default.  The value is truncated as necessary.
+    static APFloat getNaN(const fltSemantics &Sem, bool Negative = false,
+                          unsigned type = 0) {
+      if (type) {
+        APInt fill(64, type);
+        return getQNaN(Sem, Negative, &fill);
+      } else {
+        return getQNaN(Sem, Negative, 0);
+      }
+    }
+
+    /// getQNan - Factory for QNaN values.
+    static APFloat getQNaN(const fltSemantics &Sem,
+                           bool Negative = false,
+                           const APInt *payload = 0) {
+      return makeNaN(Sem, false, Negative, payload);
     }
-    
+
+    /// getSNan - Factory for SNaN values.
+    static APFloat getSNaN(const fltSemantics &Sem,
+                           bool Negative = false,
+                           const APInt *payload = 0) {
+      return makeNaN(Sem, true, Negative, payload);
+    }
+
+    /// getLargest - Returns the largest finite number in the given
+    /// semantics.
+    ///
+    /// \param Negative - True iff the number should be negative
+    static APFloat getLargest(const fltSemantics &Sem, bool Negative = false);
+
+    /// getSmallest - Returns the smallest (by magnitude) finite number
+    /// in the given semantics.  Might be denormalized, which implies a
+    /// relative loss of precision.
+    ///
+    /// \param Negative - True iff the number should be negative
+    static APFloat getSmallest(const fltSemantics &Sem, bool Negative = false);
+
+    /// getSmallestNormalized - Returns the smallest (by magnitude)
+    /// normalized finite number in the given semantics.
+    ///
+    /// \param Negative - True iff the number should be negative
+    static APFloat getSmallestNormalized(const fltSemantics &Sem,
+                                         bool Negative = false);
+
     /// 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);
 
@@ -207,6 +261,9 @@ 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);
 
@@ -216,17 +273,17 @@ 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 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;
 
@@ -239,6 +296,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,
@@ -246,9 +306,6 @@ 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; }
@@ -265,6 +322,30 @@ namespace llvm {
     /* Return an arbitrary integer value usable for hashing. */
     uint32_t getHashValue() const;
 
+    /// 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<char> &Str,
+                  unsigned FormatPrecision = 0,
+                  unsigned FormatMaxPadding = 3) const;
+
   private:
 
     /* Trivial queries.  */
@@ -290,32 +371,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);