/* 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
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. */
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. */
- static int
+ int
readExponent(const char *p)
{
bool isNegative;
/* 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;
dddd.dddd[eE][+-]ddd
where the decimal point and exponent are optional, fill out the
- structure D. If the value is zero, V->firstSigDigit
- points to a zero, and the return exponent is zero. */
+ 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 zero, and the
+ return exponent is zero.
+ */
struct decimalInfo {
const char *firstSigDigit;
const char *lastSigDigit;
int exponent;
+ int normalizedExponent;
};
void
D->firstSigDigit = p;
D->exponent = 0;
+ D->normalizedExponent = 0;
for (;;) {
if (*p == '.') {
while (*p == '0');
while (*p == '.');
- /* Adjust the specified exponent for any decimal point. */
+ /* 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;
/* 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)
{
static integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125,
/* 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)
{
}
/* Write out an unsigned decimal integer. */
- static char *
+ char *
writeUnsignedDecimal (char *dst, unsigned int n)
{
char buff[40], *p;
}
/* Write out a signed decimal integer. */
- static char *
+ char *
writeSignedDecimal (char *dst, int value)
{
if (value < 0) {
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)
{
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();
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);
}
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;
}
/* 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;
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):
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):
{
opStatus fs;
+ assertArithmeticOK(*semantics);
+
fs = addOrSubtractSpecials(rhs, subtract);
/* This return code means it was not a simple case. */
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);
}
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);
}
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);
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);
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;
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;
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)) {
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();
/* 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.
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);
+ src = significandParts();
- bits = (int) semantics->precision - 1 - exponent;
-
- 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;
+ }
+ }
+
+ /* 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. */
}
- tmp.shiftSignificandLeft(-bits);
+ } 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;
+
+ 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;
+ }
+
+ APInt::tcNegate (parts, dstPartsCount);
+ } else {
+ if (omsb >= width + !isSigned)
+ return opInvalidOp;
+ }
+
+ if (lost_fraction == lfExactlyZero)
+ return opOK;
+ else
+ return opInexact;
+}
- msb = tmp.significandMSB();
+/* 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;
- /* Negative numbers cannot be represented as unsigned. */
- if(!isSigned && tmp.sign && msb != -1U)
- return opInvalidOp;
+ fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode);
- /* 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 (fs == opInvalidOp) {
+ unsigned int bits, dstPartsCount;
- if(isSigned && msb + 1 == width
- && (!tmp.sign || tmp.significandLSB() != msb))
- return opInvalidOp;
+ dstPartsCount = partCountForBits(width);
- APInt::tcAssign(parts, tmp.significandParts(), partsCount);
+ if (category == fcNaN)
+ bits = 0;
+ else if (sign)
+ bits = isSigned;
+ else
+ bits = width - isSigned;
- if(tmp.sign)
- APInt::tcNegate(parts, partsCount);
+ APInt::tcSetLeastSignificantBits(parts, dstPartsCount, bits);
+ if (sign && isSigned)
+ APInt::tcShiftLeft(parts, dstPartsCount, width - 1);
+ }
- if(lost_fraction == lfExactlyZero)
- return opOK;
- else
- return opInexact;
+ return fs;
}
/* Convert an unsigned integer SRC to a floating point number,
integerPart *dst;
lostFraction lost_fraction;
+ assertArithmeticOK(*semantics);
category = fcNormal;
omsb = APInt::tcMSB(src, srcCount) + 1;
dst = significandParts();
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;
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);
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;
roundingMode rounding_mode)
{
unsigned int parts, pow5PartCount;
- fltSemantics calcSemantics = { 32767, -32767, 0 };
+ fltSemantics calcSemantics = { 32767, -32767, 0, true };
integerPart pow5Parts[maxPowerOfFiveParts];
bool isNearest;
/* Scan the text. */
interpretDecimal(p, &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
+ small. Writing L for log 10 / log 2, a number d.ddddd*10^exp
+ definitely overflows if
+
+ (exp - 1) * L >= maxExponent
+
+ and definitely underflows to zero where
+
+ (exp + 1) * L <= minExponent - precision
+
+ With integer arithmetic the tightest bounds for L are
+
+ 93/28 < L < 196/59 [ numerator <= 256 ]
+ 42039/12655 < L < 28738/8651 [ numerator <= 65536 ]
+ */
+
if (*D.firstSigDigit == '0') {
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 {
integerPart *decSignificand;
unsigned int partCount;
/* A tight upper bound on number of bits required to hold an
- N-digit decimal integer is N * 256 / 77. Allocate enough space
+ 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 + 256 * partCount / 77);
+ partCount = partCountForBits(1 + 196 * partCount / 59);
decSignificand = new integerPart[partCount + 1];
partCount = 0;
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++;
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++ = '-';