summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Support/APFloat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Support/APFloat.cpp')
-rw-r--r--contrib/llvm/lib/Support/APFloat.cpp696
1 files changed, 495 insertions, 201 deletions
diff --git a/contrib/llvm/lib/Support/APFloat.cpp b/contrib/llvm/lib/Support/APFloat.cpp
index 6182e34..676e2d4 100644
--- a/contrib/llvm/lib/Support/APFloat.cpp
+++ b/contrib/llvm/lib/Support/APFloat.cpp
@@ -25,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. */
@@ -38,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. */
@@ -288,9 +294,9 @@ interpretDecimal(StringRef::iterator begin, StringRef::iterator end,
}
/* Adjust the exponents for any decimal point. */
- D->exponent += static_cast<exponent_t>((dot - p) - (dot > p));
+ D->exponent += static_cast<APFloat::ExponentType>((dot - p) - (dot > p));
D->normalizedExponent = (D->exponent +
- static_cast<exponent_t>((p - D->firstSigDigit)
+ static_cast<APFloat::ExponentType>((p - D->firstSigDigit)
- (dot > D->firstSigDigit && dot < p)));
}
@@ -313,8 +319,8 @@ trailingHexadecimalFraction(StringRef::iterator p, StringRef::iterator end,
else if (digitValue < 8 && digitValue > 0)
return lfLessThanHalf;
- /* Otherwise we need to find the first non-zero digit. */
- while (*p == '0')
+ // Otherwise we need to find the first non-zero digit.
+ while (p != end && (*p == '0' || *p == '.'))
p++;
assert(p != end && "Invalid trailing hexadecimal fraction!");
@@ -580,7 +586,7 @@ APFloat::initialize(const fltSemantics *ourSemantics)
void
APFloat::freeSignificand()
{
- if (partCount() > 1)
+ if (needsCleanup())
delete [] significand.parts;
}
@@ -592,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(),
@@ -679,12 +685,73 @@ 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)
return true;
@@ -694,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();
@@ -711,6 +778,7 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) {
initialize(&ourSemantics);
sign = 0;
+ category = fcNormal;
zeroSignificand();
exponent = ourSemantics.precision - 1;
significandParts()[0] = value;
@@ -728,17 +796,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);
@@ -780,8 +837,6 @@ APFloat::significandParts() const
integerPart *
APFloat::significandParts()
{
- assert(category == fcNormal || category == fcNaN);
-
if (partCount() > 1)
return significand.parts;
else
@@ -791,7 +846,6 @@ APFloat::significandParts()
void
APFloat::zeroSignificand()
{
- category = fcNormal;
APInt::tcSet(significandParts(), 0, partCount());
}
@@ -872,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;
@@ -880,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;
@@ -912,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;
@@ -1035,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;
@@ -1064,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;
@@ -1117,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);
@@ -1155,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. */
@@ -1259,42 +1338,43 @@ 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):
+ sign = false;
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) {
@@ -1304,7 +1384,7 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract)
return opOK;
- case convolve(fcNormal, fcNormal):
+ case PackCategoriesIntoKey(fcNormal, fcNormal):
return opDivByZero;
}
}
@@ -1385,41 +1465,43 @@ 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):
+ sign = false;
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):
+ sign = false;
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;
}
}
@@ -1427,41 +1509,40 @@ 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):
- 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);
+ case PackCategoriesIntoKey(fcNaN, fcZero):
+ case PackCategoriesIntoKey(fcNaN, fcNormal):
+ case PackCategoriesIntoKey(fcNaN, fcInfinity):
+ case PackCategoriesIntoKey(fcNaN, fcNaN):
+ sign = false;
+ case PackCategoriesIntoKey(fcInfinity, fcZero):
+ case PackCategoriesIntoKey(fcInfinity, fcNormal):
+ case PackCategoriesIntoKey(fcZero, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcNormal):
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;
}
}
@@ -1469,35 +1550,36 @@ 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):
+ sign = false;
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;
}
}
@@ -1578,7 +1660,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)
@@ -1597,7 +1679,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)
@@ -1651,7 +1733,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;
@@ -1697,9 +1779,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);
@@ -1736,7 +1818,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
@@ -1780,36 +1862,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)
@@ -1817,10 +1899,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;
}
@@ -1877,8 +1959,25 @@ APFloat::convert(const fltSemantics &toSemantics,
X86SpecialNan = true;
}
+ // If this is a truncation of a denormal number, and the target semantics
+ // has larger exponent range than the source semantics (this can happen
+ // when truncating from PowerPC double-double to double format), the
+ // right shift could lose result mantissa bits. Adjust exponent instead
+ // of performing excessive shift.
+ if (shift < 0 && isFiniteNonZero()) {
+ int exponentChange = significandMSB() + 1 - fromSemantics.precision;
+ if (exponent + exponentChange < toSemantics.minExponent)
+ exponentChange = toSemantics.minExponent - exponent;
+ if (exponentChange < shift)
+ exponentChange = shift;
+ if (exponentChange < 0) {
+ shift -= exponentChange;
+ exponent += exponentChange;
+ }
+ }
+
// 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.
@@ -1887,14 +1986,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;
@@ -1905,10 +2004,10 @@ 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) {
@@ -2204,56 +2303,46 @@ APFloat::opStatus
APFloat::convertFromHexadecimalString(StringRef s, roundingMode rounding_mode)
{
lostFraction lost_fraction = lfExactlyZero;
- integerPart *significand;
- unsigned int bitPos, partsCount;
- StringRef::iterator dot, firstSignificantDigit;
+ category = fcNormal;
zeroSignificand();
exponent = 0;
- category = fcNormal;
- significand = significandParts();
- partsCount = partCount();
- bitPos = partsCount * integerPartWidth;
+ integerPart *significand = significandParts();
+ unsigned partsCount = partCount();
+ unsigned bitPos = partsCount * integerPartWidth;
+ bool computedTrailingFraction = false;
- /* Skip leading zeroes and any (hexa)decimal point. */
+ // Skip leading zeroes and any (hexa)decimal point.
StringRef::iterator begin = s.begin();
StringRef::iterator end = s.end();
+ StringRef::iterator dot;
StringRef::iterator p = skipLeadingZeroesAndAnyDot(begin, end, &dot);
- firstSignificantDigit = p;
+ StringRef::iterator firstSignificantDigit = p;
- for (; p != end;) {
+ while (p != end) {
integerPart hex_value;
if (*p == '.') {
assert(dot == end && "String contains multiple dots");
dot = p++;
- if (p == end) {
- break;
- }
+ continue;
}
hex_value = hexDigitValue(*p);
- if (hex_value == -1U) {
+ if (hex_value == -1U)
break;
- }
p++;
- if (p == end) {
- break;
- } else {
- /* Store the number whilst 4-bit nibbles remain. */
- if (bitPos) {
- bitPos -= 4;
- hex_value <<= bitPos % integerPartWidth;
- significand[bitPos / integerPartWidth] |= hex_value;
- } else {
- lost_fraction = trailingHexadecimalFraction(p, end, hex_value);
- while (p != end && hexDigitValue(*p) != -1U)
- p++;
- break;
- }
+ // Store the number while we have space.
+ if (bitPos) {
+ bitPos -= 4;
+ hex_value <<= bitPos % integerPartWidth;
+ significand[bitPos / integerPartWidth] |= hex_value;
+ } else if (!computedTrailingFraction) {
+ lost_fraction = trailingHexadecimalFraction(p, end, hex_value);
+ computedTrailingFraction = true;
}
}
@@ -2316,8 +2405,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);
@@ -2402,7 +2491,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;
@@ -2419,6 +2515,7 @@ APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode)
(D.normalizedExponent + 1) * 28738 <=
8651 * (semantics->minExponent - (int) semantics->precision)) {
/* Underflow to zero and round. */
+ category = fcNormal;
zeroSignificand();
fs = normalize(rounding_mode, lfLessThanHalf);
@@ -2485,11 +2582,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();
@@ -2686,7 +2812,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,
@@ -2717,7 +2843,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))
@@ -2774,7 +2900,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;
@@ -2800,7 +2926,7 @@ APFloat::convertQuadrupleAPFloatToAPInt() const
uint64_t myexponent, mysignificand, mysignificand2;
- if (category==fcNormal) {
+ if (isFiniteNonZero()) {
myexponent = exponent+16383; //bias
mysignificand = significandParts()[0];
mysignificand2 = significandParts()[1];
@@ -2836,7 +2962,7 @@ APFloat::convertDoubleAPFloatToAPInt() const
uint64_t myexponent, mysignificand;
- if (category==fcNormal) {
+ if (isFiniteNonZero()) {
myexponent = exponent+1023; //bias
mysignificand = *significandParts();
if (myexponent==1 && !(mysignificand & 0x10000000000000LL))
@@ -2866,7 +2992,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))
@@ -2895,7 +3021,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))
@@ -3018,7 +3144,7 @@ APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api)
(void)fs;
// Unless we have a special case, add in second double.
- if (category == fcNormal) {
+ if (isFiniteNonZero()) {
APFloat v(IEEEdouble, APInt(64, i2));
fs = v.convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
assert(fs == opOK && !losesInfo);
@@ -3211,55 +3337,75 @@ APFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE)
}
}
-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;
+}
+
+/// 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());
+}
- // ...and then clear the top bits for internal consistency.
- if (Sem.precision % integerPartWidth != 0)
- significand[N-1] &=
- (((integerPart) 1) << (Sem.precision % integerPartWidth)) - 1;
+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.category = fcNormal;
Val.zeroSignificand();
+ Val.sign = Negative;
+ Val.exponent = Sem.minExponent;
Val.significandParts()[partCountForBits(Sem.precision)-1] |=
(((integerPart) 1) << ((Sem.precision - 1) % integerPartWidth));
@@ -3400,11 +3546,14 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
// Set FormatPrecision if zero. We want to do this before we
// truncate trailing zeros, as those are part of the precision.
if (!FormatPrecision) {
- // It's an interesting question whether to use the nominal
- // precision or the active precision here for denormals.
+ // We use enough digits so the number can be round-tripped back to an
+ // APFloat. The formula comes from "How to Print Floating-Point Numbers
+ // Accurately" by Steele and White.
+ // FIXME: Using a formula based purely on the precision is conservative;
+ // we can print fewer digits depending on the actual value being printed.
- // FormatPrecision = ceil(significandBits / lg_2(10))
- FormatPrecision = (semantics->precision * 59 + 195) / 196;
+ // FormatPrecision = 2 + floor(significandBits / lg_2(10))
+ FormatPrecision = 2 + semantics->precision * 59 / 196;
}
// Ignore trailing binary zeros.
@@ -3564,7 +3713,7 @@ void APFloat::toString(SmallVectorImpl<char> &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
@@ -3579,10 +3728,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)
@@ -3590,3 +3739,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());
+}
OpenPOWER on IntegriCloud