X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FAPFloat.cpp;h=8713ede6a17c4d12190b35f8c7579c6d4106b5ac;hb=627190ed78c9c2752dfe7be6ea426690863d54e4;hp=4a7a5d1a0562dcc69de4aec92bc16ad44bca96e9;hpb=96f498bd9f140a98321c478f517877c4767b94fa;p=oota-llvm.git diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 4a7a5d1a056..8713ede6a17 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/APSInt.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/Hashing.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" @@ -24,7 +25,13 @@ using namespace llvm; -#define convolve(lhs, rhs) ((lhs) * 4 + (rhs)) +/// A macro used to combine two fcCategory enums into one key which can be used +/// in a switch statement to classify how the interaction of two APFloat's +/// categories affects an operation. +/// +/// TODO: If clang source code is ever allowed to use constexpr in its own +/// codebase, change this into a static inline function. +#define PackCategoriesIntoKey(_lhs, _rhs) ((_lhs) * 4 + (_rhs)) /* Assumed in hexadecimal significand parsing, and conversion to hexadecimal strings. */ @@ -37,11 +44,11 @@ namespace llvm { struct fltSemantics { /* The largest E such that 2^E is representable; this matches the definition of IEEE 754. */ - exponent_t maxExponent; + APFloat::ExponentType maxExponent; /* The smallest E such that 2^E is a normalized number; this matches the definition of IEEE 754. */ - exponent_t minExponent; + APFloat::ExponentType minExponent; /* Number of bits in the significand. This includes the integer bit. */ @@ -101,26 +108,6 @@ decDigitValue(unsigned int c) return c - '0'; } -static unsigned int -hexDigitValue(unsigned int c) -{ - unsigned int r; - - r = c - '0'; - if (r <= 9) - return r; - - r = c - 'A'; - if (r <= 5) - return r + 10; - - r = c - 'a'; - if (r <= 5) - return r + 10; - - return -1U; -} - /* Return the value of a decimal exponent of the form [+-]ddddddd. @@ -307,9 +294,9 @@ interpretDecimal(StringRef::iterator begin, StringRef::iterator end, } /* Adjust the exponents for any decimal point. */ - D->exponent += static_cast((dot - p) - (dot > p)); + D->exponent += static_cast((dot - p) - (dot > p)); D->normalizedExponent = (D->exponent + - static_cast((p - D->firstSigDigit) + static_cast((p - D->firstSigDigit) - (dot > D->firstSigDigit && dot < p))); } @@ -599,7 +586,7 @@ APFloat::initialize(const fltSemantics *ourSemantics) void APFloat::freeSignificand() { - if (partCount() > 1) + if (needsCleanup()) delete [] significand.parts; } @@ -611,14 +598,14 @@ APFloat::assign(const APFloat &rhs) sign = rhs.sign; category = rhs.category; exponent = rhs.exponent; - if (category == fcNormal || category == fcNaN) + if (isFiniteNonZero() || category == fcNaN) copySignificand(rhs); } void APFloat::copySignificand(const APFloat &rhs) { - assert(category == fcNormal || category == fcNaN); + assert(isFiniteNonZero() || category == fcNaN); assert(rhs.partCount() >= partCount()); APInt::tcAssign(significandParts(), rhs.significandParts(), @@ -698,11 +685,72 @@ APFloat::operator=(const APFloat &rhs) bool APFloat::isDenormal() const { - return isNormal() && (exponent == semantics->minExponent) && + return isFiniteNonZero() && (exponent == semantics->minExponent) && (APInt::tcExtractBit(significandParts(), semantics->precision - 1) == 0); } +bool +APFloat::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). + return isFiniteNonZero() && exponent == semantics->minExponent && + significandMSB() == 0; +} + +bool APFloat::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(); + const unsigned PartCount = partCount(); + for (unsigned i = 0; i < PartCount - 1; i++) + if (~Parts[i]) + return false; + + // Set the unused high bits to all ones when we compare. + const unsigned NumHighBits = + PartCount*integerPartWidth - semantics->precision + 1; + assert(NumHighBits <= integerPartWidth && "Can not have more high bits to " + "fill than integerPartWidth"); + const integerPart HighBitFill = + ~integerPart(0) << (integerPartWidth - NumHighBits); + if (~(Parts[PartCount - 1] | HighBitFill)) + return false; + + return true; +} + +bool APFloat::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(); + const unsigned PartCount = partCount(); + + for (unsigned i = 0; i < PartCount - 1; i++) + if (Parts[i]) + return false; + + const unsigned NumHighBits = + PartCount*integerPartWidth - semantics->precision + 1; + assert(NumHighBits <= integerPartWidth && "Can not have more high bits to " + "clear than integerPartWidth"); + const integerPart HighBitMask = ~integerPart(0) >> NumHighBits; + + if (Parts[PartCount - 1] & HighBitMask) + return false; + + return true; +} + +bool +APFloat::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::bitwiseIsEqual(const APFloat &rhs) const { if (this == &rhs) @@ -713,7 +761,7 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const { return false; if (category==fcZero || category==fcInfinity) return true; - else if (category==fcNormal && exponent!=rhs.exponent) + else if (isFiniteNonZero() && exponent!=rhs.exponent) return false; else { int i= partCount(); @@ -747,17 +795,6 @@ APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) { initialize(&ourSemantics); } -APFloat::APFloat(const fltSemantics &ourSemantics, - fltCategory ourCategory, bool negative) { - initialize(&ourSemantics); - category = ourCategory; - sign = negative; - if (category == fcNormal) - category = fcZero; - else if (ourCategory == fcNaN) - makeNaN(); -} - APFloat::APFloat(const fltSemantics &ourSemantics, StringRef text) { initialize(&ourSemantics); convertFromString(text, rmNearestTiesToEven); @@ -799,8 +836,6 @@ APFloat::significandParts() const integerPart * APFloat::significandParts() { - assert(category == fcNormal || category == fcNaN); - if (partCount() > 1) return significand.parts; else @@ -891,7 +926,21 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1; exponent += rhs.exponent; + // Assume the operands involved in the multiplication are single-precision + // FP, and the two multiplicants are: + // *this = a23 . a22 ... a0 * 2^e1 + // rhs = b23 . b22 ... b0 * 2^e2 + // the result of multiplication is: + // *this = c47 c46 . c45 ... c0 * 2^(e1+e2) + // Note that there are two significant bits at the left-hand side of the + // radix point. Move the radix point toward left by one bit, and adjust + // exponent accordingly. + exponent += 1; + if (addend) { + // The intermediate result of the multiplication has "2 * precision" + // signicant bit; adjust the addend to be consistent with mul result. + // Significand savedSignificand = significand; const fltSemantics *savedSemantics = semantics; fltSemantics extendedSemantics; @@ -899,8 +948,9 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) unsigned int extendedPrecision; /* Normalize our MSB. */ - extendedPrecision = precision + precision - 1; + extendedPrecision = 2 * precision; if (omsb != extendedPrecision) { + assert(extendedPrecision > omsb); APInt::tcShiftLeft(fullSignificand, newPartsCount, extendedPrecision - omsb); exponent -= extendedPrecision - omsb; @@ -931,8 +981,18 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1; } - exponent -= (precision - 1); + // Convert the result having "2 * precision" significant-bits back to the one + // having "precision" significant-bits. First, move the radix point from + // poision "2*precision - 1" to "precision - 1". The exponent need to be + // adjusted by "2*precision - 1" - "precision - 1" = "precision". + exponent -= precision; + // In case MSB resides at the left-hand side of radix point, shift the + // mantissa right by some amount to make sure the MSB reside right before + // 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. if (omsb > precision) { unsigned int bits, significantParts; lostFraction lf; @@ -1054,7 +1114,7 @@ lostFraction APFloat::shiftSignificandRight(unsigned int bits) { /* Our exponent should not overflow. */ - assert((exponent_t) (exponent + bits) >= exponent); + assert((ExponentType) (exponent + bits) >= exponent); exponent += bits; @@ -1083,8 +1143,8 @@ APFloat::compareAbsoluteValue(const APFloat &rhs) const int compare; assert(semantics == rhs.semantics); - assert(category == fcNormal); - assert(rhs.category == fcNormal); + assert(isFiniteNonZero()); + assert(rhs.isFiniteNonZero()); compare = exponent - rhs.exponent; @@ -1136,7 +1196,7 @@ APFloat::roundAwayFromZero(roundingMode rounding_mode, unsigned int bit) const { /* NaNs and infinities should not have lost fractions. */ - assert(category == fcNormal || category == fcZero); + assert(isFiniteNonZero() || category == fcZero); /* Current callers never pass this so we don't handle it. */ assert(lost_fraction != lfExactlyZero); @@ -1174,7 +1234,7 @@ APFloat::normalize(roundingMode rounding_mode, unsigned int omsb; /* One, not zero, based MSB. */ int exponentChange; - if (category != fcNormal) + if (!isFiniteNonZero()) return opOK; /* Before rounding normalize the exponent of fcNormal numbers. */ @@ -1278,42 +1338,42 @@ APFloat::normalize(roundingMode rounding_mode, APFloat::opStatus APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract) { - switch (convolve(category, rhs.category)) { + switch (PackCategoriesIntoKey(category, rhs.category)) { default: llvm_unreachable(0); - case convolve(fcNaN, fcZero): - case convolve(fcNaN, fcNormal): - case convolve(fcNaN, fcInfinity): - case convolve(fcNaN, fcNaN): - case convolve(fcNormal, fcZero): - case convolve(fcInfinity, fcNormal): - case convolve(fcInfinity, fcZero): + case PackCategoriesIntoKey(fcNaN, fcZero): + case PackCategoriesIntoKey(fcNaN, fcNormal): + case PackCategoriesIntoKey(fcNaN, fcInfinity): + case PackCategoriesIntoKey(fcNaN, fcNaN): + case PackCategoriesIntoKey(fcNormal, fcZero): + case PackCategoriesIntoKey(fcInfinity, fcNormal): + case PackCategoriesIntoKey(fcInfinity, fcZero): return opOK; - case convolve(fcZero, fcNaN): - case convolve(fcNormal, fcNaN): - case convolve(fcInfinity, fcNaN): + case PackCategoriesIntoKey(fcZero, fcNaN): + case PackCategoriesIntoKey(fcNormal, fcNaN): + case PackCategoriesIntoKey(fcInfinity, fcNaN): category = fcNaN; copySignificand(rhs); return opOK; - case convolve(fcNormal, fcInfinity): - case convolve(fcZero, fcInfinity): + case PackCategoriesIntoKey(fcNormal, fcInfinity): + case PackCategoriesIntoKey(fcZero, fcInfinity): category = fcInfinity; sign = rhs.sign ^ subtract; return opOK; - case convolve(fcZero, fcNormal): + case PackCategoriesIntoKey(fcZero, fcNormal): assign(rhs); sign = rhs.sign ^ subtract; return opOK; - case convolve(fcZero, fcZero): + case PackCategoriesIntoKey(fcZero, fcZero): /* Sign depends on rounding mode; handled by caller. */ return opOK; - case convolve(fcInfinity, fcInfinity): + case PackCategoriesIntoKey(fcInfinity, fcInfinity): /* Differently signed infinities can only be validly subtracted. */ if (((sign ^ rhs.sign)!=0) != subtract) { @@ -1323,7 +1383,7 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract) return opOK; - case convolve(fcNormal, fcNormal): + case PackCategoriesIntoKey(fcNormal, fcNormal): return opDivByZero; } } @@ -1404,41 +1464,41 @@ APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract) APFloat::opStatus APFloat::multiplySpecials(const APFloat &rhs) { - switch (convolve(category, rhs.category)) { + switch (PackCategoriesIntoKey(category, rhs.category)) { default: llvm_unreachable(0); - case convolve(fcNaN, fcZero): - case convolve(fcNaN, fcNormal): - case convolve(fcNaN, fcInfinity): - case convolve(fcNaN, fcNaN): + case PackCategoriesIntoKey(fcNaN, fcZero): + case PackCategoriesIntoKey(fcNaN, fcNormal): + case PackCategoriesIntoKey(fcNaN, fcInfinity): + case PackCategoriesIntoKey(fcNaN, fcNaN): return opOK; - case convolve(fcZero, fcNaN): - case convolve(fcNormal, fcNaN): - case convolve(fcInfinity, fcNaN): + case PackCategoriesIntoKey(fcZero, fcNaN): + case PackCategoriesIntoKey(fcNormal, fcNaN): + case PackCategoriesIntoKey(fcInfinity, fcNaN): category = fcNaN; copySignificand(rhs); return opOK; - case convolve(fcNormal, fcInfinity): - case convolve(fcInfinity, fcNormal): - case convolve(fcInfinity, fcInfinity): + case PackCategoriesIntoKey(fcNormal, fcInfinity): + case PackCategoriesIntoKey(fcInfinity, fcNormal): + case PackCategoriesIntoKey(fcInfinity, fcInfinity): category = fcInfinity; return opOK; - case convolve(fcZero, fcNormal): - case convolve(fcNormal, fcZero): - case convolve(fcZero, fcZero): + case PackCategoriesIntoKey(fcZero, fcNormal): + case PackCategoriesIntoKey(fcNormal, fcZero): + case PackCategoriesIntoKey(fcZero, fcZero): category = fcZero; return opOK; - case convolve(fcZero, fcInfinity): - case convolve(fcInfinity, fcZero): + case PackCategoriesIntoKey(fcZero, fcInfinity): + case PackCategoriesIntoKey(fcInfinity, fcZero): makeNaN(); return opInvalidOp; - case convolve(fcNormal, fcNormal): + case PackCategoriesIntoKey(fcNormal, fcNormal): return opOK; } } @@ -1446,41 +1506,41 @@ APFloat::multiplySpecials(const APFloat &rhs) APFloat::opStatus APFloat::divideSpecials(const APFloat &rhs) { - switch (convolve(category, rhs.category)) { + switch (PackCategoriesIntoKey(category, rhs.category)) { default: llvm_unreachable(0); - case convolve(fcNaN, fcZero): - case convolve(fcNaN, fcNormal): - case convolve(fcNaN, fcInfinity): - case convolve(fcNaN, fcNaN): - case convolve(fcInfinity, fcZero): - case convolve(fcInfinity, fcNormal): - case convolve(fcZero, fcInfinity): - case convolve(fcZero, fcNormal): + case PackCategoriesIntoKey(fcNaN, fcZero): + case PackCategoriesIntoKey(fcNaN, fcNormal): + case PackCategoriesIntoKey(fcNaN, fcInfinity): + case PackCategoriesIntoKey(fcNaN, fcNaN): + case PackCategoriesIntoKey(fcInfinity, fcZero): + case PackCategoriesIntoKey(fcInfinity, fcNormal): + case PackCategoriesIntoKey(fcZero, fcInfinity): + case PackCategoriesIntoKey(fcZero, fcNormal): return opOK; - case convolve(fcZero, fcNaN): - case convolve(fcNormal, fcNaN): - case convolve(fcInfinity, fcNaN): + case PackCategoriesIntoKey(fcZero, fcNaN): + case PackCategoriesIntoKey(fcNormal, fcNaN): + case PackCategoriesIntoKey(fcInfinity, fcNaN): category = fcNaN; copySignificand(rhs); return opOK; - case convolve(fcNormal, fcInfinity): + case PackCategoriesIntoKey(fcNormal, fcInfinity): category = fcZero; return opOK; - case convolve(fcNormal, fcZero): + case PackCategoriesIntoKey(fcNormal, fcZero): category = fcInfinity; return opDivByZero; - case convolve(fcInfinity, fcInfinity): - case convolve(fcZero, fcZero): + case PackCategoriesIntoKey(fcInfinity, fcInfinity): + case PackCategoriesIntoKey(fcZero, fcZero): makeNaN(); return opInvalidOp; - case convolve(fcNormal, fcNormal): + case PackCategoriesIntoKey(fcNormal, fcNormal): return opOK; } } @@ -1488,35 +1548,35 @@ APFloat::divideSpecials(const APFloat &rhs) APFloat::opStatus APFloat::modSpecials(const APFloat &rhs) { - switch (convolve(category, rhs.category)) { + switch (PackCategoriesIntoKey(category, rhs.category)) { default: llvm_unreachable(0); - case convolve(fcNaN, fcZero): - case convolve(fcNaN, fcNormal): - case convolve(fcNaN, fcInfinity): - case convolve(fcNaN, fcNaN): - case convolve(fcZero, fcInfinity): - case convolve(fcZero, fcNormal): - case convolve(fcNormal, fcInfinity): + case PackCategoriesIntoKey(fcNaN, fcZero): + case PackCategoriesIntoKey(fcNaN, fcNormal): + case PackCategoriesIntoKey(fcNaN, fcInfinity): + case PackCategoriesIntoKey(fcNaN, fcNaN): + case PackCategoriesIntoKey(fcZero, fcInfinity): + case PackCategoriesIntoKey(fcZero, fcNormal): + case PackCategoriesIntoKey(fcNormal, fcInfinity): return opOK; - case convolve(fcZero, fcNaN): - case convolve(fcNormal, fcNaN): - case convolve(fcInfinity, fcNaN): + case PackCategoriesIntoKey(fcZero, fcNaN): + case PackCategoriesIntoKey(fcNormal, fcNaN): + case PackCategoriesIntoKey(fcInfinity, fcNaN): category = fcNaN; copySignificand(rhs); return opOK; - case convolve(fcNormal, fcZero): - case convolve(fcInfinity, fcZero): - case convolve(fcInfinity, fcNormal): - case convolve(fcInfinity, fcInfinity): - case convolve(fcZero, fcZero): + case PackCategoriesIntoKey(fcNormal, fcZero): + case PackCategoriesIntoKey(fcInfinity, fcZero): + case PackCategoriesIntoKey(fcInfinity, fcNormal): + case PackCategoriesIntoKey(fcInfinity, fcInfinity): + case PackCategoriesIntoKey(fcZero, fcZero): makeNaN(); return opInvalidOp; - case convolve(fcNormal, fcNormal): + case PackCategoriesIntoKey(fcNormal, fcNormal): return opOK; } } @@ -1597,7 +1657,7 @@ APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode) sign ^= rhs.sign; fs = multiplySpecials(rhs); - if (category == fcNormal) { + if (isFiniteNonZero()) { lostFraction lost_fraction = multiplySignificand(rhs, 0); fs = normalize(rounding_mode, lost_fraction); if (lost_fraction != lfExactlyZero) @@ -1616,7 +1676,7 @@ APFloat::divide(const APFloat &rhs, roundingMode rounding_mode) sign ^= rhs.sign; fs = divideSpecials(rhs); - if (category == fcNormal) { + if (isFiniteNonZero()) { lostFraction lost_fraction = divideSignificand(rhs); fs = normalize(rounding_mode, lost_fraction); if (lost_fraction != lfExactlyZero) @@ -1670,7 +1730,7 @@ APFloat::mod(const APFloat &rhs, roundingMode rounding_mode) opStatus fs; fs = modSpecials(rhs); - if (category == fcNormal && rhs.category == fcNormal) { + if (isFiniteNonZero() && rhs.isFiniteNonZero()) { APFloat V = *this; unsigned int origSign = sign; @@ -1716,9 +1776,9 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand, /* If and only if all arguments are normal do we need to do an extended-precision calculation. */ - if (category == fcNormal && - multiplicand.category == fcNormal && - addend.category == fcNormal) { + if (isFiniteNonZero() && + multiplicand.isFiniteNonZero() && + addend.isFiniteNonZero()) { lostFraction lost_fraction; lost_fraction = multiplySignificand(multiplicand, &addend); @@ -1755,7 +1815,7 @@ APFloat::opStatus APFloat::roundToIntegral(roundingMode rounding_mode) { // If the exponent is large enough, we know that this value is already // integral, and the arithmetic below would potentially cause it to saturate // to +/-Inf. Bail out early instead. - if (category == fcNormal && exponent+1 >= (int)semanticsPrecision(*semantics)) + if (isFiniteNonZero() && exponent+1 >= (int)semanticsPrecision(*semantics)) return opOK; // The algorithm here is quite simple: we add 2^(p-1), where p is the @@ -1799,36 +1859,36 @@ APFloat::compare(const APFloat &rhs) const assert(semantics == rhs.semantics); - switch (convolve(category, rhs.category)) { + switch (PackCategoriesIntoKey(category, rhs.category)) { default: llvm_unreachable(0); - case convolve(fcNaN, fcZero): - case convolve(fcNaN, fcNormal): - case convolve(fcNaN, fcInfinity): - case convolve(fcNaN, fcNaN): - case convolve(fcZero, fcNaN): - case convolve(fcNormal, fcNaN): - case convolve(fcInfinity, fcNaN): + case PackCategoriesIntoKey(fcNaN, fcZero): + case PackCategoriesIntoKey(fcNaN, fcNormal): + case PackCategoriesIntoKey(fcNaN, fcInfinity): + case PackCategoriesIntoKey(fcNaN, fcNaN): + case PackCategoriesIntoKey(fcZero, fcNaN): + case PackCategoriesIntoKey(fcNormal, fcNaN): + case PackCategoriesIntoKey(fcInfinity, fcNaN): return cmpUnordered; - case convolve(fcInfinity, fcNormal): - case convolve(fcInfinity, fcZero): - case convolve(fcNormal, fcZero): + case PackCategoriesIntoKey(fcInfinity, fcNormal): + case PackCategoriesIntoKey(fcInfinity, fcZero): + case PackCategoriesIntoKey(fcNormal, fcZero): if (sign) return cmpLessThan; else return cmpGreaterThan; - case convolve(fcNormal, fcInfinity): - case convolve(fcZero, fcInfinity): - case convolve(fcZero, fcNormal): + case PackCategoriesIntoKey(fcNormal, fcInfinity): + case PackCategoriesIntoKey(fcZero, fcInfinity): + case PackCategoriesIntoKey(fcZero, fcNormal): if (rhs.sign) return cmpGreaterThan; else return cmpLessThan; - case convolve(fcInfinity, fcInfinity): + case PackCategoriesIntoKey(fcInfinity, fcInfinity): if (sign == rhs.sign) return cmpEqual; else if (sign) @@ -1836,10 +1896,10 @@ APFloat::compare(const APFloat &rhs) const else return cmpGreaterThan; - case convolve(fcZero, fcZero): + case PackCategoriesIntoKey(fcZero, fcZero): return cmpEqual; - case convolve(fcNormal, fcNormal): + case PackCategoriesIntoKey(fcNormal, fcNormal): break; } @@ -1897,7 +1957,7 @@ APFloat::convert(const fltSemantics &toSemantics, } // If this is a truncation, perform the shift before we narrow the storage. - if (shift < 0 && (category==fcNormal || category==fcNaN)) + if (shift < 0 && (isFiniteNonZero() || category==fcNaN)) lostFraction = shiftRight(significandParts(), oldPartCount, -shift); // Fix the storage so it can hold to new value. @@ -1906,14 +1966,14 @@ APFloat::convert(const fltSemantics &toSemantics, integerPart *newParts; newParts = new integerPart[newPartCount]; APInt::tcSet(newParts, 0, newPartCount); - if (category==fcNormal || category==fcNaN) + if (isFiniteNonZero() || category==fcNaN) APInt::tcAssign(newParts, significandParts(), oldPartCount); freeSignificand(); significand.parts = newParts; } else if (newPartCount == 1 && oldPartCount != 1) { // Switch to built-in storage for a single part. integerPart newPart = 0; - if (category==fcNormal || category==fcNaN) + if (isFiniteNonZero() || category==fcNaN) newPart = significandParts()[0]; freeSignificand(); significand.part = newPart; @@ -1924,14 +1984,20 @@ APFloat::convert(const fltSemantics &toSemantics, // If this is an extension, perform the shift now that the storage is // available. - if (shift > 0 && (category==fcNormal || category==fcNaN)) + if (shift > 0 && (isFiniteNonZero() || category==fcNaN)) APInt::tcShiftLeft(significandParts(), newPartCount, shift); - if (category == fcNormal) { + if (isFiniteNonZero()) { fs = normalize(rounding_mode, lostFraction); *losesInfo = (fs != opOK); } else if (category == fcNaN) { *losesInfo = lostFraction != lfExactlyZero || X86SpecialNan; + + // 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) + APInt::tcSetBit(significandParts(), semantics->precision - 1); + // gcc forces the Quiet bit on, which means (float)(double)(float_sNan) // does not give you back the same bits. This is dubious, and we // don't currently do it. You're really supposed to get @@ -2329,8 +2395,8 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts, excessPrecision = calcSemantics.precision - semantics->precision; truncatedBits = excessPrecision; - APFloat decSig(calcSemantics, fcZero, sign); - APFloat pow5(calcSemantics, fcZero, false); + APFloat decSig = APFloat::getZero(calcSemantics, sign); + APFloat pow5(calcSemantics); sigStatus = decSig.convertFromUnsignedParts(decSigParts, sigPartCount, rmNearestTiesToEven); @@ -2415,7 +2481,14 @@ APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) 42039/12655 < L < 28738/8651 [ numerator <= 65536 ] */ - if (decDigitValue(*D.firstSigDigit) >= 10U) { + // Test if we have a zero number allowing for strings with no null terminators + // and zero decimals with non-zero exponents. + // + // We computed firstSigDigit by ignoring all zeros and dots. Thus if + // D->firstSigDigit equals str.end(), every digit must be a zero and there can + // be at most one dot. On the other hand, if we have a zero with a non-zero + // exponent, then we know that D.firstSigDigit will be non-numeric. + if (D.firstSigDigit == str.end() || decDigitValue(*D.firstSigDigit) >= 10U) { category = fcZero; fs = opOK; @@ -2498,11 +2571,40 @@ APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) return fs; } +bool +APFloat::convertFromStringSpecials(StringRef str) { + if (str.equals("inf") || str.equals("INFINITY")) { + makeInf(false); + return true; + } + + if (str.equals("-inf") || str.equals("-INFINITY")) { + makeInf(true); + return true; + } + + if (str.equals("nan") || str.equals("NaN")) { + makeNaN(false, false); + return true; + } + + if (str.equals("-nan") || str.equals("-NaN")) { + makeNaN(false, true); + return true; + } + + return false; +} + APFloat::opStatus APFloat::convertFromString(StringRef str, roundingMode rounding_mode) { assert(!str.empty() && "Invalid string length"); + // Handle special cases. + if (convertFromStringSpecials(str)) + return opOK; + /* Handle a leading minus sign. */ StringRef::iterator p = str.begin(); size_t slen = str.size(); @@ -2699,7 +2801,7 @@ APFloat::convertNormalToHexString(char *dst, unsigned int hexDigits, } hash_code llvm::hash_value(const APFloat &Arg) { - if (Arg.category != APFloat::fcNormal) + if (!Arg.isFiniteNonZero()) return hash_combine((uint8_t)Arg.category, // NaN has no sign, fix it at zero. Arg.isNaN() ? (uint8_t)0 : (uint8_t)Arg.sign, @@ -2730,7 +2832,7 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const uint64_t myexponent, mysignificand; - if (category==fcNormal) { + if (isFiniteNonZero()) { myexponent = exponent+16383; //bias mysignificand = significandParts()[0]; if (myexponent==1 && !(mysignificand & 0x8000000000000000ULL)) @@ -2787,7 +2889,7 @@ APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const // just set the second double to zero. Otherwise, re-convert back to // the extended format and compute the difference. This now should // convert exactly to double. - if (u.category == fcNormal && losesInfo) { + if (u.isFiniteNonZero() && losesInfo) { fs = u.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo); assert(fs == opOK && !losesInfo); (void)fs; @@ -2813,7 +2915,7 @@ APFloat::convertQuadrupleAPFloatToAPInt() const uint64_t myexponent, mysignificand, mysignificand2; - if (category==fcNormal) { + if (isFiniteNonZero()) { myexponent = exponent+16383; //bias mysignificand = significandParts()[0]; mysignificand2 = significandParts()[1]; @@ -2849,7 +2951,7 @@ APFloat::convertDoubleAPFloatToAPInt() const uint64_t myexponent, mysignificand; - if (category==fcNormal) { + if (isFiniteNonZero()) { myexponent = exponent+1023; //bias mysignificand = *significandParts(); if (myexponent==1 && !(mysignificand & 0x10000000000000LL)) @@ -2879,7 +2981,7 @@ APFloat::convertFloatAPFloatToAPInt() const uint32_t myexponent, mysignificand; - if (category==fcNormal) { + if (isFiniteNonZero()) { myexponent = exponent+127; //bias mysignificand = (uint32_t)*significandParts(); if (myexponent == 1 && !(mysignificand & 0x800000)) @@ -2908,7 +3010,7 @@ APFloat::convertHalfAPFloatToAPInt() const uint32_t myexponent, mysignificand; - if (category==fcNormal) { + if (isFiniteNonZero()) { myexponent = exponent+15; //bias mysignificand = (uint32_t)*significandParts(); if (myexponent == 1 && !(mysignificand & 0x400)) @@ -3031,8 +3133,8 @@ APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) (void)fs; // Unless we have a special case, add in second double. - if (category == fcNormal) { - APFloat v(APInt(64, i2)); + if (isFiniteNonZero()) { + APFloat v(IEEEdouble, APInt(64, i2)); fs = v.convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo); assert(fs == opOK && !losesInfo); (void)fs; @@ -3185,94 +3287,129 @@ APFloat::initFromHalfAPInt(const APInt & api) /// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful /// when the size is anything else). void -APFloat::initFromAPInt(const APInt& api, bool isIEEE) +APFloat::initFromAPInt(const fltSemantics* Sem, const APInt& api) { - if (api.getBitWidth() == 16) + if (Sem == &IEEEhalf) return initFromHalfAPInt(api); - else if (api.getBitWidth() == 32) + if (Sem == &IEEEsingle) return initFromFloatAPInt(api); - else if (api.getBitWidth()==64) + if (Sem == &IEEEdouble) return initFromDoubleAPInt(api); - else if (api.getBitWidth()==80) + if (Sem == &x87DoubleExtended) return initFromF80LongDoubleAPInt(api); - else if (api.getBitWidth()==128) - return (isIEEE ? - initFromQuadrupleAPInt(api) : initFromPPCDoubleDoubleAPInt(api)); - else - llvm_unreachable(0); + if (Sem == &IEEEquad) + return initFromQuadrupleAPInt(api); + if (Sem == &PPCDoubleDouble) + return initFromPPCDoubleDoubleAPInt(api); + + llvm_unreachable(0); } APFloat APFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE) { - return APFloat(APInt::getAllOnesValue(BitWidth), isIEEE); + switch (BitWidth) { + case 16: + return APFloat(IEEEhalf, APInt::getAllOnesValue(BitWidth)); + case 32: + return APFloat(IEEEsingle, APInt::getAllOnesValue(BitWidth)); + case 64: + return APFloat(IEEEdouble, APInt::getAllOnesValue(BitWidth)); + case 80: + return APFloat(x87DoubleExtended, APInt::getAllOnesValue(BitWidth)); + case 128: + if (isIEEE) + return APFloat(IEEEquad, APInt::getAllOnesValue(BitWidth)); + return APFloat(PPCDoubleDouble, APInt::getAllOnesValue(BitWidth)); + default: + llvm_unreachable("Unknown floating bit width"); + } } -APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) { - APFloat Val(Sem, fcNormal, Negative); - +/// Make this number the largest magnitude normal number in the given +/// semantics. +void APFloat::makeLargest(bool Negative) { // We want (in interchange format): // sign = {Negative} // exponent = 1..10 // significand = 1..1 + category = fcNormal; + sign = Negative; + exponent = semantics->maxExponent; - Val.exponent = Sem.maxExponent; // unbiased + // Use memset to set all but the highest integerPart to all ones. + integerPart *significand = significandParts(); + unsigned PartCount = partCount(); + memset(significand, 0xFF, sizeof(integerPart)*(PartCount - 1)); - // 1-initialize all bits.... - Val.zeroSignificand(); - integerPart *significand = Val.significandParts(); - unsigned N = partCountForBits(Sem.precision); - for (unsigned i = 0; i != N; ++i) - significand[i] = ~((integerPart) 0); + // Set the high integerPart especially setting all unused top bits for + // internal consistency. + const unsigned NumUnusedHighBits = + PartCount*integerPartWidth - semantics->precision; + significand[PartCount - 1] = ~integerPart(0) >> NumUnusedHighBits; +} - // ...and then clear the top bits for internal consistency. - if (Sem.precision % integerPartWidth != 0) - significand[N-1] &= - (((integerPart) 1) << (Sem.precision % integerPartWidth)) - 1; +/// Make this number the smallest magnitude denormal number in the given +/// semantics. +void APFloat::makeSmallest(bool Negative) { + // We want (in interchange format): + // sign = {Negative} + // exponent = 0..0 + // significand = 0..01 + category = fcNormal; + sign = Negative; + exponent = semantics->minExponent; + APInt::tcSet(significandParts(), 1, partCount()); +} + +APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) { + // We want (in interchange format): + // sign = {Negative} + // exponent = 1..10 + // significand = 1..1 + APFloat Val(Sem, uninitialized); + Val.makeLargest(Negative); return Val; } APFloat APFloat::getSmallest(const fltSemantics &Sem, bool Negative) { - APFloat Val(Sem, fcNormal, Negative); - // We want (in interchange format): // sign = {Negative} // exponent = 0..0 // significand = 0..01 - - Val.exponent = Sem.minExponent; // unbiased - Val.zeroSignificand(); - Val.significandParts()[0] = 1; + APFloat Val(Sem, uninitialized); + Val.makeSmallest(Negative); return Val; } APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) { - APFloat Val(Sem, fcNormal, Negative); + APFloat Val(Sem, uninitialized); // We want (in interchange format): // sign = {Negative} // exponent = 0..0 // significand = 10..0 - Val.exponent = Sem.minExponent; Val.zeroSignificand(); + Val.sign = Negative; + Val.exponent = Sem.minExponent; Val.significandParts()[partCountForBits(Sem.precision)-1] |= (((integerPart) 1) << ((Sem.precision - 1) % integerPartWidth)); return Val; } -APFloat::APFloat(const APInt& api, bool isIEEE) { - initFromAPInt(api, isIEEE); +APFloat::APFloat(const fltSemantics &Sem, const APInt &API) { + initFromAPInt(&Sem, API); } APFloat::APFloat(float f) { - initFromAPInt(APInt::floatToBits(f)); + initFromAPInt(&IEEEsingle, APInt::floatToBits(f)); } APFloat::APFloat(double d) { - initFromAPInt(APInt::doubleToBits(d)); + initFromAPInt(&IEEEdouble, APInt::doubleToBits(d)); } namespace { @@ -3308,10 +3445,8 @@ namespace { significand = significand.udiv(divisor); - // Truncate the significand down to its active bit count, but - // don't try to drop below 32. - unsigned newPrecision = std::max(32U, significand.getActiveBits()); - significand = significand.trunc(newPrecision); + // Truncate the significand down to its active bit count. + significand = significand.trunc(significand.getActiveBits()); } @@ -3563,7 +3698,7 @@ void APFloat::toString(SmallVectorImpl &Str, bool APFloat::getExactInverse(APFloat *inv) const { // Special floats and denormals have no exact inverse. - if (category != fcNormal) + if (!isFiniteNonZero()) return false; // Check that the number is a power of two by making sure that only the @@ -3578,10 +3713,10 @@ bool APFloat::getExactInverse(APFloat *inv) const { // Avoid multiplication with a denormal, it is not safe on all platforms and // may be slower than a normal division. - if (reciprocal.significandMSB() + 1 < reciprocal.semantics->precision) + if (reciprocal.isDenormal()) return false; - assert(reciprocal.category == fcNormal && + assert(reciprocal.isFiniteNonZero() && reciprocal.significandLSB() == reciprocal.semantics->precision - 1); if (inv) @@ -3589,3 +3724,148 @@ bool APFloat::getExactInverse(APFloat *inv) const { return true; } + +bool APFloat::isSignaling() const { + if (!isNaN()) + return false; + + // IEEE-754R 2008 6.2.1: A signaling NaN bit string should be encoded with the + // first bit of the trailing significand being 0. + return !APInt::tcExtractBit(significandParts(), semantics->precision - 2); +} + +/// IEEE-754R 2008 5.3.1: nextUp/nextDown. +/// +/// *NOTE* since nextDown(x) = -nextUp(-x), we only implement nextUp with +/// appropriate sign switching before/after the computation. +APFloat::opStatus APFloat::next(bool nextDown) { + // If we are performing nextDown, swap sign so we have -x. + if (nextDown) + changeSign(); + + // Compute nextUp(x) + opStatus result = opOK; + + // Handle each float category separately. + switch (category) { + case fcInfinity: + // nextUp(+inf) = +inf + if (!isNegative()) + break; + // nextUp(-inf) = -getLargest() + makeLargest(true); + break; + case fcNaN: + // IEEE-754R 2008 6.2 Par 2: nextUp(sNaN) = qNaN. Set Invalid flag. + // IEEE-754R 2008 6.2: nextUp(qNaN) = qNaN. Must be identity so we do not + // change the payload. + if (isSignaling()) { + result = opInvalidOp; + // For consistency, propogate the sign of the sNaN to the qNaN. + makeNaN(false, isNegative(), 0); + } + break; + case fcZero: + // nextUp(pm 0) = +getSmallest() + makeSmallest(false); + break; + case fcNormal: + // nextUp(-getSmallest()) = -0 + if (isSmallest() && isNegative()) { + APInt::tcSet(significandParts(), 0, partCount()); + category = fcZero; + exponent = 0; + break; + } + + // nextUp(getLargest()) == INFINITY + if (isLargest() && !isNegative()) { + APInt::tcSet(significandParts(), 0, partCount()); + category = fcInfinity; + exponent = semantics->maxExponent + 1; + break; + } + + // nextUp(normal) == normal + inc. + if (isNegative()) { + // If we are negative, we need to decrement the significand. + + // We only cross a binade boundary that requires adjusting the exponent + // if: + // 1. exponent != semantics->minExponent. This implies we are not in the + // smallest binade or are dealing with denormals. + // 2. Our significand excluding the integral bit is all zeros. + bool WillCrossBinadeBoundary = + exponent != semantics->minExponent && isSignificandAllZeros(); + + // Decrement the significand. + // + // We always do this since: + // 1. If we are dealing with a non binade decrement, by definition we + // just decrement the significand. + // 2. If we are dealing with a normal -> normal binade decrement, since + // we have an explicit integral bit the fact that all bits but the + // integral bit are zero implies that subtracting one will yield a + // significand with 0 integral bit and 1 in all other spots. Thus we + // must just adjust the exponent and set the integral bit to 1. + // 3. If we are dealing with a normal -> denormal binade decrement, + // since we set the integral bit to 0 when we represent denormals, we + // just decrement the significand. + integerPart *Parts = significandParts(); + APInt::tcDecrement(Parts, partCount()); + + if (WillCrossBinadeBoundary) { + // Our result is a normal number. Do the following: + // 1. Set the integral bit to 1. + // 2. Decrement the exponent. + APInt::tcSetBit(Parts, semantics->precision - 1); + exponent--; + } + } else { + // If we are positive, we need to increment the significand. + + // We only cross a binade boundary that requires adjusting the exponent if + // the input is not a denormal and all of said input's significand bits + // are set. If all of said conditions are true: clear the significand, set + // the integral bit to 1, and increment the exponent. If we have a + // denormal always increment since moving denormals and the numbers in the + // smallest normal binade have the same exponent in our representation. + bool WillCrossBinadeBoundary = !isDenormal() && isSignificandAllOnes(); + + if (WillCrossBinadeBoundary) { + integerPart *Parts = significandParts(); + APInt::tcSet(Parts, 0, partCount()); + APInt::tcSetBit(Parts, semantics->precision - 1); + assert(exponent != semantics->maxExponent && + "We can not increment an exponent beyond the maxExponent allowed" + " by the given floating point semantics."); + exponent++; + } else { + incrementSignificand(); + } + } + break; + } + + // If we are performing nextDown, swap sign so we have -nextUp(-x) + if (nextDown) + changeSign(); + + return result; +} + +void +APFloat::makeInf(bool Negative) { + category = fcInfinity; + sign = Negative; + exponent = semantics->maxExponent + 1; + APInt::tcSet(significandParts(), 0, partCount()); +} + +void +APFloat::makeZero(bool Negative) { + category = fcZero; + sign = Negative; + exponent = semantics->minExponent-1; + APInt::tcSet(significandParts(), 0, partCount()); +}