X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FAPFloat.cpp;h=cc86e795e7927e6616b05b0441bd3a66f062a099;hb=e6be34a53ecbe8c2ff9f0793b13d847e94c0de91;hp=d040932a152cf0605a5511ac89758216c958bdf4;hpb=96c7471b39dc77d4f29658212e5a72e575b23c39;p=oota-llvm.git diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index d040932a152..cc86e795e79 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -2,8 +2,8 @@ // // The LLVM Compiler Infrastructure // -// This file was developed by Neil Booth and is distributed under the -// University of Illinois Open Source License. See LICENSE.TXT for details. +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // @@ -12,9 +12,10 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/FoldingSet.h" #include #include -#include "llvm/ADT/APFloat.h" #include "llvm/Support/MathExtras.h" using namespace llvm; @@ -40,23 +41,26 @@ namespace llvm { /* Number of bits in the significand. This includes the integer bit. */ unsigned int precision; + + /* True if arithmetic is supported. */ + unsigned int arithmeticOK; }; - const fltSemantics APFloat::IEEEsingle = { 127, -126, 24 }; - const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53 }; - const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113 }; - const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64 }; - const fltSemantics APFloat::Bogus = { 0, 0, 0 }; + const fltSemantics APFloat::IEEEsingle = { 127, -126, 24, true }; + const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53, true }; + const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, true }; + const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64, true }; + const fltSemantics APFloat::Bogus = { 0, 0, 0, true }; // The PowerPC format consists of two doubles. It does not map cleanly // onto the usual format above. For now only storage of constants of // this type is supported, no arithmetic. - const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022, 106 }; + const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022, 106, false }; /* A tight upper bound on number of parts required to hold the value pow(5, power) is - power * 1024 / (441 * integerPartWidth) + 1 + power * 815 / (351 * integerPartWidth) + 1 However, whilst the result may require only this many parts, because we are multiplying two values to get it, the @@ -67,8 +71,8 @@ namespace llvm { const unsigned int maxExponent = 16383; const unsigned int maxPrecision = 113; const unsigned int maxPowerOfFiveExponent = maxExponent + maxPrecision - 1; - const unsigned int maxPowerOfFiveParts = 2 + ((maxPowerOfFiveExponent * 1024) - / (441 * integerPartWidth)); + const unsigned int maxPowerOfFiveParts = 2 + ((maxPowerOfFiveExponent * 815) + / (351 * integerPartWidth)); } /* Put a bunch of private, handy routines in an anonymous namespace. */ @@ -80,16 +84,11 @@ namespace { return ((bits) + integerPartWidth - 1) / integerPartWidth; } - unsigned int - digitValue(unsigned int c) + /* Returns 0U-9U. Return values >= 10U are not digits. */ + inline unsigned int + decDigitValue(unsigned int c) { - unsigned int r; - - r = c - '0'; - if(r <= 9) - return r; - - return -1U; + return c - '0'; } unsigned int @@ -112,9 +111,56 @@ namespace { return -1U; } + inline void + assertArithmeticOK(const llvm::fltSemantics &semantics) { + assert(semantics.arithmeticOK + && "Compile-time arithmetic does not support these semantics"); + } + + /* Return the value of a decimal exponent of the form + [+-]ddddddd. + + If the exponent overflows, returns a large exponent with the + appropriate sign. */ + int + readExponent(const char *p) + { + bool isNegative; + unsigned int absExponent; + const unsigned int overlargeExponent = 24000; /* FIXME. */ + + isNegative = (*p == '-'); + if (*p == '-' || *p == '+') + p++; + + absExponent = decDigitValue(*p++); + assert (absExponent < 10U); + + for (;;) { + unsigned int value; + + value = decDigitValue(*p); + if (value >= 10U) + break; + + p++; + value += absExponent * 10; + if (absExponent >= overlargeExponent) { + absExponent = overlargeExponent; + break; + } + absExponent = value; + } + + if (isNegative) + return -(int) absExponent; + else + return (int) absExponent; + } + /* This is ugly and needs cleaning up, but I don't immediately see how whilst remaining safe. */ - static int + int totalExponent(const char *p, int exponentAdjustment) { integerPart unsignedExponent; @@ -132,8 +178,8 @@ namespace { for(;;) { unsigned int value; - value = digitValue(*p); - if(value == -1U) + value = decDigitValue(*p); + if(value >= 10U) break; p++; @@ -176,6 +222,72 @@ namespace { return p; } + /* Given a normal decimal floating point number of the form + + dddd.dddd[eE][+-]ddd + + where the decimal point and exponent are optional, fill out the + structure D. Exponent is appropriate if the significand is + treated as an integer, and normalizedExponent if the significand + is taken to have the decimal point after a single leading + non-zero digit. + + If the value is zero, V->firstSigDigit points to a non-digit, and + the return exponent is zero. + */ + struct decimalInfo { + const char *firstSigDigit; + const char *lastSigDigit; + int exponent; + int normalizedExponent; + }; + + void + interpretDecimal(const char *p, decimalInfo *D) + { + const char *dot; + + p = skipLeadingZeroesAndAnyDot (p, &dot); + + D->firstSigDigit = p; + D->exponent = 0; + D->normalizedExponent = 0; + + for (;;) { + if (*p == '.') { + assert(dot == 0); + dot = p++; + } + if (decDigitValue(*p) >= 10U) + break; + p++; + } + + /* If number is all zerooes accept any exponent. */ + if (p != D->firstSigDigit) { + if (*p == 'e' || *p == 'E') + D->exponent = readExponent(p + 1); + + /* Implied decimal point? */ + if (!dot) + dot = p; + + /* Drop insignificant trailing zeroes. */ + do + do + p--; + while (*p == '0'); + while (*p == '.'); + + /* Adjust the exponents for any decimal point. */ + D->exponent += (dot - p) - (dot > p); + D->normalizedExponent = (D->exponent + (p - D->firstSigDigit) + - (dot > D->firstSigDigit && dot < p)); + } + + D->lastSigDigit = p; + } + /* Return the trailing fraction of a hexadecimal number. DIGITVALUE is the first hex digit of the fraction, P points to the next digit. */ @@ -322,20 +434,9 @@ namespace { /* Place pow(5, power) in DST, and return the number of parts used. DST must be at least one part larger than size of the answer. */ - static unsigned int + unsigned int powerOf5(integerPart *dst, unsigned int power) { - /* A tight upper bound on number of parts required to hold the - value pow(5, power) is - - power * 65536 / (28224 * integerPartWidth) + 1 - - However, whilst the result may require only N parts, because we - are multiplying two values to get it, the multiplication may - require N + 1 parts with the excess part being zero (consider - the trivial case of 1 * 1, the multiplier requires two parts to - hold the single-part result). So we add two to guarantee - enough space whilst multiplying. */ static integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125, 15625, 78125 }; static integerPart pow5s[maxPowerOfFiveParts * 2 + 5] = { 78125 * 5 }; @@ -404,7 +505,7 @@ namespace { /* Write out an integerPart in hexadecimal, starting with the most significant nibble. Write out exactly COUNT hexdigits, return COUNT. */ - static unsigned int + unsigned int partAsHex (char *dst, integerPart part, unsigned int count, const char *hexDigitChars) { @@ -422,7 +523,7 @@ namespace { } /* Write out an unsigned decimal integer. */ - static char * + char * writeUnsignedDecimal (char *dst, unsigned int n) { char buff[40], *p; @@ -440,7 +541,7 @@ namespace { } /* Write out a signed decimal integer. */ - static char * + char * writeSignedDecimal (char *dst, int value) { if (value < 0) { @@ -496,6 +597,15 @@ APFloat::copySignificand(const APFloat &rhs) partCount()); } +/* Make this number a NaN, with an arbitrary but deterministic value + for the significand. */ +void +APFloat::makeNaN(void) +{ + category = fcNaN; + APInt::tcSet(significandParts(), ~0U, partCount()); +} + APFloat & APFloat::operator=(const APFloat &rhs) { @@ -518,14 +628,14 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const { category != rhs.category || sign != rhs.sign) return false; - if (semantics==(const llvm::fltSemantics* const)&PPCDoubleDouble && + if (semantics==(const llvm::fltSemantics*)&PPCDoubleDouble && sign2 != rhs.sign2) return false; if (category==fcZero || category==fcInfinity) return true; else if (category==fcNormal && exponent!=rhs.exponent) return false; - else if (semantics==(const llvm::fltSemantics* const)&PPCDoubleDouble && + else if (semantics==(const llvm::fltSemantics*)&PPCDoubleDouble && exponent2!=rhs.exponent2) return false; else { @@ -542,8 +652,7 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const { APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); + assertArithmeticOK(ourSemantics); initialize(&ourSemantics); sign = 0; zeroSignificand(); @@ -555,19 +664,19 @@ APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) APFloat::APFloat(const fltSemantics &ourSemantics, fltCategory ourCategory, bool negative) { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); + assertArithmeticOK(ourSemantics); initialize(&ourSemantics); category = ourCategory; sign = negative; if(category == fcNormal) category = fcZero; + else if (ourCategory == fcNaN) + makeNaN(); } APFloat::APFloat(const fltSemantics &ourSemantics, const char *text) { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); + assertArithmeticOK(ourSemantics); initialize(&ourSemantics); convertFromString(text, rmNearestTiesToEven); } @@ -583,6 +692,11 @@ APFloat::~APFloat() freeSignificand(); } +// Profile - This method 'profiles' an APFloat for use with FoldingSet. +void APFloat::Profile(FoldingSetNodeID& ID) const { + ID.Add(convertToAPInt()); +} + unsigned int APFloat::partCount() const { @@ -1122,10 +1236,8 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract) case convolve(fcInfinity, fcInfinity): /* Differently signed infinities can only be validly subtracted. */ - if(sign ^ rhs.sign != subtract) { - category = fcNaN; - // Arbitrary but deterministic value for significand - APInt::tcSet(significandParts(), ~0U, partCount()); + if((sign ^ rhs.sign) != subtract) { + makeNaN(); return opInvalidOp; } @@ -1146,7 +1258,7 @@ APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract) /* Determine if the operation on the absolute values is effectively an addition or subtraction. */ - subtract ^= (sign ^ rhs.sign); + subtract ^= (sign ^ rhs.sign) ? true : false; /* Are we bigger exponent-wise than the RHS? */ bits = exponent - rhs.exponent; @@ -1241,9 +1353,7 @@ APFloat::multiplySpecials(const APFloat &rhs) case convolve(fcZero, fcInfinity): case convolve(fcInfinity, fcZero): - category = fcNaN; - // Arbitrary but deterministic value for significand - APInt::tcSet(significandParts(), ~0U, partCount()); + makeNaN(); return opInvalidOp; case convolve(fcNormal, fcNormal): @@ -1285,9 +1395,7 @@ APFloat::divideSpecials(const APFloat &rhs) case convolve(fcInfinity, fcInfinity): case convolve(fcZero, fcZero): - category = fcNaN; - // Arbitrary but deterministic value for significand - APInt::tcSet(significandParts(), ~0U, partCount()); + makeNaN(); return opInvalidOp; case convolve(fcNormal, fcNormal): @@ -1324,6 +1432,8 @@ APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode, { opStatus fs; + assertArithmeticOK(*semantics); + fs = addOrSubtractSpecials(rhs, subtract); /* This return code means it was not a simple case. */ @@ -1352,8 +1462,6 @@ APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode, APFloat::opStatus APFloat::add(const APFloat &rhs, roundingMode rounding_mode) { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); return addOrSubtract(rhs, rounding_mode, false); } @@ -1361,8 +1469,6 @@ APFloat::add(const APFloat &rhs, roundingMode rounding_mode) APFloat::opStatus APFloat::subtract(const APFloat &rhs, roundingMode rounding_mode) { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); return addOrSubtract(rhs, rounding_mode, true); } @@ -1370,10 +1476,9 @@ APFloat::subtract(const APFloat &rhs, roundingMode rounding_mode) APFloat::opStatus APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode) { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); opStatus fs; + assertArithmeticOK(*semantics); sign ^= rhs.sign; fs = multiplySpecials(rhs); @@ -1391,10 +1496,9 @@ APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode) APFloat::opStatus APFloat::divide(const APFloat &rhs, roundingMode rounding_mode) { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); opStatus fs; + assertArithmeticOK(*semantics); sign ^= rhs.sign; fs = divideSpecials(rhs); @@ -1412,11 +1516,11 @@ APFloat::divide(const APFloat &rhs, roundingMode rounding_mode) APFloat::opStatus APFloat::mod(const APFloat &rhs, roundingMode rounding_mode) { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); opStatus fs; APFloat V = *this; unsigned int origSign = sign; + + assertArithmeticOK(*semantics); fs = V.divide(rhs, rmNearestTiesToEven); if (fs == opDivByZero) return fs; @@ -1450,10 +1554,10 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand, const APFloat &addend, roundingMode rounding_mode) { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); opStatus fs; + assertArithmeticOK(*semantics); + /* Post-multiplication sign, before addition. */ sign ^= multiplicand.sign; @@ -1495,10 +1599,9 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand, APFloat::cmpResult APFloat::compare(const APFloat &rhs) const { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); cmpResult result; + assertArithmeticOK(*semantics); assert(semantics == rhs.semantics); switch(convolve(category, rhs.category)) { @@ -1570,12 +1673,11 @@ APFloat::opStatus APFloat::convert(const fltSemantics &toSemantics, roundingMode rounding_mode) { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); lostFraction lostFraction; unsigned int newPartCount, oldPartCount; opStatus fs; + assertArithmeticOK(*semantics); lostFraction = lfExactlyZero; newPartCount = partCountForBits(toSemantics.precision + 1); oldPartCount = partCount(); @@ -1616,6 +1718,8 @@ APFloat::convert(const fltSemantics &toSemantics, fs = normalize(rounding_mode, lostFraction); } else if (category == fcNaN) { int shift = toSemantics.precision - semantics->precision; + // Do this now so significandParts gets the right answer + semantics = &toSemantics; // No normalization here, just truncate if (shift>0) APInt::tcShiftLeft(significandParts(), newPartCount, shift); @@ -1625,7 +1729,6 @@ APFloat::convert(const fltSemantics &toSemantics, // 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. - semantics = &toSemantics; fs = opOK; } else { semantics = &toSemantics; @@ -1637,7 +1740,8 @@ APFloat::convert(const fltSemantics &toSemantics, /* Convert a floating point number to an integer according to the rounding mode. If the rounded integer value is out of range this - returns an invalid operation exception. If the rounded value is in + returns an invalid operation exception and the contents of the + destination parts are unspecified. If the rounded value is in range but the floating point number is not the exact integer, the C standard doesn't require an inexact exception to be raised. IEEE 854 does require it so we do that. @@ -1645,96 +1749,133 @@ APFloat::convert(const fltSemantics &toSemantics, Note that for conversions to integer type the C standard requires round-to-zero to always be used. */ APFloat::opStatus -APFloat::convertToInteger(integerPart *parts, unsigned int width, - bool isSigned, - roundingMode rounding_mode) const +APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width, + bool isSigned, + roundingMode rounding_mode) const { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); lostFraction lost_fraction; - unsigned int msb, partsCount; - int bits; + const integerPart *src; + unsigned int dstPartsCount, truncatedBits; - partsCount = partCountForBits(width); + assertArithmeticOK(*semantics); - /* Handle the three special cases first. We produce - a deterministic result even for the Invalid cases. */ - if (category == fcNaN) { - // Neither sign nor isSigned affects this. - APInt::tcSet(parts, 0, partsCount); - return opInvalidOp; - } - if (category == fcInfinity) { - if (!sign && isSigned) - APInt::tcSetLeastSignificantBits(parts, partsCount, width-1); - else if (!sign && !isSigned) - APInt::tcSetLeastSignificantBits(parts, partsCount, width); - else if (sign && isSigned) { - APInt::tcSetLeastSignificantBits(parts, partsCount, 1); - APInt::tcShiftLeft(parts, partsCount, width-1); - } else // sign && !isSigned - APInt::tcSet(parts, 0, partsCount); + /* Handle the three special cases first. */ + if(category == fcInfinity || category == fcNaN) return opInvalidOp; - } - if (category == fcZero) { - APInt::tcSet(parts, 0, partsCount); + + dstPartsCount = partCountForBits(width); + + if(category == fcZero) { + APInt::tcSet(parts, 0, dstPartsCount); return opOK; } - /* Shift the bit pattern so the fraction is lost. */ - APFloat tmp(*this); - - bits = (int) semantics->precision - 1 - exponent; + src = significandParts(); - if(bits > 0) { - lost_fraction = tmp.shiftSignificandRight(bits); + /* Step 1: place our absolute value, with any fraction truncated, in + the destination. */ + if (exponent < 0) { + /* Our absolute value is less than one; truncate everything. */ + APInt::tcSet(parts, 0, dstPartsCount); + truncatedBits = semantics->precision; } else { - if (-bits >= semantics->precision) { - // Unrepresentably large. - if (!sign && isSigned) - APInt::tcSetLeastSignificantBits(parts, partsCount, width-1); - else if (!sign && !isSigned) - APInt::tcSetLeastSignificantBits(parts, partsCount, width); - else if (sign && isSigned) { - APInt::tcSetLeastSignificantBits(parts, partsCount, 1); - APInt::tcShiftLeft(parts, partsCount, width-1); - } else // sign && !isSigned - APInt::tcSet(parts, 0, partsCount); - return (opStatus)(opOverflow | opInexact); + /* We want the most significant (exponent + 1) bits; the rest are + truncated. */ + unsigned int bits = exponent + 1U; + + /* Hopelessly large in magnitude? */ + if (bits > width) + return opInvalidOp; + + if (bits < semantics->precision) { + /* We truncate (semantics->precision - bits) bits. */ + truncatedBits = semantics->precision - bits; + APInt::tcExtract(parts, dstPartsCount, src, bits, truncatedBits); + } else { + /* We want at least as many bits as are available. */ + APInt::tcExtract(parts, dstPartsCount, src, semantics->precision, 0); + APInt::tcShiftLeft(parts, dstPartsCount, bits - semantics->precision); + truncatedBits = 0; } - tmp.shiftSignificandLeft(-bits); + } + + /* Step 2: work out any lost fraction, and increment the absolute + value if we would round away from zero. */ + if (truncatedBits) { + lost_fraction = lostFractionThroughTruncation(src, partCount(), + truncatedBits); + if (lost_fraction != lfExactlyZero + && roundAwayFromZero(rounding_mode, lost_fraction, truncatedBits)) { + if (APInt::tcIncrement(parts, dstPartsCount)) + return opInvalidOp; /* Overflow. */ + } + } else { lost_fraction = lfExactlyZero; } - if(lost_fraction != lfExactlyZero - && tmp.roundAwayFromZero(rounding_mode, lost_fraction, 0)) - tmp.incrementSignificand(); + /* Step 3: check if we fit in the destination. */ + unsigned int omsb = APInt::tcMSB(parts, dstPartsCount) + 1; - msb = tmp.significandMSB(); + if (sign) { + if (!isSigned) { + /* Negative numbers cannot be represented as unsigned. */ + if (omsb != 0) + return opInvalidOp; + } else { + /* It takes omsb bits to represent the unsigned integer value. + We lose a bit for the sign, but care is needed as the + maximally negative integer is a special case. */ + if (omsb == width && APInt::tcLSB(parts, dstPartsCount) + 1 != omsb) + return opInvalidOp; + + /* This case can happen because of rounding. */ + if (omsb > width) + return opInvalidOp; + } - /* Negative numbers cannot be represented as unsigned. */ - if(!isSigned && tmp.sign && msb != -1U) - return opInvalidOp; + APInt::tcNegate (parts, dstPartsCount); + } else { + if (omsb >= width + !isSigned) + return opInvalidOp; + } - /* It takes exponent + 1 bits to represent the truncated floating - point number without its sign. We lose a bit for the sign, but - the maximally negative integer is a special case. */ - if(msb + 1 > width) /* !! Not same as msb >= width !! */ - return opInvalidOp; + if (lost_fraction == lfExactlyZero) + return opOK; + else + return opInexact; +} - if(isSigned && msb + 1 == width - && (!tmp.sign || tmp.significandLSB() != msb)) - return opInvalidOp; +/* Same as convertToSignExtendedInteger, except we provide + deterministic values in case of an invalid operation exception, + namely zero for NaNs and the minimal or maximal value respectively + for underflow or overflow. */ +APFloat::opStatus +APFloat::convertToInteger(integerPart *parts, unsigned int width, + bool isSigned, + roundingMode rounding_mode) const +{ + opStatus fs; - APInt::tcAssign(parts, tmp.significandParts(), partsCount); + fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode); - if(tmp.sign) - APInt::tcNegate(parts, partsCount); + if (fs == opInvalidOp) { + unsigned int bits, dstPartsCount; - if(lost_fraction == lfExactlyZero) - return opOK; - else - return opInexact; + dstPartsCount = partCountForBits(width); + + if (category == fcNaN) + bits = 0; + else if (sign) + bits = isSigned; + else + bits = width - isSigned; + + APInt::tcSetLeastSignificantBits(parts, dstPartsCount, bits); + if (sign && isSigned) + APInt::tcShiftLeft(parts, dstPartsCount, width - 1); + } + + return fs; } /* Convert an unsigned integer SRC to a floating point number, @@ -1749,6 +1890,7 @@ APFloat::convertFromUnsignedParts(const integerPart *src, integerPart *dst; lostFraction lost_fraction; + assertArithmeticOK(*semantics); category = fcNormal; omsb = APInt::tcMSB(src, srcCount) + 1; dst = significandParts(); @@ -1780,10 +1922,9 @@ APFloat::convertFromSignExtendedInteger(const integerPart *src, bool isSigned, roundingMode rounding_mode) { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); opStatus status; + assertArithmeticOK(*semantics); if (isSigned && APInt::tcExtractBit(src, srcCount * integerPartWidth - 1)) { integerPart *copy; @@ -1809,8 +1950,6 @@ APFloat::convertFromZeroExtendedInteger(const integerPart *parts, unsigned int width, bool isSigned, roundingMode rounding_mode) { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); unsigned int partCount = partCountForBits(width); APInt api = APInt(width, partCount, parts); @@ -1827,8 +1966,6 @@ APFloat::opStatus APFloat::convertFromHexadecimalString(const char *p, roundingMode rounding_mode) { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); lostFraction lost_fraction; integerPart *significand; unsigned int bitPos, partsCount; @@ -1911,7 +2048,7 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts, roundingMode rounding_mode) { unsigned int parts, pow5PartCount; - fltSemantics calcSemantics = { 32767, -32767, 0 }; + fltSemantics calcSemantics = { 32767, -32767, 0, true }; integerPart pow5Parts[maxPowerOfFiveParts]; bool isNearest; @@ -1958,7 +2095,7 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts, excessPrecision = calcSemantics.precision; } /* Extra half-ulp lost in reciprocal of exponent. */ - powHUerr = 1 + powStatus != opOK; + powHUerr = (powStatus == opOK && calcLostFraction == lfExactlyZero) ? 0: 2; } /* Both multiplySignificand and divideSignificand return the @@ -1992,104 +2129,91 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts, APFloat::opStatus APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode) { - const char *dot, *firstSignificantDigit; - integerPart val, maxVal, decValue; + decimalInfo D; opStatus fs; - /* Skip leading zeroes and any decimal point. */ - p = skipLeadingZeroesAndAnyDot(p, &dot); - firstSignificantDigit = p; - - /* The maximum number that can be multiplied by ten with any digit - added without overflowing an integerPart. */ - maxVal = (~ (integerPart) 0 - 9) / 10; - - val = 0; - while (val <= maxVal) { - if (*p == '.') { - assert(dot == 0); - dot = p++; - } + /* Scan the text. */ + interpretDecimal(p, &D); - decValue = digitValue(*p); - if (decValue == -1U) - break; - p++; - val = val * 10 + decValue; - } - - integerPart *decSignificand; - unsigned int partCount, maxPartCount; - - partCount = 0; - maxPartCount = 4; - decSignificand = new integerPart[maxPartCount]; - decSignificand[partCount++] = val; - - /* Now continue to do single-part arithmetic for as long as we can. - Then do a part multiplication, and repeat. */ - while (decValue != -1U) { - integerPart multiplier; - - val = 0; - multiplier = 1; - - while (multiplier <= maxVal) { - if (*p == '.') { - assert(dot == 0); - dot = p++; - } + /* Handle the quick cases. First the case of no significant digits, + i.e. zero, and then exponents that are obviously too large or too + small. Writing L for log 10 / log 2, a number d.ddddd*10^exp + definitely overflows if - decValue = digitValue(*p); - if (decValue == -1U) - break; - p++; - multiplier *= 10; - val = val * 10 + decValue; - } + (exp - 1) * L >= maxExponent - if (partCount == maxPartCount) { - integerPart *newDecSignificand; - newDecSignificand = new integerPart[maxPartCount = partCount * 2]; - APInt::tcAssign(newDecSignificand, decSignificand, partCount); - delete [] decSignificand; - decSignificand = newDecSignificand; - } + and definitely underflows to zero where - APInt::tcMultiplyPart(decSignificand, decSignificand, multiplier, val, - partCount, partCount + 1, false); + (exp + 1) * L <= minExponent - precision - /* If we used another part (likely), increase the count. */ - if (decSignificand[partCount] != 0) - partCount++; - } + With integer arithmetic the tightest bounds for L are - /* Now decSignificand contains the supplied significand ignoring the - decimal point. Figure out our effective exponent, which is the - specified exponent adjusted for any decimal point. */ + 93/28 < L < 196/59 [ numerator <= 256 ] + 42039/12655 < L < 28738/8651 [ numerator <= 65536 ] + */ - if (p == firstSignificantDigit) { - /* Ignore the exponent if we are zero - we cannot overflow. */ + if (decDigitValue(*D.firstSigDigit) >= 10U) { category = fcZero; fs = opOK; + } else if ((D.normalizedExponent + 1) * 28738 + <= 8651 * (semantics->minExponent - (int) semantics->precision)) { + /* Underflow to zero and round. */ + zeroSignificand(); + fs = normalize(rounding_mode, lfLessThanHalf); + } else if ((D.normalizedExponent - 1) * 42039 + >= 12655 * semantics->maxExponent) { + /* Overflow and round. */ + fs = handleOverflow(rounding_mode); } else { - int decimalExponent; + integerPart *decSignificand; + unsigned int partCount; + + /* A tight upper bound on number of bits required to hold an + N-digit decimal integer is N * 196 / 59. Allocate enough space + to hold the full significand, and an extra part required by + tcMultiplyPart. */ + partCount = (D.lastSigDigit - D.firstSigDigit) + 1; + partCount = partCountForBits(1 + 196 * partCount / 59); + decSignificand = new integerPart[partCount + 1]; + partCount = 0; + + /* Convert to binary efficiently - we do almost all multiplication + in an integerPart. When this would overflow do we do a single + bignum multiplication, and then revert again to multiplication + in an integerPart. */ + do { + integerPart decValue, val, multiplier; - if (dot) - decimalExponent = dot + 1 - p; - else - decimalExponent = 0; + val = 0; + multiplier = 1; - /* Add the given exponent. */ - if (*p == 'e' || *p == 'E') - decimalExponent = totalExponent(p, decimalExponent); + do { + if (*p == '.') + p++; + + decValue = decDigitValue(*p++); + multiplier *= 10; + val = val * 10 + decValue; + /* The maximum number that can be multiplied by ten with any + digit added without overflowing an integerPart. */ + } while (p <= D.lastSigDigit && multiplier <= (~ (integerPart) 0 - 9) / 10); + + /* Multiply out the current part. */ + APInt::tcMultiplyPart(decSignificand, decSignificand, multiplier, val, + partCount, partCount + 1, false); + + /* If we used another part (likely but not guaranteed), increase + the count. */ + if (decSignificand[partCount]) + partCount++; + } while (p <= D.lastSigDigit); category = fcNormal; fs = roundSignificandWithExponent(decSignificand, partCount, - decimalExponent, rounding_mode); - } + D.exponent, rounding_mode); - delete [] decSignificand; + delete [] decSignificand; + } return fs; } @@ -2097,8 +2221,8 @@ APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode) APFloat::opStatus APFloat::convertFromString(const char *p, roundingMode rounding_mode) { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); + assertArithmeticOK(*semantics); + /* Handle a leading minus sign. */ if(*p == '-') sign = 1, p++; @@ -2139,10 +2263,10 @@ unsigned int APFloat::convertToHexString(char *dst, unsigned int hexDigits, bool upperCase, roundingMode rounding_mode) const { - assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && - "Compile-time arithmetic on PPC long double not supported yet"); char *p; + assertArithmeticOK(*semantics); + p = dst; if (sign) *dst++ = '-'; @@ -2318,7 +2442,7 @@ APFloat::getHashValue() const APInt APFloat::convertF80LongDoubleAPFloatToAPInt() const { - assert(semantics == (const llvm::fltSemantics* const)&x87DoubleExtended); + assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended); assert (partCount()==2); uint64_t myexponent, mysignificand; @@ -2351,7 +2475,7 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const APInt APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const { - assert(semantics == (const llvm::fltSemantics* const)&PPCDoubleDouble); + assert(semantics == (const llvm::fltSemantics*)&PPCDoubleDouble); assert (partCount()==2); uint64_t myexponent, mysignificand, myexponent2, mysignificand2; @@ -2434,7 +2558,7 @@ APFloat::convertFloatAPFloatToAPInt() const if (category==fcNormal) { myexponent = exponent+127; //bias mysignificand = *significandParts(); - if (myexponent == 1 && !(mysignificand & 0x400000)) + if (myexponent == 1 && !(mysignificand & 0x800000)) myexponent = 0; // denormal } else if (category==fcZero) { myexponent = 0; @@ -2459,16 +2583,16 @@ APFloat::convertFloatAPFloatToAPInt() const APInt APFloat::convertToAPInt() const { - if (semantics == (const llvm::fltSemantics* const)&IEEEsingle) + if (semantics == (const llvm::fltSemantics*)&IEEEsingle) return convertFloatAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics* const)&IEEEdouble) + if (semantics == (const llvm::fltSemantics*)&IEEEdouble) return convertDoubleAPFloatToAPInt(); - if (semantics == (const llvm::fltSemantics* const)&PPCDoubleDouble) + if (semantics == (const llvm::fltSemantics*)&PPCDoubleDouble) return convertPPCDoubleDoubleAPFloatToAPInt(); - assert(semantics == (const llvm::fltSemantics* const)&x87DoubleExtended && + assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended && "unknown format!"); return convertF80LongDoubleAPFloatToAPInt(); } @@ -2476,7 +2600,7 @@ APFloat::convertToAPInt() const float APFloat::convertToFloat() const { - assert(semantics == (const llvm::fltSemantics* const)&IEEEsingle); + assert(semantics == (const llvm::fltSemantics*)&IEEEsingle); APInt api = convertToAPInt(); return api.bitsToFloat(); } @@ -2484,7 +2608,7 @@ APFloat::convertToFloat() const double APFloat::convertToDouble() const { - assert(semantics == (const llvm::fltSemantics* const)&IEEEdouble); + assert(semantics == (const llvm::fltSemantics*)&IEEEdouble); APInt api = convertToAPInt(); return api.bitsToDouble(); }