Add support for letting the client choose different flavors of NaNs. Testcase to be
authorMike Stump <mrs@apple.com>
Sat, 30 May 2009 03:49:43 +0000 (03:49 +0000)
committerMike Stump <mrs@apple.com>
Sat, 30 May 2009 03:49:43 +0000 (03:49 +0000)
added in clang.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72606 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/APFloat.h
lib/Support/APFloat.cpp

index 29a89dd06c2d53acc14b42ec1e950f1acef7701a..aebc6e63ef34f5190b04c6de20fcbffdcef1d59b 100644 (file)
@@ -174,7 +174,7 @@ namespace llvm {
     // Constructors.
     APFloat(const fltSemantics &, const char *);
     APFloat(const fltSemantics &, integerPart);
-    APFloat(const fltSemantics &, fltCategory, bool negative);
+    APFloat(const fltSemantics &, fltCategory, bool negative, unsigned type=0);
     explicit APFloat(double d);
     explicit APFloat(float f);
     explicit APFloat(const APInt &, bool isIEEE = false);
@@ -188,8 +188,9 @@ 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);
+    static APFloat getNaN(const fltSemantics &Sem, bool Negative = false,
+                          long unsigned type=0) {
+      return APFloat(Sem, fcNaN, Negative, type);
     }
 
     /// Profile - Used to insert APFloat objects, or objects that contain
@@ -296,7 +297,7 @@ namespace llvm {
     opStatus modSpecials(const APFloat &);
 
     /* Miscellany.  */
-    void makeNaN(void);
+    void makeNaN(unsigned = 0);
     opStatus normalize(roundingMode, lostFraction);
     opStatus addOrSubtract(const APFloat &, roundingMode, bool subtract);
     cmpResult compareAbsoluteValue(const APFloat &) const;
index 4c79ba61d253a90806f886e09fc3f1d2676693a8..3b03c54e9764155953d6bbf752170e2c45dcb5b5 100644 (file)
@@ -598,12 +598,18 @@ APFloat::copySignificand(const APFloat &rhs)
 
 /* 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. */
+   which may not be ideal.  If float, this is QNaN(0).  */
 void
-APFloat::makeNaN(void)
+APFloat::makeNaN(unsigned type)
 {
   category = fcNaN;
-  APInt::tcSet(significandParts(), ~0U, partCount());
+  // FIXME: Add double and long double support for QNaN(0).
+  if (semantics->precision == 24 && semantics->maxExponent == 127) {
+    type |=  0x7fc00000U;
+    type &= ~0x80000000U;
+  } else
+    type = ~0U;
+  APInt::tcSet(significandParts(), type, partCount());
 }
 
 APFloat &
@@ -662,16 +668,16 @@ APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value)
 }
 
 APFloat::APFloat(const fltSemantics &ourSemantics,
-                 fltCategory ourCategory, bool negative)
+                 fltCategory ourCategory, bool negative, unsigned type)
 {
   assertArithmeticOK(ourSemantics);
   initialize(&ourSemantics);
   category = ourCategory;
   sign = negative;
-  if(category == fcNormal)
+  if (category == fcNormal)
     category = fcZero;
   else if (ourCategory == fcNaN)
-    makeNaN();
+    makeNaN(type);
 }
 
 APFloat::APFloat(const fltSemantics &ourSemantics, const char *text)