X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FAPFloat.cpp;h=409d4fbd0ae5ca444a1a96162812aa731e5ef953;hb=7a4c071cd9f67599eba21e902079d0e85f2abf97;hp=c3169acabbc7b115375c4548fadd24b4e18d00af;hpb=7a2bdde0a0eebcd2125055e0eacaca040f0b766c;p=oota-llvm.git diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index c3169acabbc..409d4fbd0ae 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -13,8 +13,10 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/APFloat.h" -#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/APSInt.h" #include "llvm/ADT/FoldingSet.h" +#include "llvm/ADT/Hashing.h" +#include "llvm/ADT/StringRef.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include @@ -831,6 +833,7 @@ APFloat::incrementSignificand() /* Our callers should never cause us to overflow. */ assert(carry == 0); + (void)carry; } /* Add the significand of the RHS. Returns the carry flag. */ @@ -925,6 +928,7 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) APFloat extendedAddend(*addend); status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored); assert(status == opOK); + (void)status; lost_fraction = addOrSubtractSignificand(extendedAddend, false); /* Restore our state. */ @@ -1147,9 +1151,6 @@ APFloat::roundAwayFromZero(roundingMode rounding_mode, assert(lost_fraction != lfExactlyZero); switch (rounding_mode) { - default: - llvm_unreachable(0); - case rmNearestTiesToAway: return lost_fraction == lfExactlyHalf || lost_fraction == lfMoreThanHalf; @@ -1172,6 +1173,7 @@ APFloat::roundAwayFromZero(roundingMode rounding_mode, case rmTowardNegative: return sign == true; } + llvm_unreachable("Invalid rounding mode found"); } APFloat::opStatus @@ -1189,7 +1191,7 @@ APFloat::normalize(roundingMode rounding_mode, if (omsb) { /* OMSB is numbered from 1. We want to place it in the integer - bit numbered PRECISON if possible, with a compensating change in + bit numbered PRECISION if possible, with a compensating change in the exponent. */ exponentChange = omsb - semantics->precision; @@ -1388,6 +1390,7 @@ APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract) /* The code above is intended to ensure that no borrow is necessary. */ assert(!carry); + (void)carry; } else { if (bits > 0) { APFloat temp_rhs(rhs); @@ -1401,6 +1404,7 @@ APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract) /* We have a guard bit; generating a carry cannot happen. */ assert(!carry); + (void)carry; } return lost_fraction; @@ -1849,20 +1853,33 @@ APFloat::convert(const fltSemantics &toSemantics, lostFraction lostFraction; unsigned int newPartCount, oldPartCount; opStatus fs; + int shift; + const fltSemantics &fromSemantics = *semantics; - assertArithmeticOK(*semantics); + assertArithmeticOK(fromSemantics); assertArithmeticOK(toSemantics); lostFraction = lfExactlyZero; newPartCount = partCountForBits(toSemantics.precision + 1); oldPartCount = partCount(); + shift = toSemantics.precision - fromSemantics.precision; + + bool X86SpecialNan = false; + if (&fromSemantics == &APFloat::x87DoubleExtended && + &toSemantics != &APFloat::x87DoubleExtended && category == fcNaN && + (!(*significandParts() & 0x8000000000000000ULL) || + !(*significandParts() & 0x4000000000000000ULL))) { + // x86 has some unusual NaNs which cannot be represented in any other + // format; note them here. + X86SpecialNan = true; + } + + // If this is a truncation, perform the shift before we narrow the storage. + if (shift < 0 && (category==fcNormal || category==fcNaN)) + lostFraction = shiftRight(significandParts(), oldPartCount, -shift); - /* Handle storage complications. If our new form is wider, - re-allocate our bit pattern into wider storage. If it is - narrower, we ignore the excess parts, but if narrowing to a - single part we need to free the old storage. - Be careful not to reference significandParts for zeroes - and infinities, since it aborts. */ + // Fix the storage so it can hold to new value. if (newPartCount > oldPartCount) { + // The new type requires more storage; make it available. integerPart *newParts; newParts = new integerPart[newPartCount]; APInt::tcSet(newParts, 0, newPartCount); @@ -1870,61 +1887,36 @@ APFloat::convert(const fltSemantics &toSemantics, APInt::tcAssign(newParts, significandParts(), oldPartCount); freeSignificand(); significand.parts = newParts; - } else if (newPartCount < oldPartCount) { - /* Capture any lost fraction through truncation of parts so we get - correct rounding whilst normalizing. */ - if (category==fcNormal) - lostFraction = lostFractionThroughTruncation - (significandParts(), oldPartCount, toSemantics.precision); - if (newPartCount == 1) { - integerPart newPart = 0; - if (category==fcNormal || category==fcNaN) - newPart = significandParts()[0]; - freeSignificand(); - significand.part = newPart; - } + } else if (newPartCount == 1 && oldPartCount != 1) { + // Switch to built-in storage for a single part. + integerPart newPart = 0; + if (category==fcNormal || category==fcNaN) + newPart = significandParts()[0]; + freeSignificand(); + significand.part = newPart; } + // Now that we have the right storage, switch the semantics. + semantics = &toSemantics; + + // If this is an extension, perform the shift now that the storage is + // available. + if (shift > 0 && (category==fcNormal || category==fcNaN)) + APInt::tcShiftLeft(significandParts(), newPartCount, shift); + if (category == fcNormal) { - /* Re-interpret our bit-pattern. */ - exponent += toSemantics.precision - semantics->precision; - semantics = &toSemantics; fs = normalize(rounding_mode, lostFraction); *losesInfo = (fs != opOK); } else if (category == fcNaN) { - int shift = toSemantics.precision - semantics->precision; - // Do this now so significandParts gets the right answer - const fltSemantics *oldSemantics = semantics; - semantics = &toSemantics; - *losesInfo = false; - // No normalization here, just truncate - if (shift>0) - APInt::tcShiftLeft(significandParts(), newPartCount, shift); - else if (shift < 0) { - unsigned ushift = -shift; - // Figure out if we are losing information. This happens - // if are shifting out something other than 0s, or if the x87 long - // double input did not have its integer bit set (pseudo-NaN), or if the - // x87 long double input did not have its QNan bit set (because the x87 - // hardware sets this bit when converting a lower-precision NaN to - // x87 long double). - if (APInt::tcLSB(significandParts(), newPartCount) < ushift) - *losesInfo = true; - if (oldSemantics == &APFloat::x87DoubleExtended && - (!(*significandParts() & 0x8000000000000000ULL) || - !(*significandParts() & 0x4000000000000000ULL))) - *losesInfo = true; - APInt::tcShiftRight(significandParts(), newPartCount, ushift); - } + *losesInfo = lostFraction != lfExactlyZero || X86SpecialNan; // 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 // an invalid operation signal at runtime, but nobody does that. fs = opOK; } else { - semantics = &toSemantics; - fs = opOK; *losesInfo = false; + fs = opOK; } return fs; @@ -2084,6 +2076,23 @@ APFloat::convertToInteger(integerPart *parts, unsigned int width, return fs; } +/* Same as convertToInteger(integerPart*, ...), except the result is returned in + an APSInt, whose initial bit-width and signed-ness are used to determine the + precision of the conversion. + */ +APFloat::opStatus +APFloat::convertToInteger(APSInt &result, + roundingMode rounding_mode, bool *isExact) const +{ + unsigned bitWidth = result.getBitWidth(); + SmallVector parts(result.getNumWords()); + opStatus status = convertToInteger( + parts.data(), bitWidth, result.isSigned(), rounding_mode, isExact); + // Keeps the original signed-ness. + result = APInt(bitWidth, parts); + return status; +} + /* Convert an unsigned integer SRC to a floating point number, rounding according to ROUNDING_MODE. The sign of the floating point number is not modified. */ @@ -2103,7 +2112,7 @@ APFloat::convertFromUnsignedParts(const integerPart *src, dstCount = partCount(); precision = semantics->precision; - /* We want the most significant PRECISON bits of SRC. There may not + /* We want the most significant PRECISION bits of SRC. There may not be that many; extract what we can. */ if (precision <= omsb) { exponent = omsb - 1; @@ -2174,7 +2183,7 @@ APFloat::convertFromZeroExtendedInteger(const integerPart *parts, roundingMode rounding_mode) { unsigned int partCount = partCountForBits(width); - APInt api = APInt(width, partCount, parts); + APInt api = APInt(width, makeArrayRef(parts, partCount)); sign = false; if (isSigned && APInt::tcExtractBit(parts, width - 1)) { @@ -2673,21 +2682,19 @@ APFloat::convertNormalToHexString(char *dst, unsigned int hexDigits, return writeSignedDecimal (dst, exponent); } -// For good performance it is desirable for different APFloats -// to produce different integers. -uint32_t -APFloat::getHashValue() const -{ - if (category==fcZero) return sign<<8 | semantics->precision ; - else if (category==fcInfinity) return sign<<9 | semantics->precision; - else if (category==fcNaN) return 1<<10 | semantics->precision; - else { - uint32_t hash = sign<<11 | semantics->precision | exponent<<12; - const integerPart* p = significandParts(); - for (int i=partCount(); i>0; i--, p++) - hash ^= ((uint32_t)*p) ^ (uint32_t)((*p)>>32); - return hash; - } +hash_code llvm::hash_value(const APFloat &Arg) { + if (Arg.category != APFloat::fcNormal) + return hash_combine((uint8_t)Arg.category, + // NaN has no sign, fix it at zero. + Arg.isNaN() ? (uint8_t)0 : (uint8_t)Arg.sign, + Arg.semantics->precision); + + // Normal floats need their exponent and significand hashed. + return hash_combine((uint8_t)Arg.category, (uint8_t)Arg.sign, + Arg.semantics->precision, Arg.exponent, + hash_combine_range( + Arg.significandParts(), + Arg.significandParts() + Arg.partCount())); } // Conversion from APFloat to/from host float/double. It may eventually be @@ -2728,7 +2735,7 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const words[0] = mysignificand; words[1] = ((uint64_t)(sign & 1) << 15) | (myexponent & 0x7fffLL); - return APInt(80, 2, words); + return APInt(80, words); } APInt @@ -2773,7 +2780,7 @@ APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const words[1] = ((uint64_t)(sign2 & 1) << 63) | ((myexponent2 & 0x7ff) << 52) | (mysignificand2 & 0xfffffffffffffLL); - return APInt(128, 2, words); + return APInt(128, words); } APInt @@ -2809,7 +2816,7 @@ APFloat::convertQuadrupleAPFloatToAPInt() const ((myexponent & 0x7fff) << 48) | (mysignificand2 & 0xffffffffffffLL); - return APInt(128, 2, words); + return APInt(128, words); } APInt @@ -3221,8 +3228,9 @@ APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) { significand[i] = ~((integerPart) 0); // ...and then clear the top bits for internal consistency. - significand[N-1] &= - (((integerPart) 1) << ((Sem.precision % integerPartWidth) - 1)) - 1; + if (Sem.precision % integerPartWidth != 0) + significand[N-1] &= + (((integerPart) 1) << (Sem.precision % integerPartWidth)) - 1; return Val; } @@ -3252,7 +3260,7 @@ APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) { Val.exponent = Sem.minExponent; Val.zeroSignificand(); Val.significandParts()[partCountForBits(Sem.precision)-1] |= - (((integerPart) 1) << ((Sem.precision % integerPartWidth) - 1)); + (((integerPart) 1) << ((Sem.precision - 1) % integerPartWidth)); return Val; } @@ -3331,7 +3339,7 @@ namespace { // Rounding down is just a truncation, except we also want to drop // trailing zeros from the new result. if (buffer[FirstSignificant - 1] < '5') { - while (buffer[FirstSignificant] == '0') + while (FirstSignificant < N && buffer[FirstSignificant] == '0') FirstSignificant++; exp += FirstSignificant; @@ -3395,8 +3403,8 @@ void APFloat::toString(SmallVectorImpl &Str, // Decompose the number into an APInt and an exponent. int exp = exponent - ((int) semantics->precision - 1); APInt significand(semantics->precision, - partCountForBits(semantics->precision), - significandParts()); + makeArrayRef(significandParts(), + partCountForBits(semantics->precision))); // Set FormatPrecision if zero. We want to do this before we // truncate trailing zeros, as those are part of the precision. @@ -3433,7 +3441,7 @@ void APFloat::toString(SmallVectorImpl &Str, // <= semantics->precision + e * 137 / 59 // (log_2(5) ~ 2.321928 < 2.322034 ~ 137/59) - unsigned precision = semantics->precision + 137 * texp / 59; + unsigned precision = semantics->precision + (137 * texp + 136) / 59; // Multiply significand by 5^e. // N * 5^0101 == N * 5^(1*1) * 5^(0*2) * 5^(1*4) * 5^(0*8)