X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FAPFloat.cpp;h=d7f0d8215987c0a2720eac4cd6ac697747004b00;hb=bf5836b075a7fdd680e7c43134237bdef65643cf;hp=b93f1d109a02df01ab0d29410fdccf237de9a1a2;hpb=2df5eec2ff25cbb7e5fd4848e667fb9f854d3339;p=oota-llvm.git diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index b93f1d109a0..d7f0d821598 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -75,484 +75,482 @@ namespace llvm { / (351 * integerPartWidth)); } -/* Put a bunch of private, handy routines in an anonymous namespace. */ -namespace { +/* A bunch of private, handy routines. */ - static inline unsigned int - partCountForBits(unsigned int bits) - { - return ((bits) + integerPartWidth - 1) / integerPartWidth; - } +static inline unsigned int +partCountForBits(unsigned int bits) +{ + return ((bits) + integerPartWidth - 1) / integerPartWidth; +} - /* Returns 0U-9U. Return values >= 10U are not digits. */ - static inline unsigned int - decDigitValue(unsigned int c) - { - return c - '0'; - } +/* Returns 0U-9U. Return values >= 10U are not digits. */ +static inline unsigned int +decDigitValue(unsigned int c) +{ + return c - '0'; +} - static unsigned int - hexDigitValue(unsigned int c) - { - unsigned int r; +static unsigned int +hexDigitValue(unsigned int c) +{ + unsigned int r; - r = c - '0'; - if(r <= 9) - return r; + r = c - '0'; + if(r <= 9) + return r; - r = c - 'A'; - if(r <= 5) - return r + 10; + r = c - 'A'; + if(r <= 5) + return r + 10; - r = c - 'a'; - if(r <= 5) - return r + 10; + r = c - 'a'; + if(r <= 5) + return r + 10; - return -1U; - } + return -1U; +} - static inline void - assertArithmeticOK(const llvm::fltSemantics &semantics) { - assert(semantics.arithmeticOK - && "Compile-time arithmetic does not support these semantics"); - } +static 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. +/* Return the value of a decimal exponent of the form + [+-]ddddddd. - If the exponent overflows, returns a large exponent with the - appropriate sign. */ - static int - readExponent(const char *p) - { - bool isNegative; - unsigned int absExponent; - const unsigned int overlargeExponent = 24000; /* FIXME. */ + If the exponent overflows, returns a large exponent with the + appropriate sign. */ +static int +readExponent(const char *p) +{ + bool isNegative; + unsigned int absExponent; + const unsigned int overlargeExponent = 24000; /* FIXME. */ - isNegative = (*p == '-'); - if (*p == '-' || *p == '+') - p++; + isNegative = (*p == '-'); + if (*p == '-' || *p == '+') + p++; - absExponent = decDigitValue(*p++); - assert (absExponent < 10U); + absExponent = decDigitValue(*p++); + assert (absExponent < 10U); - for (;;) { - unsigned int value; + for (;;) { + unsigned int value; - value = decDigitValue(*p); - if (value >= 10U) - break; + value = decDigitValue(*p); + if (value >= 10U) + break; - p++; - value += absExponent * 10; - if (absExponent >= overlargeExponent) { - absExponent = overlargeExponent; - break; - } - absExponent = value; + p++; + value += absExponent * 10; + if (absExponent >= overlargeExponent) { + absExponent = overlargeExponent; + break; } - - if (isNegative) - return -(int) absExponent; - else - return (int) absExponent; + absExponent = value; } - /* This is ugly and needs cleaning up, but I don't immediately see - how whilst remaining safe. */ - static int - totalExponent(const char *p, int exponentAdjustment) - { - int unsignedExponent; - bool negative, overflow; - int exponent; + 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 +totalExponent(const char *p, int exponentAdjustment) +{ + int unsignedExponent; + bool negative, overflow; + int exponent; - /* Move past the exponent letter and sign to the digits. */ + /* Move past the exponent letter and sign to the digits. */ + p++; + negative = *p == '-'; + if(*p == '-' || *p == '+') p++; - negative = *p == '-'; - if(*p == '-' || *p == '+') - p++; - unsignedExponent = 0; - overflow = false; - for(;;) { - unsigned int value; + unsignedExponent = 0; + overflow = false; + for(;;) { + unsigned int value; - value = decDigitValue(*p); - if(value >= 10U) - break; + value = decDigitValue(*p); + if(value >= 10U) + break; - p++; - unsignedExponent = unsignedExponent * 10 + value; - if(unsignedExponent > 65535) - overflow = true; - } + p++; + unsignedExponent = unsignedExponent * 10 + value; + if(unsignedExponent > 65535) + overflow = true; + } + + if(exponentAdjustment > 65535 || exponentAdjustment < -65536) + overflow = true; - if(exponentAdjustment > 65535 || exponentAdjustment < -65536) + if(!overflow) { + exponent = unsignedExponent; + if(negative) + exponent = -exponent; + exponent += exponentAdjustment; + if(exponent > 65535 || exponent < -65536) overflow = true; + } - if(!overflow) { - exponent = unsignedExponent; - if(negative) - exponent = -exponent; - exponent += exponentAdjustment; - if(exponent > 65535 || exponent < -65536) - overflow = true; - } + if(overflow) + exponent = negative ? -65536: 65535; - if(overflow) - exponent = negative ? -65536: 65535; + return exponent; +} - return exponent; - } +static const char * +skipLeadingZeroesAndAnyDot(const char *p, const char **dot) +{ + *dot = 0; + while(*p == '0') + p++; - static const char * - skipLeadingZeroesAndAnyDot(const char *p, const char **dot) - { - *dot = 0; + if(*p == '.') { + *dot = p++; while(*p == '0') p++; - - if(*p == '.') { - *dot = p++; - while(*p == '0') - p++; - } - - return p; } - /* Given a normal decimal floating point number of the form + return p; +} - dddd.dddd[eE][+-]ddd +/* Given a normal decimal floating point number of the form - 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. + dddd.dddd[eE][+-]ddd - 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; - }; + 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. - static void - interpretDecimal(const char *p, decimalInfo *D) - { - const char *dot; + 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; +}; - p = skipLeadingZeroesAndAnyDot (p, &dot); +static void +interpretDecimal(const char *p, decimalInfo *D) +{ + const char *dot; - D->firstSigDigit = p; - D->exponent = 0; - D->normalizedExponent = 0; + p = skipLeadingZeroesAndAnyDot (p, &dot); - for (;;) { - if (*p == '.') { - assert(dot == 0); - dot = p++; - } - if (decDigitValue(*p) >= 10U) - break; - p++; + 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); + /* 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; + /* Implied decimal point? */ + if (!dot) + dot = p; - /* Drop insignificant trailing zeroes. */ + /* Drop insignificant trailing zeroes. */ + do do - do - p--; - while (*p == '0'); - while (*p == '.'); - - /* Adjust the exponents for any decimal point. */ - D->exponent += static_cast((dot - p) - (dot > p)); - D->normalizedExponent = (D->exponent + - static_cast((p - D->firstSigDigit) - - (dot > D->firstSigDigit && dot < p))); - } + p--; + while (*p == '0'); + while (*p == '.'); - D->lastSigDigit = p; + /* Adjust the exponents for any decimal point. */ + D->exponent += static_cast((dot - p) - (dot > p)); + D->normalizedExponent = (D->exponent + + static_cast((p - D->firstSigDigit) + - (dot > D->firstSigDigit && dot < p))); } - /* Return the trailing fraction of a hexadecimal number. - DIGITVALUE is the first hex digit of the fraction, P points to - the next digit. */ - static lostFraction - trailingHexadecimalFraction(const char *p, unsigned int digitValue) - { - unsigned int hexDigit; + D->lastSigDigit = p; +} - /* If the first trailing digit isn't 0 or 8 we can work out the - fraction immediately. */ - if(digitValue > 8) - return lfMoreThanHalf; - else if(digitValue < 8 && digitValue > 0) - return lfLessThanHalf; +/* Return the trailing fraction of a hexadecimal number. + DIGITVALUE is the first hex digit of the fraction, P points to + the next digit. */ +static lostFraction +trailingHexadecimalFraction(const char *p, unsigned int digitValue) +{ + unsigned int hexDigit; - /* Otherwise we need to find the first non-zero digit. */ - while(*p == '0') - p++; + /* If the first trailing digit isn't 0 or 8 we can work out the + fraction immediately. */ + if(digitValue > 8) + return lfMoreThanHalf; + else if(digitValue < 8 && digitValue > 0) + return lfLessThanHalf; - hexDigit = hexDigitValue(*p); + /* Otherwise we need to find the first non-zero digit. */ + while(*p == '0') + p++; - /* If we ran off the end it is exactly zero or one-half, otherwise - a little more. */ - if(hexDigit == -1U) - return digitValue == 0 ? lfExactlyZero: lfExactlyHalf; - else - return digitValue == 0 ? lfLessThanHalf: lfMoreThanHalf; - } + hexDigit = hexDigitValue(*p); - /* Return the fraction lost were a bignum truncated losing the least - significant BITS bits. */ - static lostFraction - lostFractionThroughTruncation(const integerPart *parts, - unsigned int partCount, - unsigned int bits) - { - unsigned int lsb; + /* If we ran off the end it is exactly zero or one-half, otherwise + a little more. */ + if(hexDigit == -1U) + return digitValue == 0 ? lfExactlyZero: lfExactlyHalf; + else + return digitValue == 0 ? lfLessThanHalf: lfMoreThanHalf; +} - lsb = APInt::tcLSB(parts, partCount); +/* Return the fraction lost were a bignum truncated losing the least + significant BITS bits. */ +static lostFraction +lostFractionThroughTruncation(const integerPart *parts, + unsigned int partCount, + unsigned int bits) +{ + unsigned int lsb; - /* Note this is guaranteed true if bits == 0, or LSB == -1U. */ - if(bits <= lsb) - return lfExactlyZero; - if(bits == lsb + 1) - return lfExactlyHalf; - if(bits <= partCount * integerPartWidth - && APInt::tcExtractBit(parts, bits - 1)) - return lfMoreThanHalf; + lsb = APInt::tcLSB(parts, partCount); - return lfLessThanHalf; - } + /* Note this is guaranteed true if bits == 0, or LSB == -1U. */ + if(bits <= lsb) + return lfExactlyZero; + if(bits == lsb + 1) + return lfExactlyHalf; + if(bits <= partCount * integerPartWidth + && APInt::tcExtractBit(parts, bits - 1)) + return lfMoreThanHalf; - /* Shift DST right BITS bits noting lost fraction. */ - static lostFraction - shiftRight(integerPart *dst, unsigned int parts, unsigned int bits) - { - lostFraction lost_fraction; + return lfLessThanHalf; +} - lost_fraction = lostFractionThroughTruncation(dst, parts, bits); +/* Shift DST right BITS bits noting lost fraction. */ +static lostFraction +shiftRight(integerPart *dst, unsigned int parts, unsigned int bits) +{ + lostFraction lost_fraction; - APInt::tcShiftRight(dst, parts, bits); + lost_fraction = lostFractionThroughTruncation(dst, parts, bits); - return lost_fraction; - } + APInt::tcShiftRight(dst, parts, bits); - /* Combine the effect of two lost fractions. */ - static lostFraction - combineLostFractions(lostFraction moreSignificant, - lostFraction lessSignificant) - { - if(lessSignificant != lfExactlyZero) { - if(moreSignificant == lfExactlyZero) - moreSignificant = lfLessThanHalf; - else if(moreSignificant == lfExactlyHalf) - moreSignificant = lfMoreThanHalf; - } + return lost_fraction; +} - return moreSignificant; +/* Combine the effect of two lost fractions. */ +static lostFraction +combineLostFractions(lostFraction moreSignificant, + lostFraction lessSignificant) +{ + if(lessSignificant != lfExactlyZero) { + if(moreSignificant == lfExactlyZero) + moreSignificant = lfLessThanHalf; + else if(moreSignificant == lfExactlyHalf) + moreSignificant = lfMoreThanHalf; } - /* The error from the true value, in half-ulps, on multiplying two - floating point numbers, which differ from the value they - approximate by at most HUE1 and HUE2 half-ulps, is strictly less - than the returned value. + return moreSignificant; +} - See "How to Read Floating Point Numbers Accurately" by William D - Clinger. */ - static unsigned int - HUerrBound(bool inexactMultiply, unsigned int HUerr1, unsigned int HUerr2) - { - assert(HUerr1 < 2 || HUerr2 < 2 || (HUerr1 + HUerr2 < 8)); +/* The error from the true value, in half-ulps, on multiplying two + floating point numbers, which differ from the value they + approximate by at most HUE1 and HUE2 half-ulps, is strictly less + than the returned value. - if (HUerr1 + HUerr2 == 0) - return inexactMultiply * 2; /* <= inexactMultiply half-ulps. */ - else - return inexactMultiply + 2 * (HUerr1 + HUerr2); - } + See "How to Read Floating Point Numbers Accurately" by William D + Clinger. */ +static unsigned int +HUerrBound(bool inexactMultiply, unsigned int HUerr1, unsigned int HUerr2) +{ + assert(HUerr1 < 2 || HUerr2 < 2 || (HUerr1 + HUerr2 < 8)); - /* The number of ulps from the boundary (zero, or half if ISNEAREST) - when the least significant BITS are truncated. BITS cannot be - zero. */ - static integerPart - ulpsFromBoundary(const integerPart *parts, unsigned int bits, bool isNearest) - { - unsigned int count, partBits; - integerPart part, boundary; + if (HUerr1 + HUerr2 == 0) + return inexactMultiply * 2; /* <= inexactMultiply half-ulps. */ + else + return inexactMultiply + 2 * (HUerr1 + HUerr2); +} - assert (bits != 0); +/* The number of ulps from the boundary (zero, or half if ISNEAREST) + when the least significant BITS are truncated. BITS cannot be + zero. */ +static integerPart +ulpsFromBoundary(const integerPart *parts, unsigned int bits, bool isNearest) +{ + unsigned int count, partBits; + integerPart part, boundary; - bits--; - count = bits / integerPartWidth; - partBits = bits % integerPartWidth + 1; + assert (bits != 0); - part = parts[count] & (~(integerPart) 0 >> (integerPartWidth - partBits)); + bits--; + count = bits / integerPartWidth; + partBits = bits % integerPartWidth + 1; - if (isNearest) - boundary = (integerPart) 1 << (partBits - 1); - else - boundary = 0; + part = parts[count] & (~(integerPart) 0 >> (integerPartWidth - partBits)); - if (count == 0) { - if (part - boundary <= boundary - part) - return part - boundary; - else - return boundary - part; - } + if (isNearest) + boundary = (integerPart) 1 << (partBits - 1); + else + boundary = 0; - if (part == boundary) { - while (--count) - if (parts[count]) - return ~(integerPart) 0; /* A lot. */ + if (count == 0) { + if (part - boundary <= boundary - part) + return part - boundary; + else + return boundary - part; + } - return parts[0]; - } else if (part == boundary - 1) { - while (--count) - if (~parts[count]) - return ~(integerPart) 0; /* A lot. */ + if (part == boundary) { + while (--count) + if (parts[count]) + return ~(integerPart) 0; /* A lot. */ - return -parts[0]; - } + return parts[0]; + } else if (part == boundary - 1) { + while (--count) + if (~parts[count]) + return ~(integerPart) 0; /* A lot. */ - return ~(integerPart) 0; /* A lot. */ + return -parts[0]; } - /* 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 - powerOf5(integerPart *dst, unsigned int power) - { - static const integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125, - 15625, 78125 }; - static integerPart pow5s[maxPowerOfFiveParts * 2 + 5] = { 78125 * 5 }; - static unsigned int partsCount[16] = { 1 }; - - integerPart scratch[maxPowerOfFiveParts], *p1, *p2, *pow5; - unsigned int result; - - assert(power <= maxExponent); + return ~(integerPart) 0; /* A lot. */ +} - p1 = dst; - p2 = scratch; +/* 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 +powerOf5(integerPart *dst, unsigned int power) +{ + static const integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125, + 15625, 78125 }; + integerPart pow5s[maxPowerOfFiveParts * 2 + 5]; + pow5s[0] = 78125 * 5; + + unsigned int partsCount[16] = { 1 }; + integerPart scratch[maxPowerOfFiveParts], *p1, *p2, *pow5; + unsigned int result; + assert(power <= maxExponent); - *p1 = firstEightPowers[power & 7]; - power >>= 3; + p1 = dst; + p2 = scratch; - result = 1; - pow5 = pow5s; + *p1 = firstEightPowers[power & 7]; + power >>= 3; - for (unsigned int n = 0; power; power >>= 1, n++) { - unsigned int pc; + result = 1; + pow5 = pow5s; - pc = partsCount[n]; + for (unsigned int n = 0; power; power >>= 1, n++) { + unsigned int pc; - /* Calculate pow(5,pow(2,n+3)) if we haven't yet. */ - if (pc == 0) { - pc = partsCount[n - 1]; - APInt::tcFullMultiply(pow5, pow5 - pc, pow5 - pc, pc, pc); - pc *= 2; - if (pow5[pc - 1] == 0) - pc--; - partsCount[n] = pc; - } + pc = partsCount[n]; - if (power & 1) { - integerPart *tmp; + /* Calculate pow(5,pow(2,n+3)) if we haven't yet. */ + if (pc == 0) { + pc = partsCount[n - 1]; + APInt::tcFullMultiply(pow5, pow5 - pc, pow5 - pc, pc, pc); + pc *= 2; + if (pow5[pc - 1] == 0) + pc--; + partsCount[n] = pc; + } - APInt::tcFullMultiply(p2, p1, pow5, result, pc); - result += pc; - if (p2[result - 1] == 0) - result--; + if (power & 1) { + integerPart *tmp; - /* Now result is in p1 with partsCount parts and p2 is scratch - space. */ - tmp = p1, p1 = p2, p2 = tmp; - } + APInt::tcFullMultiply(p2, p1, pow5, result, pc); + result += pc; + if (p2[result - 1] == 0) + result--; - pow5 += pc; + /* Now result is in p1 with partsCount parts and p2 is scratch + space. */ + tmp = p1, p1 = p2, p2 = tmp; } - if (p1 != dst) - APInt::tcAssign(dst, p1, result); - - return result; + pow5 += pc; } - /* Zero at the end to avoid modular arithmetic when adding one; used - when rounding up during hexadecimal output. */ - static const char hexDigitsLower[] = "0123456789abcdef0"; - static const char hexDigitsUpper[] = "0123456789ABCDEF0"; - static const char infinityL[] = "infinity"; - static const char infinityU[] = "INFINITY"; - static const char NaNL[] = "nan"; - static const char NaNU[] = "NAN"; + if (p1 != dst) + APInt::tcAssign(dst, p1, result); - /* Write out an integerPart in hexadecimal, starting with the most - significant nibble. Write out exactly COUNT hexdigits, return - COUNT. */ - static unsigned int - partAsHex (char *dst, integerPart part, unsigned int count, - const char *hexDigitChars) - { - unsigned int result = count; + return result; +} - assert (count != 0 && count <= integerPartWidth / 4); +/* Zero at the end to avoid modular arithmetic when adding one; used + when rounding up during hexadecimal output. */ +static const char hexDigitsLower[] = "0123456789abcdef0"; +static const char hexDigitsUpper[] = "0123456789ABCDEF0"; +static const char infinityL[] = "infinity"; +static const char infinityU[] = "INFINITY"; +static const char NaNL[] = "nan"; +static const char NaNU[] = "NAN"; - part >>= (integerPartWidth - 4 * count); - while (count--) { - dst[count] = hexDigitChars[part & 0xf]; - part >>= 4; - } +/* Write out an integerPart in hexadecimal, starting with the most + significant nibble. Write out exactly COUNT hexdigits, return + COUNT. */ +static unsigned int +partAsHex (char *dst, integerPart part, unsigned int count, + const char *hexDigitChars) +{ + unsigned int result = count; + + assert (count != 0 && count <= integerPartWidth / 4); - return result; + part >>= (integerPartWidth - 4 * count); + while (count--) { + dst[count] = hexDigitChars[part & 0xf]; + part >>= 4; } - /* Write out an unsigned decimal integer. */ - static char * - writeUnsignedDecimal (char *dst, unsigned int n) - { - char buff[40], *p; + return result; +} - p = buff; - do - *p++ = '0' + n % 10; - while (n /= 10); +/* Write out an unsigned decimal integer. */ +static char * +writeUnsignedDecimal (char *dst, unsigned int n) +{ + char buff[40], *p; - do - *dst++ = *--p; - while (p != buff); + p = buff; + do + *p++ = '0' + n % 10; + while (n /= 10); - return dst; - } + do + *dst++ = *--p; + while (p != buff); - /* Write out a signed decimal integer. */ - static char * - writeSignedDecimal (char *dst, int value) - { - if (value < 0) { - *dst++ = '-'; - dst = writeUnsignedDecimal(dst, -(unsigned) value); - } else - dst = writeUnsignedDecimal(dst, value); + return dst; +} - return dst; - } +/* Write out a signed decimal integer. */ +static char * +writeSignedDecimal (char *dst, int value) +{ + if (value < 0) { + *dst++ = '-'; + dst = writeUnsignedDecimal(dst, -(unsigned) value); + } else + dst = writeUnsignedDecimal(dst, value); + + return dst; } /* Constructors. */ @@ -599,7 +597,8 @@ APFloat::copySignificand(const APFloat &rhs) } /* Make this number a NaN, with an arbitrary but deterministic value - for the significand. */ + for the significand. If double or longer, this is a signalling NaN, + which may not be ideal. */ void APFloat::makeNaN(void) { @@ -695,7 +694,7 @@ APFloat::~APFloat() // Profile - This method 'profiles' an APFloat for use with FoldingSet. void APFloat::Profile(FoldingSetNodeID& ID) const { - ID.Add(convertToAPInt()); + ID.Add(bitcastToAPInt()); } unsigned int @@ -788,6 +787,7 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) integerPart scratch[4]; integerPart *fullSignificand; lostFraction lost_fraction; + bool ignored; assert(semantics == rhs.semantics); @@ -836,7 +836,7 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) semantics = &extendedSemantics; APFloat extendedAddend(*addend); - status = extendedAddend.convert(extendedSemantics, rmTowardZero); + status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored); assert(status == opOK); lost_fraction = addOrSubtractSignificand(extendedAddend, false); @@ -1237,7 +1237,7 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract) case convolve(fcInfinity, fcInfinity): /* Differently signed infinities can only be validly subtracted. */ - if((sign ^ rhs.sign) != subtract) { + if(((sign ^ rhs.sign)!=0) != subtract) { makeNaN(); return opInvalidOp; } @@ -1404,6 +1404,42 @@ APFloat::divideSpecials(const APFloat &rhs) } } +APFloat::opStatus +APFloat::modSpecials(const APFloat &rhs) +{ + switch(convolve(category, rhs.category)) { + default: + assert(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): + return opOK; + + case convolve(fcZero, fcNaN): + case convolve(fcNormal, fcNaN): + case convolve(fcInfinity, fcNaN): + category = fcNaN; + copySignificand(rhs); + return opOK; + + case convolve(fcNormal, fcZero): + case convolve(fcInfinity, fcZero): + case convolve(fcInfinity, fcNormal): + case convolve(fcInfinity, fcInfinity): + case convolve(fcZero, fcZero): + makeNaN(); + return opInvalidOp; + + case convolve(fcNormal, fcNormal): + return opOK; + } +} + /* Change sign. */ void APFloat::changeSign() @@ -1513,9 +1549,9 @@ APFloat::divide(const APFloat &rhs, roundingMode rounding_mode) return fs; } -/* Normalized remainder. This is not currently doing TRT. */ +/* Normalized remainder. This is not currently correct in all cases. */ APFloat::opStatus -APFloat::mod(const APFloat &rhs, roundingMode rounding_mode) +APFloat::remainder(const APFloat &rhs) { opStatus fs; APFloat V = *this; @@ -1528,8 +1564,9 @@ APFloat::mod(const APFloat &rhs, roundingMode rounding_mode) int parts = partCount(); integerPart *x = new integerPart[parts]; + bool ignored; fs = V.convertToInteger(x, parts * integerPartWidth, true, - rmNearestTiesToEven); + rmNearestTiesToEven, &ignored); if (fs==opInvalidOp) return fs; @@ -1537,10 +1574,10 @@ APFloat::mod(const APFloat &rhs, roundingMode rounding_mode) rmNearestTiesToEven); assert(fs==opOK); // should always work - fs = V.multiply(rhs, rounding_mode); + fs = V.multiply(rhs, rmNearestTiesToEven); assert(fs==opOK || fs==opInexact); // should not overflow or underflow - fs = subtract(V, rounding_mode); + fs = subtract(V, rmNearestTiesToEven); assert(fs==opOK || fs==opInexact); // likewise if (isZero()) @@ -1549,6 +1586,48 @@ APFloat::mod(const APFloat &rhs, roundingMode rounding_mode) return fs; } +/* Normalized llvm frem (C fmod). + This is not currently correct in all cases. */ +APFloat::opStatus +APFloat::mod(const APFloat &rhs, roundingMode rounding_mode) +{ + opStatus fs; + assertArithmeticOK(*semantics); + fs = modSpecials(rhs); + + if (category == fcNormal && rhs.category == fcNormal) { + APFloat V = *this; + unsigned int origSign = sign; + + fs = V.divide(rhs, rmNearestTiesToEven); + if (fs == opDivByZero) + return fs; + + int parts = partCount(); + integerPart *x = new integerPart[parts]; + bool ignored; + fs = V.convertToInteger(x, parts * integerPartWidth, true, + rmTowardZero, &ignored); + if (fs==opInvalidOp) + return fs; + + fs = V.convertFromZeroExtendedInteger(x, parts * integerPartWidth, true, + rmNearestTiesToEven); + assert(fs==opOK); // should always work + + fs = V.multiply(rhs, rounding_mode); + assert(fs==opOK || fs==opInexact); // should not overflow or underflow + + fs = subtract(V, rounding_mode); + assert(fs==opOK || fs==opInexact); // likewise + + if (isZero()) + sign = origSign; // IEEE754 requires this + delete[] x; + } + return fs; +} + /* Normalized fused-multiply-add. */ APFloat::opStatus APFloat::fusedMultiplyAdd(const APFloat &multiplicand, @@ -1670,9 +1749,16 @@ APFloat::compare(const APFloat &rhs) const return result; } +/// APFloat::convert - convert a value of one floating point type to another. +/// The return value corresponds to the IEEE754 exceptions. *losesInfo +/// records whether the transformation lost information, i.e. whether +/// converting the result back to the original type will produce the +/// original value (this is almost the same as return value==fsOK, but there +/// are edge cases where this is not so). + APFloat::opStatus APFloat::convert(const fltSemantics &toSemantics, - roundingMode rounding_mode) + roundingMode rounding_mode, bool *losesInfo) { lostFraction lostFraction; unsigned int newPartCount, oldPartCount; @@ -1718,38 +1804,41 @@ APFloat::convert(const fltSemantics &toSemantics, 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; - fs = opOK; + *losesInfo = false; // No normalization here, just truncate if (shift>0) APInt::tcShiftLeft(significandParts(), newPartCount, shift); else if (shift < 0) { unsigned ushift = -shift; - // We mark this as Inexact if we are losing information. This happens + // 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) - fs = opInexact; + *losesInfo = true; if (oldSemantics == &APFloat::x87DoubleExtended && (!(*significandParts() & 0x8000000000000000ULL) || !(*significandParts() & 0x4000000000000000ULL))) - fs = opInexact; + *losesInfo = true; APInt::tcShiftRight(significandParts(), newPartCount, ushift); } // 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; } return fs; @@ -1768,7 +1857,8 @@ APFloat::convert(const fltSemantics &toSemantics, APFloat::opStatus APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width, bool isSigned, - roundingMode rounding_mode) const + roundingMode rounding_mode, + bool *isExact) const { lostFraction lost_fraction; const integerPart *src; @@ -1776,6 +1866,8 @@ APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width, assertArithmeticOK(*semantics); + *isExact = false; + /* Handle the three special cases first. */ if(category == fcInfinity || category == fcNaN) return opInvalidOp; @@ -1784,6 +1876,8 @@ APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width, if(category == fcZero) { APInt::tcSet(parts, 0, dstPartsCount); + // Negative zero can't be represented as an int. + *isExact = !sign; return opOK; } @@ -1794,7 +1888,9 @@ APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width, if (exponent < 0) { /* Our absolute value is less than one; truncate everything. */ APInt::tcSet(parts, 0, dstPartsCount); - truncatedBits = semantics->precision; + /* For exponent -1 the integer bit represents .5, look at that. + For smaller exponents leftmost truncated bit is 0. */ + truncatedBits = semantics->precision -1U - exponent; } else { /* We want the most significant (exponent + 1) bits; the rest are truncated. */ @@ -1856,24 +1952,31 @@ APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width, return opInvalidOp; } - if (lost_fraction == lfExactlyZero) + if (lost_fraction == lfExactlyZero) { + *isExact = true; return opOK; - else + } else return opInexact; } /* 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. */ + for underflow or overflow. + The *isExact output tells whether the result is exact, in the sense + that converting it back to the original floating point type produces + the original value. This is almost equivalent to result==opOK, + except for negative zeroes. +*/ APFloat::opStatus APFloat::convertToInteger(integerPart *parts, unsigned int width, bool isSigned, - roundingMode rounding_mode) const + roundingMode rounding_mode, bool *isExact) const { opStatus fs; - fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode); + fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode, + isExact); if (fs == opInvalidOp) { unsigned int bits, dstPartsCount; @@ -2266,8 +2369,8 @@ APFloat::convertFromString(const char *p, roundingMode rounding_mode) if(p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) return convertFromHexadecimalString(p + 2, rounding_mode); - else - return convertFromDecimalString(p, rounding_mode); + + return convertFromDecimalString(p, rounding_mode); } /* Write out a hexadecimal representation of the floating point value @@ -2616,7 +2719,7 @@ APFloat::convertFloatAPFloatToAPInt() const // and treating the result as a normal integer is unlikely to be useful. APInt -APFloat::convertToAPInt() const +APFloat::bitcastToAPInt() const { if (semantics == (const llvm::fltSemantics*)&IEEEsingle) return convertFloatAPFloatToAPInt(); @@ -2636,7 +2739,7 @@ float APFloat::convertToFloat() const { assert(semantics == (const llvm::fltSemantics*)&IEEEsingle); - APInt api = convertToAPInt(); + APInt api = bitcastToAPInt(); return api.bitsToFloat(); } @@ -2644,7 +2747,7 @@ double APFloat::convertToDouble() const { assert(semantics == (const llvm::fltSemantics*)&IEEEdouble); - APInt api = convertToAPInt(); + APInt api = bitcastToAPInt(); return api.bitsToDouble(); }