X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;ds=sidebyside;f=lib%2FSupport%2FAPFloat.cpp;h=34bc6b6dd6bde0936947cc99a5454d4aa79f7ec0;hb=900617094505bba1fcf4d29c54901f48a0dacfa5;hp=ec50064f42fef13f7905d98432fdcd14c6040fbf;hpb=fdec0c7a7302702d08f1221609221018af8085ec;p=oota-llvm.git diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index ec50064f42f..34bc6b6dd6b 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -319,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!"); @@ -598,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(), @@ -761,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(); @@ -778,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; @@ -795,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); @@ -856,7 +846,6 @@ APFloat::significandParts() void APFloat::zeroSignificand() { - category = fcNormal; APInt::tcSet(significandParts(), 0, partCount()); } @@ -1154,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; @@ -1207,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); @@ -1245,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. */ @@ -1365,6 +1354,7 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract) case PackCategoriesIntoKey(fcZero, fcNaN): case PackCategoriesIntoKey(fcNormal, fcNaN): case PackCategoriesIntoKey(fcInfinity, fcNaN): + sign = false; category = fcNaN; copySignificand(rhs); return opOK; @@ -1483,11 +1473,13 @@ APFloat::multiplySpecials(const APFloat &rhs) case PackCategoriesIntoKey(fcNaN, fcNormal): case PackCategoriesIntoKey(fcNaN, fcInfinity): case PackCategoriesIntoKey(fcNaN, fcNaN): + sign = false; return opOK; case PackCategoriesIntoKey(fcZero, fcNaN): case PackCategoriesIntoKey(fcNormal, fcNaN): case PackCategoriesIntoKey(fcInfinity, fcNaN): + sign = false; category = fcNaN; copySignificand(rhs); return opOK; @@ -1521,23 +1513,22 @@ APFloat::divideSpecials(const APFloat &rhs) default: llvm_unreachable(0); + 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 PackCategoriesIntoKey(fcZero, fcNaN): - case PackCategoriesIntoKey(fcNormal, fcNaN): - case PackCategoriesIntoKey(fcInfinity, fcNaN): - category = fcNaN; - copySignificand(rhs); - return opOK; - case PackCategoriesIntoKey(fcNormal, fcInfinity): category = fcZero; return opOK; @@ -1575,6 +1566,7 @@ APFloat::modSpecials(const APFloat &rhs) case PackCategoriesIntoKey(fcZero, fcNaN): case PackCategoriesIntoKey(fcNormal, fcNaN): case PackCategoriesIntoKey(fcInfinity, fcNaN): + sign = false; category = fcNaN; copySignificand(rhs); return opOK; @@ -1668,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) @@ -1687,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) @@ -1741,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; @@ -1787,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); @@ -1826,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 @@ -1967,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. @@ -1977,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; @@ -1995,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) { @@ -2294,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; } } @@ -2406,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); @@ -2492,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; @@ -2509,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); @@ -2575,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(); @@ -2776,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, @@ -2807,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)) @@ -2864,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; @@ -2890,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]; @@ -2926,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)) @@ -2956,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)) @@ -2985,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)) @@ -3108,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); @@ -3359,15 +3395,17 @@ APFloat APFloat::getSmallest(const fltSemantics &Sem, bool Negative) { } 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)); @@ -3672,7 +3710,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 @@ -3690,7 +3728,7 @@ bool APFloat::getExactInverse(APFloat *inv) const { if (reciprocal.isDenormal()) return false; - assert(reciprocal.category == fcNormal && + assert(reciprocal.isFiniteNonZero() && reciprocal.significandLSB() == reciprocal.semantics->precision - 1); if (inv)