X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FSupport%2FAPFloat.cpp;h=b9b323c4242826176685eee547857b58325639e7;hb=05872ea804cdc9534960b30d28a391928c61481a;hp=88d158ae13a94995257bcb3e85db8f423e1cb8f1;hpb=43a4b28e94598ea8accd7a97f8e1b5902731f340;p=oota-llvm.git diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 88d158ae13a..b9b323c4242 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,10 +12,12 @@ // //===----------------------------------------------------------------------===// -#include -#include #include "llvm/ADT/APFloat.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/FoldingSet.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" +#include using namespace llvm; @@ -23,6 +25,7 @@ using namespace llvm; /* Assumed in hexadecimal significand parsing, and conversion to hexadecimal strings. */ +#define COMPILE_TIME_ASSERT(cond) extern int CTAssert[(cond) ? 1 : -1] COMPILE_TIME_ASSERT(integerPartWidth % 4 == 0); namespace llvm { @@ -45,6 +48,7 @@ namespace llvm { unsigned int arithmeticOK; }; + const fltSemantics APFloat::IEEEhalf = { 15, -14, 11, true }; const fltSemantics APFloat::IEEEsingle = { 127, -126, 24, true }; const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53, true }; const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, true }; @@ -74,483 +78,505 @@ namespace llvm { / (351 * integerPartWidth)); } -/* Put a bunch of private, handy routines in an anonymous namespace. */ -namespace { +/* A bunch of private, handy routines. */ - 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. */ - 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'; +} - 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; +} - 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(StringRef::iterator begin, StringRef::iterator end) +{ + bool isNegative; + unsigned int absExponent; + const unsigned int overlargeExponent = 24000; /* FIXME. */ + StringRef::iterator p = begin; - isNegative = (*p == '-'); - if (*p == '-' || *p == '+') - p++; + assert(p != end && "Exponent has no digits"); - absExponent = decDigitValue(*p++); - assert (absExponent < 10U); + isNegative = (*p == '-'); + if (*p == '-' || *p == '+') { + p++; + assert(p != end && "Exponent has no digits"); + } - for (;;) { - unsigned int value; + absExponent = decDigitValue(*p++); + assert(absExponent < 10U && "Invalid character in exponent"); - value = decDigitValue(*p); - if (value >= 10U) - break; + for (; p != end; ++p) { + unsigned int value; - p++; - value += absExponent * 10; - if (absExponent >= overlargeExponent) { - absExponent = overlargeExponent; - break; - } - absExponent = value; - } + value = decDigitValue(*p); + assert(value < 10U && "Invalid character in exponent"); - if (isNegative) - return -(int) absExponent; - else - return (int) absExponent; + value += absExponent * 10; + if (absExponent >= overlargeExponent) { + absExponent = overlargeExponent; + break; + } + 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) - { - integerPart unsignedExponent; - bool negative, overflow; - long exponent; + assert(p == end && "Invalid exponent in exponent"); - /* Move past the exponent letter and sign to the digits. */ - p++; - negative = *p == '-'; - if(*p == '-' || *p == '+') - p++; + if (isNegative) + return -(int) absExponent; + else + return (int) absExponent; +} - unsignedExponent = 0; - overflow = false; - for(;;) { - unsigned int value; +/* This is ugly and needs cleaning up, but I don't immediately see + how whilst remaining safe. */ +static int +totalExponent(StringRef::iterator p, StringRef::iterator end, + int exponentAdjustment) +{ + int unsignedExponent; + bool negative, overflow; + int exponent; - value = decDigitValue(*p); - if(value >= 10U) - break; + assert(p != end && "Exponent has no digits"); - p++; - unsignedExponent = unsignedExponent * 10 + value; - if(unsignedExponent > 65535) - overflow = true; - } + negative = *p == '-'; + if(*p == '-' || *p == '+') { + p++; + assert(p != end && "Exponent has no digits"); + } - if(exponentAdjustment > 65535 || exponentAdjustment < -65536) - overflow = true; + unsignedExponent = 0; + overflow = false; + for(; p != end; ++p) { + unsigned int value; - if(!overflow) { - exponent = unsignedExponent; - if(negative) - exponent = -exponent; - exponent += exponentAdjustment; - if(exponent > 65535 || exponent < -65536) - overflow = true; - } + value = decDigitValue(*p); + assert(value < 10U && "Invalid character in exponent"); - if(overflow) - exponent = negative ? -65536: 65535; + unsignedExponent = unsignedExponent * 10 + value; + if(unsignedExponent > 65535) + overflow = true; + } - return exponent; + if(exponentAdjustment > 65535 || exponentAdjustment < -65536) + overflow = true; + + if(!overflow) { + exponent = unsignedExponent; + if(negative) + exponent = -exponent; + exponent += exponentAdjustment; + if(exponent > 65535 || exponent < -65536) + overflow = true; } - const char * - skipLeadingZeroesAndAnyDot(const char *p, const char **dot) - { - *dot = 0; - while(*p == '0') - p++; + if(overflow) + exponent = negative ? -65536: 65535; - if(*p == '.') { - *dot = p++; - while(*p == '0') - p++; - } + return exponent; +} - return p; - } +static StringRef::iterator +skipLeadingZeroesAndAnyDot(StringRef::iterator begin, StringRef::iterator end, + StringRef::iterator *dot) +{ + StringRef::iterator p = begin; + *dot = end; + while(*p == '0' && p != end) + p++; - /* Given a normal decimal floating point number of the form + if(*p == '.') { + *dot = p++; - dddd.dddd[eE][+-]ddd + assert(end - begin != 1 && "Significand has no digits"); - 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. + while(*p == '0' && p != end) + p++; + } - If the value is zero, V->firstSigDigit points to a zero, and the - return exponent is zero. - */ - struct decimalInfo { - const char *firstSigDigit; - const char *lastSigDigit; - int exponent; - int normalizedExponent; - }; + return p; +} - void - interpretDecimal(const char *p, decimalInfo *D) - { - const char *dot; +/* Given a normal decimal floating point number of the form - p = skipLeadingZeroesAndAnyDot (p, &dot); + dddd.dddd[eE][+-]ddd - D->firstSigDigit = p; - D->exponent = 0; - D->normalizedExponent = 0; + 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. - for (;;) { - if (*p == '.') { - assert(dot == 0); - dot = p++; - } - if (decDigitValue(*p) >= 10U) + 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; +}; + +static void +interpretDecimal(StringRef::iterator begin, StringRef::iterator end, + decimalInfo *D) +{ + StringRef::iterator dot = end; + StringRef::iterator p = skipLeadingZeroesAndAnyDot (begin, end, &dot); + + D->firstSigDigit = p; + D->exponent = 0; + D->normalizedExponent = 0; + + for (; p != end; ++p) { + if (*p == '.') { + assert(dot == end && "String contains multiple dots"); + dot = p++; + if (p == end) break; - p++; } + if (decDigitValue(*p) >= 10U) + break; + } - /* If number is all zerooes accept any exponent. */ - if (p != D->firstSigDigit) { - if (*p == 'e' || *p == 'E') - D->exponent = readExponent(p + 1); + if (p != end) { + assert((*p == 'e' || *p == 'E') && "Invalid character in significand"); + assert(p != begin && "Significand has no digits"); + assert((dot == end || p - begin != 1) && "Significand has no digits"); - /* Implied decimal point? */ - if (!dot) - dot = p; + /* p points to the first non-digit in the string */ + D->exponent = readExponent(p + 1, end); + + /* Implied decimal point? */ + if (dot == end) + dot = p; + } - /* Drop insignificant trailing zeroes. */ + /* If number is all zeroes accept any exponent. */ + if (p != D->firstSigDigit) { + /* Drop insignificant trailing zeroes. */ + if (p != begin) { 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)); + while (p != begin && *p == '0'); + while (p != begin && *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. */ - lostFraction - trailingHexadecimalFraction(const char *p, unsigned int digitValue) - { - unsigned int hexDigit; - - /* 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; - - /* Otherwise we need to find the first non-zero digit. */ - while(*p == '0') - p++; + D->lastSigDigit = p; +} - hexDigit = hexDigitValue(*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(StringRef::iterator p, StringRef::iterator end, + unsigned int digitValue) +{ + unsigned int hexDigit; - /* 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; - } + /* 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 fraction lost were a bignum truncated losing the least - significant BITS bits. */ - lostFraction - lostFractionThroughTruncation(const integerPart *parts, - unsigned int partCount, - unsigned int bits) - { - unsigned int lsb; + /* Otherwise we need to find the first non-zero digit. */ + while(*p == '0') + p++; - lsb = APInt::tcLSB(parts, partCount); + assert(p != end && "Invalid trailing hexadecimal fraction!"); - /* 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; + hexDigit = hexDigitValue(*p); - return lfLessThanHalf; - } + /* 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; +} - /* Shift DST right BITS bits noting lost fraction. */ - lostFraction - shiftRight(integerPart *dst, unsigned int parts, unsigned int bits) - { - lostFraction lost_fraction; +/* 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; - lost_fraction = lostFractionThroughTruncation(dst, parts, bits); + lsb = APInt::tcLSB(parts, partCount); - APInt::tcShiftRight(dst, parts, bits); + /* 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; - return lost_fraction; - } + return lfLessThanHalf; +} - /* Combine the effect of two lost fractions. */ - lostFraction - combineLostFractions(lostFraction moreSignificant, - lostFraction lessSignificant) - { - if(lessSignificant != lfExactlyZero) { - if(moreSignificant == lfExactlyZero) - moreSignificant = lfLessThanHalf; - else if(moreSignificant == lfExactlyHalf) - moreSignificant = lfMoreThanHalf; - } +/* Shift DST right BITS bits noting lost fraction. */ +static lostFraction +shiftRight(integerPart *dst, unsigned int parts, unsigned int bits) +{ + lostFraction lost_fraction; - return moreSignificant; - } + lost_fraction = lostFractionThroughTruncation(dst, parts, bits); - /* 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. + APInt::tcShiftRight(dst, parts, bits); - See "How to Read Floating Point Numbers Accurately" by William D - Clinger. */ - unsigned int - HUerrBound(bool inexactMultiply, unsigned int HUerr1, unsigned int HUerr2) - { - assert(HUerr1 < 2 || HUerr2 < 2 || (HUerr1 + HUerr2 < 8)); + return lost_fraction; +} - if (HUerr1 + HUerr2 == 0) - return inexactMultiply * 2; /* <= inexactMultiply half-ulps. */ - else - return inexactMultiply + 2 * (HUerr1 + HUerr2); +/* 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 number of ulps from the boundary (zero, or half if ISNEAREST) - when the least significant BITS are truncated. BITS cannot be - zero. */ - integerPart - ulpsFromBoundary(const integerPart *parts, unsigned int bits, bool isNearest) - { - unsigned int count, partBits; - integerPart part, boundary; + return moreSignificant; +} - assert (bits != 0); +/* 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. - bits--; - count = bits / integerPartWidth; - partBits = bits % integerPartWidth + 1; + 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)); - part = parts[count] & (~(integerPart) 0 >> (integerPartWidth - partBits)); + if (HUerr1 + HUerr2 == 0) + return inexactMultiply * 2; /* <= inexactMultiply half-ulps. */ + else + return inexactMultiply + 2 * (HUerr1 + HUerr2); +} - if (isNearest) - boundary = (integerPart) 1 << (partBits - 1); - else - boundary = 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; - if (count == 0) { - if (part - boundary <= boundary - part) - return part - boundary; - else - return boundary - part; - } + assert(bits != 0); - if (part == boundary) { - while (--count) - if (parts[count]) - return ~(integerPart) 0; /* A lot. */ + bits--; + count = bits / integerPartWidth; + partBits = bits % integerPartWidth + 1; - return parts[0]; - } else if (part == boundary - 1) { - while (--count) - if (~parts[count]) - return ~(integerPart) 0; /* A lot. */ + part = parts[count] & (~(integerPart) 0 >> (integerPartWidth - partBits)); - return -parts[0]; - } + if (isNearest) + boundary = (integerPart) 1 << (partBits - 1); + else + boundary = 0; - return ~(integerPart) 0; /* A lot. */ + if (count == 0) { + if (part - boundary <= boundary - part) + return part - boundary; + else + return boundary - part; } - /* 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 integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125, - 15625, 78125 }; - static integerPart pow5s[maxPowerOfFiveParts * 2 + 5] = { 78125 * 5 }; - static unsigned int partsCount[16] = { 1 }; + if (part == boundary) { + while (--count) + if (parts[count]) + return ~(integerPart) 0; /* A lot. */ - integerPart scratch[maxPowerOfFiveParts], *p1, *p2, *pow5; - unsigned int result; + return parts[0]; + } else if (part == boundary - 1) { + while (--count) + if (~parts[count]) + return ~(integerPart) 0; /* A lot. */ - assert(power <= maxExponent); + return -parts[0]; + } - p1 = dst; - p2 = scratch; + return ~(integerPart) 0; /* A lot. */ +} - *p1 = firstEightPowers[power & 7]; - power >>= 3; +/* 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); - result = 1; - pow5 = pow5s; + p1 = dst; + p2 = scratch; - for (unsigned int n = 0; power; power >>= 1, n++) { - unsigned int pc; + *p1 = firstEightPowers[power & 7]; + power >>= 3; - pc = partsCount[n]; + result = 1; + pow5 = pow5s; - /* 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; - } + for (unsigned int n = 0; power; power >>= 1, n++) { + unsigned int pc; - if (power & 1) { - integerPart *tmp; + pc = partsCount[n]; - APInt::tcFullMultiply(p2, p1, pow5, result, pc); - result += pc; - if (p2[result - 1] == 0) - result--; + /* 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; + } - /* Now result is in p1 with partsCount parts and p2 is scratch - space. */ - tmp = p1, p1 = p2, p2 = tmp; - } + if (power & 1) { + integerPart *tmp; - pow5 += pc; - } + APInt::tcFullMultiply(p2, p1, pow5, result, pc); + result += pc; + if (p2[result - 1] == 0) + result--; - if (p1 != dst) - APInt::tcAssign(dst, p1, result); + /* Now result is in p1 with partsCount parts and p2 is scratch + space. */ + tmp = p1, p1 = p2, p2 = tmp; + } - 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; - return result; + assert(count != 0 && count <= integerPartWidth / 4); + + 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. */ @@ -597,12 +623,19 @@ 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. If float, this is QNaN(0). */ void -APFloat::makeNaN(void) +APFloat::makeNaN(unsigned type) { category = fcNaN; - APInt::tcSet(significandParts(), ~0U, partCount()); + // FIXME: Add double and long double support for QNaN(0). + if (semantics->precision == 24 && semantics->maxExponent == 127) { + type |= 0x7fc00000U; + type &= ~0x80000000U; + } else + type = ~0U; + APInt::tcSet(significandParts(), type, partCount()); } APFloat & @@ -627,14 +660,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 { @@ -660,20 +693,28 @@ APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) normalize(rmNearestTiesToEven, lfExactlyZero); } +APFloat::APFloat(const fltSemantics &ourSemantics) { + assertArithmeticOK(ourSemantics); + initialize(&ourSemantics); + category = fcZero; + sign = false; +} + + APFloat::APFloat(const fltSemantics &ourSemantics, - fltCategory ourCategory, bool negative) + fltCategory ourCategory, bool negative, unsigned type) { assertArithmeticOK(ourSemantics); initialize(&ourSemantics); category = ourCategory; sign = negative; - if(category == fcNormal) + if (category == fcNormal) category = fcZero; else if (ourCategory == fcNaN) - makeNaN(); + makeNaN(type); } -APFloat::APFloat(const fltSemantics &ourSemantics, const char *text) +APFloat::APFloat(const fltSemantics &ourSemantics, const StringRef& text) { assertArithmeticOK(ourSemantics); initialize(&ourSemantics); @@ -691,6 +732,11 @@ APFloat::~APFloat() freeSignificand(); } +// Profile - This method 'profiles' an APFloat for use with FoldingSet. +void APFloat::Profile(FoldingSetNodeID& ID) const { + ID.Add(bitcastToAPInt()); +} + unsigned int APFloat::partCount() const { @@ -714,7 +760,7 @@ APFloat::significandParts() { assert(category == fcNormal || category == fcNaN); - if(partCount() > 1) + if (partCount() > 1) return significand.parts; else return &significand.part; @@ -781,6 +827,7 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend) integerPart scratch[4]; integerPart *fullSignificand; lostFraction lost_fraction; + bool ignored; assert(semantics == rhs.semantics); @@ -829,7 +876,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); @@ -1053,9 +1100,9 @@ APFloat::roundAwayFromZero(roundingMode rounding_mode, /* Current callers never pass this so we don't handle it. */ assert(lost_fraction != lfExactlyZero); - switch(rounding_mode) { + switch (rounding_mode) { default: - assert(0); + llvm_unreachable(0); case rmNearestTiesToAway: return lost_fraction == lfExactlyHalf || lost_fraction == lfMoreThanHalf; @@ -1192,9 +1239,9 @@ APFloat::normalize(roundingMode rounding_mode, APFloat::opStatus APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract) { - switch(convolve(category, rhs.category)) { + switch (convolve(category, rhs.category)) { default: - assert(0); + llvm_unreachable(0); case convolve(fcNaN, fcZero): case convolve(fcNaN, fcNormal): @@ -1230,7 +1277,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; } @@ -1316,9 +1363,9 @@ APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract) APFloat::opStatus APFloat::multiplySpecials(const APFloat &rhs) { - switch(convolve(category, rhs.category)) { + switch (convolve(category, rhs.category)) { default: - assert(0); + llvm_unreachable(0); case convolve(fcNaN, fcZero): case convolve(fcNaN, fcNormal): @@ -1358,9 +1405,9 @@ APFloat::multiplySpecials(const APFloat &rhs) APFloat::opStatus APFloat::divideSpecials(const APFloat &rhs) { - switch(convolve(category, rhs.category)) { + switch (convolve(category, rhs.category)) { default: - assert(0); + llvm_unreachable(0); case convolve(fcNaN, fcZero): case convolve(fcNaN, fcNormal): @@ -1397,6 +1444,42 @@ APFloat::divideSpecials(const APFloat &rhs) } } +APFloat::opStatus +APFloat::modSpecials(const APFloat &rhs) +{ + switch (convolve(category, rhs.category)) { + default: + llvm_unreachable(0); + + case convolve(fcNaN, fcZero): + case convolve(fcNaN, fcNormal): + case convolve(fcNaN, fcInfinity): + case convolve(fcNaN, fcNaN): + case convolve(fcZero, fcInfinity): + case convolve(fcZero, fcNormal): + case convolve(fcNormal, fcInfinity): + 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() @@ -1506,9 +1589,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; @@ -1521,8 +1604,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; @@ -1530,10 +1614,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()) @@ -1542,6 +1626,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, @@ -1598,9 +1724,9 @@ APFloat::compare(const APFloat &rhs) const assertArithmeticOK(*semantics); assert(semantics == rhs.semantics); - switch(convolve(category, rhs.category)) { + switch (convolve(category, rhs.category)) { default: - assert(0); + llvm_unreachable(0); case convolve(fcNaN, fcZero): case convolve(fcNaN, fcNormal): @@ -1663,15 +1789,23 @@ 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; opStatus fs; assertArithmeticOK(*semantics); + assertArithmeticOK(toSemantics); lostFraction = lfExactlyZero; newPartCount = partCountForBits(toSemantics.precision + 1); oldPartCount = partCount(); @@ -1710,22 +1844,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; + *losesInfo = false; // No normalization here, just truncate if (shift>0) APInt::tcShiftLeft(significandParts(), newPartCount, shift); - else if (shift < 0) - APInt::tcShiftRight(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); + } // 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. - semantics = &toSemantics; fs = opOK; } else { semantics = &toSemantics; fs = opOK; + *losesInfo = false; } return fs; @@ -1744,12 +1897,17 @@ 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; unsigned int dstPartsCount, truncatedBits; + assertArithmeticOK(*semantics); + + *isExact = false; + /* Handle the three special cases first. */ if(category == fcInfinity || category == fcNaN) return opInvalidOp; @@ -1758,6 +1916,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; } @@ -1768,7 +1928,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. */ @@ -1830,24 +1992,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; @@ -1904,6 +2073,23 @@ APFloat::convertFromUnsignedParts(const integerPart *src, return normalize(rounding_mode, lost_fraction); } +APFloat::opStatus +APFloat::convertFromAPInt(const APInt &Val, + bool isSigned, + roundingMode rounding_mode) +{ + unsigned int partCount = Val.getNumWords(); + APInt api = Val; + + sign = false; + if (isSigned && api.isNegative()) { + sign = true; + api = -api; + } + + return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode); +} + /* Convert a two's complement integer SRC to a floating point number, rounding according to ROUNDING_MODE. ISSIGNED is true if the integer is signed, in which case it must be sign-extended. */ @@ -1954,13 +2140,13 @@ APFloat::convertFromZeroExtendedInteger(const integerPart *parts, } APFloat::opStatus -APFloat::convertFromHexadecimalString(const char *p, +APFloat::convertFromHexadecimalString(const StringRef &s, roundingMode rounding_mode) { - lostFraction lost_fraction; + lostFraction lost_fraction = lfExactlyZero; integerPart *significand; unsigned int bitPos, partsCount; - const char *dot, *firstSignificantDigit; + StringRef::iterator dot, firstSignificantDigit; zeroSignificand(); exponent = 0; @@ -1971,52 +2157,63 @@ APFloat::convertFromHexadecimalString(const char *p, bitPos = partsCount * integerPartWidth; /* Skip leading zeroes and any (hexa)decimal point. */ - p = skipLeadingZeroesAndAnyDot(p, &dot); + StringRef::iterator begin = s.begin(); + StringRef::iterator end = s.end(); + StringRef::iterator p = skipLeadingZeroesAndAnyDot(begin, end, &dot); firstSignificantDigit = p; - for(;;) { + for(; p != end;) { integerPart hex_value; if(*p == '.') { - assert(dot == 0); + assert(dot == end && "String contains multiple dots"); dot = p++; + if (p == end) { + break; + } } hex_value = hexDigitValue(*p); if(hex_value == -1U) { - lost_fraction = lfExactlyZero; break; } p++; - /* 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, hex_value); - while(hexDigitValue(*p) != -1U) - 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; + } } } /* Hex floats require an exponent but not a hexadecimal point. */ - assert(*p == 'p' || *p == 'P'); + assert(p != end && "Hex strings require an exponent"); + assert((*p == 'p' || *p == 'P') && "Invalid character in significand"); + assert(p != begin && "Significand has no digits"); + assert((dot == end || p - begin != 1) && "Significand has no digits"); /* Ignore the exponent if we are zero. */ if(p != firstSignificantDigit) { int expAdjustment; /* Implicit hexadecimal point? */ - if(!dot) + if (dot == end) dot = p; /* Calculate the exponent adjustment implicit in the number of significant digits. */ - expAdjustment = dot - firstSignificantDigit; + expAdjustment = static_cast(dot - firstSignificantDigit); if(expAdjustment < 0) expAdjustment++; expAdjustment = expAdjustment * 4 - 1; @@ -2027,7 +2224,7 @@ APFloat::convertFromHexadecimalString(const char *p, expAdjustment -= partsCount * integerPartWidth; /* Adjust for the given exponent. */ - exponent = totalExponent(p, expAdjustment); + exponent = totalExponent(p + 1, end, expAdjustment); } return normalize(rounding_mode, lost_fraction); @@ -2070,7 +2267,8 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts, decSig.exponent += exp; lostFraction calcLostFraction; - integerPart HUerr, HUdistance, powHUerr; + integerPart HUerr, HUdistance; + unsigned int powHUerr; if (exp >= 0) { /* multiplySignificand leaves the precision-th bit set to 1. */ @@ -2086,13 +2284,13 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts, excessPrecision = calcSemantics.precision; } /* Extra half-ulp lost in reciprocal of exponent. */ - powHUerr = (powStatus == opOK && calcLostFraction == lfExactlyZero) ? 0: 2; + powHUerr = (powStatus == opOK && calcLostFraction == lfExactlyZero) ? 0:2; } /* Both multiplySignificand and divideSignificand return the result with the integer bit set. */ - assert (APInt::tcExtractBit - (decSig.significandParts(), calcSemantics.precision - 1) == 1); + assert(APInt::tcExtractBit + (decSig.significandParts(), calcSemantics.precision - 1) == 1); HUerr = HUerrBound(calcLostFraction != lfExactlyZero, sigStatus != opOK, powHUerr); @@ -2118,13 +2316,14 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts, } APFloat::opStatus -APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode) +APFloat::convertFromDecimalString(const StringRef &str, roundingMode rounding_mode) { decimalInfo D; opStatus fs; /* Scan the text. */ - interpretDecimal(p, &D); + StringRef::iterator p = str.begin(); + interpretDecimal(p, str.end(), &D); /* Handle the quick cases. First the case of no significant digits, i.e. zero, and then exponents that are obviously too large or too @@ -2143,7 +2342,7 @@ APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode) 42039/12655 < L < 28738/8651 [ numerator <= 65536 ] */ - if (*D.firstSigDigit == '0') { + if (decDigitValue(*D.firstSigDigit) >= 10U) { category = fcZero; fs = opOK; } else if ((D.normalizedExponent + 1) * 28738 @@ -2163,7 +2362,7 @@ APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode) 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 = static_cast(D.lastSigDigit - D.firstSigDigit) + 1; partCount = partCountForBits(1 + 196 * partCount / 59); decSignificand = new integerPart[partCount + 1]; partCount = 0; @@ -2179,10 +2378,14 @@ APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode) multiplier = 1; do { - if (*p == '.') + if (*p == '.') { p++; - + if (p == str.end()) { + break; + } + } decValue = decDigitValue(*p++); + assert(decValue < 10U && "Invalid character in significand"); multiplier *= 10; val = val * 10 + decValue; /* The maximum number that can be multiplied by ten with any @@ -2210,20 +2413,28 @@ APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode) } APFloat::opStatus -APFloat::convertFromString(const char *p, roundingMode rounding_mode) +APFloat::convertFromString(const StringRef &str, roundingMode rounding_mode) { assertArithmeticOK(*semantics); + assert(!str.empty() && "Invalid string length"); /* Handle a leading minus sign. */ - if(*p == '-') - sign = 1, p++; - else - sign = 0; + StringRef::iterator p = str.begin(); + size_t slen = str.size(); + sign = *p == '-' ? 1 : 0; + if(*p == '-' || *p == '+') { + p++; + slen--; + assert(slen && "String has no digits"); + } - if(p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) - return convertFromHexadecimalString(p + 2, rounding_mode); - else - return convertFromDecimalString(p, rounding_mode); + if(slen >= 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { + assert(slen - 2 && "Invalid string"); + return convertFromHexadecimalString(StringRef(p + 2, slen - 2), + rounding_mode); + } + + return convertFromDecimalString(StringRef(p, slen), rounding_mode); } /* Write out a hexadecimal representation of the floating point value @@ -2293,7 +2504,7 @@ APFloat::convertToHexString(char *dst, unsigned int hexDigits, *dst = 0; - return dst - p; + return static_cast(dst - p); } /* Does the hard work of outputting the correctly rounded hexadecimal @@ -2382,7 +2593,7 @@ APFloat::convertNormalToHexString(char *dst, unsigned int hexDigits, q--; *q = hexDigitChars[hexDigitValue (*q) + 1]; } while (*q == '0'); - assert (q >= p); + assert(q >= p); } else { /* Add trailing zeroes. */ memset (dst, '0', outputDigits); @@ -2416,7 +2627,7 @@ APFloat::getHashValue() const 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) ^ (*p)>>32; + hash ^= ((uint32_t)*p) ^ (uint32_t)((*p)>>32); return hash; } } @@ -2433,8 +2644,8 @@ APFloat::getHashValue() const APInt APFloat::convertF80LongDoubleAPFloatToAPInt() const { - assert(semantics == (const llvm::fltSemantics* const)&x87DoubleExtended); - assert (partCount()==2); + assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended); + assert(partCount()==2); uint64_t myexponent, mysignificand; @@ -2456,18 +2667,17 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const } uint64_t words[2]; - words[0] = (((uint64_t)sign & 1) << 63) | - ((myexponent & 0x7fff) << 48) | - ((mysignificand >>16) & 0xffffffffffffLL); - words[1] = mysignificand & 0xffff; + words[0] = mysignificand; + words[1] = ((uint64_t)(sign & 1) << 15) | + (myexponent & 0x7fffLL); return APInt(80, 2, words); } APInt APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const { - assert(semantics == (const llvm::fltSemantics* const)&PPCDoubleDouble); - assert (partCount()==2); + assert(semantics == (const llvm::fltSemantics*)&PPCDoubleDouble); + assert(partCount()==2); uint64_t myexponent, mysignificand, myexponent2, mysignificand2; @@ -2499,20 +2709,56 @@ APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const } uint64_t words[2]; - words[0] = (((uint64_t)sign & 1) << 63) | + words[0] = ((uint64_t)(sign & 1) << 63) | ((myexponent & 0x7ff) << 52) | (mysignificand & 0xfffffffffffffLL); - words[1] = (((uint64_t)sign2 & 1) << 63) | + words[1] = ((uint64_t)(sign2 & 1) << 63) | ((myexponent2 & 0x7ff) << 52) | (mysignificand2 & 0xfffffffffffffLL); return APInt(128, 2, words); } +APInt +APFloat::convertQuadrupleAPFloatToAPInt() const +{ + assert(semantics == (const llvm::fltSemantics*)&IEEEquad); + assert(partCount()==2); + + uint64_t myexponent, mysignificand, mysignificand2; + + if (category==fcNormal) { + myexponent = exponent+16383; //bias + mysignificand = significandParts()[0]; + mysignificand2 = significandParts()[1]; + if (myexponent==1 && !(mysignificand2 & 0x1000000000000LL)) + myexponent = 0; // denormal + } else if (category==fcZero) { + myexponent = 0; + mysignificand = mysignificand2 = 0; + } else if (category==fcInfinity) { + myexponent = 0x7fff; + mysignificand = mysignificand2 = 0; + } else { + assert(category == fcNaN && "Unknown category!"); + myexponent = 0x7fff; + mysignificand = significandParts()[0]; + mysignificand2 = significandParts()[1]; + } + + uint64_t words[2]; + words[0] = mysignificand; + words[1] = ((uint64_t)(sign & 1) << 63) | + ((myexponent & 0x7fff) << 48) | + (mysignificand2 & 0xffffffffffffLL); + + return APInt(128, 2, words); +} + APInt APFloat::convertDoubleAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&IEEEdouble); - assert (partCount()==1); + assert(partCount()==1); uint64_t myexponent, mysignificand; @@ -2533,7 +2779,7 @@ APFloat::convertDoubleAPFloatToAPInt() const mysignificand = *significandParts(); } - return APInt(64, (((((uint64_t)sign & 1) << 63) | + return APInt(64, ((((uint64_t)(sign & 1) << 63) | ((myexponent & 0x7ff) << 52) | (mysignificand & 0xfffffffffffffLL)))); } @@ -2542,14 +2788,14 @@ APInt APFloat::convertFloatAPFloatToAPInt() const { assert(semantics == (const llvm::fltSemantics*)&IEEEsingle); - assert (partCount()==1); + assert(partCount()==1); uint32_t myexponent, mysignificand; if (category==fcNormal) { myexponent = exponent+127; //bias - mysignificand = *significandParts(); - if (myexponent == 1 && !(mysignificand & 0x400000)) + mysignificand = (uint32_t)*significandParts(); + if (myexponent == 1 && !(mysignificand & 0x800000)) myexponent = 0; // denormal } else if (category==fcZero) { myexponent = 0; @@ -2560,30 +2806,65 @@ APFloat::convertFloatAPFloatToAPInt() const } else { assert(category == fcNaN && "Unknown category!"); myexponent = 0xff; - mysignificand = *significandParts(); + mysignificand = (uint32_t)*significandParts(); } return APInt(32, (((sign&1) << 31) | ((myexponent&0xff) << 23) | (mysignificand & 0x7fffff))); } +APInt +APFloat::convertHalfAPFloatToAPInt() const +{ + assert(semantics == (const llvm::fltSemantics*)&IEEEhalf); + assert(partCount()==1); + + uint32_t myexponent, mysignificand; + + if (category==fcNormal) { + myexponent = exponent+15; //bias + mysignificand = (uint32_t)*significandParts(); + if (myexponent == 1 && !(mysignificand & 0x400)) + myexponent = 0; // denormal + } else if (category==fcZero) { + myexponent = 0; + mysignificand = 0; + } else if (category==fcInfinity) { + myexponent = 0x1f; + mysignificand = 0; + } else { + assert(category == fcNaN && "Unknown category!"); + myexponent = 0x1f; + mysignificand = (uint32_t)*significandParts(); + } + + return APInt(16, (((sign&1) << 15) | ((myexponent&0x1f) << 10) | + (mysignificand & 0x3ff))); +} + // This function creates an APInt that is just a bit map of the floating // point constant as it would appear in memory. It is not a conversion, // 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* const)&IEEEsingle) + if (semantics == (const llvm::fltSemantics*)&IEEEhalf) + return convertHalfAPFloatToAPInt(); + + 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*)&IEEEquad) + return convertQuadrupleAPFloatToAPInt(); + + 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(); } @@ -2591,38 +2872,41 @@ APFloat::convertToAPInt() const float APFloat::convertToFloat() const { - assert(semantics == (const llvm::fltSemantics* const)&IEEEsingle); - APInt api = convertToAPInt(); + assert(semantics == (const llvm::fltSemantics*)&IEEEsingle && + "Float semantics are not IEEEsingle"); + APInt api = bitcastToAPInt(); return api.bitsToFloat(); } double APFloat::convertToDouble() const { - assert(semantics == (const llvm::fltSemantics* const)&IEEEdouble); - APInt api = convertToAPInt(); + assert(semantics == (const llvm::fltSemantics*)&IEEEdouble && + "Float semantics are not IEEEdouble"); + APInt api = bitcastToAPInt(); return api.bitsToDouble(); } -/// Integer bit is explicit in this format. Current Intel book does not -/// define meaning of: -/// exponent = all 1's, integer bit not set. -/// exponent = 0, integer bit set. (formerly "psuedodenormals") -/// exponent!=0 nor all 1's, integer bit not set. (formerly "unnormals") +/// Integer bit is explicit in this format. Intel hardware (387 and later) +/// does not support these bit patterns: +/// exponent = all 1's, integer bit 0, significand 0 ("pseudoinfinity") +/// exponent = all 1's, integer bit 0, significand nonzero ("pseudoNaN") +/// exponent = 0, integer bit 1 ("pseudodenormal") +/// exponent!=0 nor all 1's, integer bit 0 ("unnormal") +/// At the moment, the first two are treated as NaNs, the second two as Normal. void APFloat::initFromF80LongDoubleAPInt(const APInt &api) { assert(api.getBitWidth()==80); uint64_t i1 = api.getRawData()[0]; uint64_t i2 = api.getRawData()[1]; - uint64_t myexponent = (i1 >> 48) & 0x7fff; - uint64_t mysignificand = ((i1 << 16) & 0xffffffffffff0000ULL) | - (i2 & 0xffff); + uint64_t myexponent = (i2 & 0x7fff); + uint64_t mysignificand = i1; initialize(&APFloat::x87DoubleExtended); assert(partCount()==2); - sign = i1>>63; + sign = static_cast(i2>>15); if (myexponent==0 && mysignificand==0) { // exponent, significand meaningless category = fcZero; @@ -2658,8 +2942,8 @@ APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) initialize(&APFloat::PPCDoubleDouble); assert(partCount()==2); - sign = i1>>63; - sign2 = i2>>63; + sign = static_cast(i1>>63); + sign2 = static_cast(i2>>63); if (myexponent==0 && mysignificand==0) { // exponent, significand meaningless // exponent2 and significand2 are required to be 0; we don't check @@ -2694,6 +2978,46 @@ APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) } } +void +APFloat::initFromQuadrupleAPInt(const APInt &api) +{ + assert(api.getBitWidth()==128); + uint64_t i1 = api.getRawData()[0]; + uint64_t i2 = api.getRawData()[1]; + uint64_t myexponent = (i2 >> 48) & 0x7fff; + uint64_t mysignificand = i1; + uint64_t mysignificand2 = i2 & 0xffffffffffffLL; + + initialize(&APFloat::IEEEquad); + assert(partCount()==2); + + sign = static_cast(i2>>63); + if (myexponent==0 && + (mysignificand==0 && mysignificand2==0)) { + // exponent, significand meaningless + category = fcZero; + } else if (myexponent==0x7fff && + (mysignificand==0 && mysignificand2==0)) { + // exponent, significand meaningless + category = fcInfinity; + } else if (myexponent==0x7fff && + (mysignificand!=0 || mysignificand2 !=0)) { + // exponent meaningless + category = fcNaN; + significandParts()[0] = mysignificand; + significandParts()[1] = mysignificand2; + } else { + category = fcNormal; + exponent = myexponent - 16383; + significandParts()[0] = mysignificand; + significandParts()[1] = mysignificand2; + if (myexponent==0) // denormal + exponent = -16382; + else + significandParts()[1] |= 0x1000000000000LL; // integer bit + } +} + void APFloat::initFromDoubleAPInt(const APInt &api) { @@ -2705,7 +3029,7 @@ APFloat::initFromDoubleAPInt(const APInt &api) initialize(&APFloat::IEEEdouble); assert(partCount()==1); - sign = i>>63; + sign = static_cast(i>>63); if (myexponent==0 && mysignificand==0) { // exponent, significand meaningless category = fcZero; @@ -2760,6 +3084,39 @@ APFloat::initFromFloatAPInt(const APInt & api) } } +void +APFloat::initFromHalfAPInt(const APInt & api) +{ + assert(api.getBitWidth()==16); + uint32_t i = (uint32_t)*api.getRawData(); + uint32_t myexponent = (i >> 10) & 0x1f; + uint32_t mysignificand = i & 0x3ff; + + initialize(&APFloat::IEEEhalf); + assert(partCount()==1); + + sign = i >> 15; + if (myexponent==0 && mysignificand==0) { + // exponent, significand meaningless + category = fcZero; + } else if (myexponent==0x1f && mysignificand==0) { + // exponent, significand meaningless + category = fcInfinity; + } else if (myexponent==0x1f && mysignificand!=0) { + // sign, exponent, significand meaningless + category = fcNaN; + *significandParts() = mysignificand; + } else { + category = fcNormal; + exponent = myexponent - 15; //bias + *significandParts() = mysignificand; + if (myexponent==0) // denormal + exponent = -14; + else + *significandParts() |= 0x400; // integer bit + } +} + /// Treat api as containing the bits of a floating point number. Currently /// we infer the floating point type from the size of the APInt. The /// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful @@ -2767,16 +3124,19 @@ APFloat::initFromFloatAPInt(const APInt & api) void APFloat::initFromAPInt(const APInt& api, bool isIEEE) { - if (api.getBitWidth() == 32) + if (api.getBitWidth() == 16) + return initFromHalfAPInt(api); + else if (api.getBitWidth() == 32) return initFromFloatAPInt(api); else if (api.getBitWidth()==64) return initFromDoubleAPInt(api); else if (api.getBitWidth()==80) return initFromF80LongDoubleAPInt(api); - else if (api.getBitWidth()==128 && !isIEEE) - return initFromPPCDoubleDoubleAPInt(api); + else if (api.getBitWidth()==128) + return (isIEEE ? + initFromQuadrupleAPInt(api) : initFromPPCDoubleDoubleAPInt(api)); else - assert(0); + llvm_unreachable(0); } APFloat::APFloat(const APInt& api, bool isIEEE)