diff options
Diffstat (limited to 'lib/Support/APFloat.cpp')
-rw-r--r-- | lib/Support/APFloat.cpp | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index f90973feab..4f1b85431c 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -626,17 +626,37 @@ 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. If float, this is QNaN(0). */ -void -APFloat::makeNaN(unsigned type) +void APFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill) { category = fcNaN; - // 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()); + sign = Negative; + + // Set the significand bits to the fill. + if (!fill || fill->getNumWords() < partCount()) + APInt::tcSet(significandParts(), 0, partCount()); + if (fill) + APInt::tcAssign(significandParts(), fill->getRawData(), partCount()); + + if (SNaN) { + // We always have to clear the QNaN bit to make it an SNaN. + APInt::tcClearBit(significandParts(), semantics->precision - 2); + + // If there are no bits set in the payload, we have to set + // *something* to make it a NaN instead of an infinity; + // conventionally, this is the next bit down from the QNaN bit. + if (APInt::tcIsZero(significandParts(), partCount())) + APInt::tcSetBit(significandParts(), semantics->precision - 3); + } else { + // We always have to set the QNaN bit to make it a QNaN. + APInt::tcSetBit(significandParts(), semantics->precision - 2); + } +} + +APFloat APFloat::makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative, + const APInt *fill) { + APFloat value(Sem, uninitialized); + value.makeNaN(SNaN, Negative, fill); + return value; } APFloat & @@ -701,9 +721,14 @@ APFloat::APFloat(const fltSemantics &ourSemantics) { sign = false; } +APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) { + assertArithmeticOK(ourSemantics); + // Allocates storage if necessary but does not initialize it. + initialize(&ourSemantics); +} APFloat::APFloat(const fltSemantics &ourSemantics, - fltCategory ourCategory, bool negative, unsigned type) + fltCategory ourCategory, bool negative) { assertArithmeticOK(ourSemantics); initialize(&ourSemantics); @@ -712,7 +737,7 @@ APFloat::APFloat(const fltSemantics &ourSemantics, if (category == fcNormal) category = fcZero; else if (ourCategory == fcNaN) - makeNaN(type); + makeNaN(); } APFloat::APFloat(const fltSemantics &ourSemantics, const StringRef& text) |