/* 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
return ((bits) + integerPartWidth - 1) / integerPartWidth;
}
- unsigned int
- digitValue(unsigned int c)
+ /* Returns 0U-9U. Return values >= 10U are not digits. */
+ inline unsigned int
+ decDigitValue(unsigned int c)
{
- unsigned int r;
-
- r = c - '0';
- if(r <= 9)
- return r;
-
- return -1U;
+ return c - '0';
}
unsigned int
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
+ readExponent(const char *p)
+ {
+ bool isNegative;
+ unsigned int absExponent;
+ const unsigned int overlargeExponent = 24000; /* FIXME. */
+
+ isNegative = (*p == '-');
+ if (*p == '-' || *p == '+')
+ p++;
+
+ absExponent = decDigitValue(*p++);
+ assert (absExponent < 10U);
+
+ for (;;) {
+ unsigned int value;
+
+ value = decDigitValue(*p);
+ if (value >= 10U)
+ break;
+
+ p++;
+ value += absExponent * 10;
+ if (absExponent >= overlargeExponent) {
+ absExponent = overlargeExponent;
+ break;
+ }
+ absExponent = value;
+ }
+
+ if (isNegative)
+ return -(int) absExponent;
+ else
+ return (int) absExponent;
+ }
+
/* This is ugly and needs cleaning up, but I don't immediately see
how whilst remaining safe. */
static int
for(;;) {
unsigned int value;
- value = digitValue(*p);
- if(value == -1U)
+ value = decDigitValue(*p);
+ if(value >= 10U)
break;
p++;
return p;
}
+ /* Given a normal decimal floating point number of the form
+
+ dddd.dddd[eE][+-]ddd
+
+ where the decimal point and exponent are optional, fill out the
+ structure D. 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;
+ };
+
+ void
+ interpretDecimal(const char *p, decimalInfo *D)
+ {
+ const char *dot;
+
+ p = skipLeadingZeroesAndAnyDot (p, &dot);
+
+ D->firstSigDigit = p;
+ D->exponent = 0;
+
+ for (;;) {
+ if (*p == '.') {
+ assert(dot == 0);
+ dot = p++;
+ }
+ if (decDigitValue(*p) >= 10U)
+ break;
+ p++;
+ }
+
+ /* If number is all zerooes accept any exponent. */
+ if (p != D->firstSigDigit) {
+ if (*p == 'e' || *p == 'E')
+ D->exponent = readExponent(p + 1);
+
+ /* Implied decimal point? */
+ if (!dot)
+ dot = p;
+
+ /* Drop insignificant trailing zeroes. */
+ do
+ do
+ p--;
+ while (*p == '0');
+ while (*p == '.');
+
+ /* Adjust the specified exponent for any decimal point. */
+ D->exponent += (dot - p) - (dot > p);
+ }
+
+ D->lastSigDigit = p;
+ }
+
/* Return the trailing fraction of a hexadecimal number.
DIGITVALUE is the first hex digit of the fraction, P points to
the next digit. */
static unsigned int
powerOf5(integerPart *dst, unsigned int power)
{
- /* A tight upper bound on number of parts required to hold the
- value pow(5, power) is
-
- power * 65536 / (28224 * integerPartWidth) + 1
-
- However, whilst the result may require only N parts, because we
- are multiplying two values to get it, the multiplication may
- require N + 1 parts with the excess part being zero (consider
- the trivial case of 1 * 1, the multiplier requires two parts to
- hold the single-part result). So we add two to guarantee
- enough space whilst multiplying. */
static integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125,
15625, 78125 };
static integerPart pow5s[maxPowerOfFiveParts * 2 + 5] = { 78125 * 5 };
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);
}
/* 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());
+ makeNaN();
return opInvalidOp;
}
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();
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;
+ assertArithmeticOK(*semantics);
partsCount = partCountForBits(width);
/* Handle the three special cases first. We produce
if(bits > 0) {
lost_fraction = tmp.shiftSignificandRight(bits);
} else {
- if (-bits >= semantics->precision) {
+ if ((unsigned) -bits >= semantics->precision) {
// Unrepresentably large.
if (!sign && isSigned)
APInt::tcSetLeastSignificantBits(parts, partsCount, width-1);
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;
excessPrecision = calcSemantics.precision;
}
/* Extra half-ulp lost in reciprocal of exponent. */
- powHUerr = 1 + powStatus != opOK;
+ powHUerr = (powStatus == opOK && calcLostFraction == lfExactlyZero) ? 0: 2;
}
/* Both multiplySignificand and divideSignificand return the
APFloat::opStatus
APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode)
{
- const char *dot, *firstSignificantDigit;
- integerPart val, maxVal, decValue;
+ decimalInfo D;
opStatus fs;
- /* Skip leading zeroes and any decimal point. */
- p = skipLeadingZeroesAndAnyDot(p, &dot);
- firstSignificantDigit = p;
-
- /* The maximum number that can be multiplied by ten with any digit
- added without overflowing an integerPart. */
- maxVal = (~ (integerPart) 0 - 9) / 10;
-
- val = 0;
- while (val <= maxVal) {
- if (*p == '.') {
- assert(dot == 0);
- dot = p++;
- }
-
- decValue = digitValue(*p);
- if (decValue == -1U)
- break;
- p++;
- val = val * 10 + decValue;
- }
-
- integerPart *decSignificand;
- unsigned int partCount, maxPartCount;
-
- partCount = 0;
- maxPartCount = 4;
- decSignificand = new integerPart[maxPartCount];
- decSignificand[partCount++] = val;
+ /* Scan the text. */
+ interpretDecimal(p, &D);
- /* Now continue to do single-part arithmetic for as long as we can.
- Then do a part multiplication, and repeat. */
- while (decValue != -1U) {
- integerPart multiplier;
-
- val = 0;
- multiplier = 1;
-
- while (multiplier <= maxVal) {
- if (*p == '.') {
- assert(dot == 0);
- dot = p++;
- }
-
- decValue = digitValue(*p);
- if (decValue == -1U)
- break;
- p++;
- multiplier *= 10;
- val = val * 10 + decValue;
- }
-
- if (partCount == maxPartCount) {
- integerPart *newDecSignificand;
- newDecSignificand = new integerPart[maxPartCount = partCount * 2];
- APInt::tcAssign(newDecSignificand, decSignificand, partCount);
- delete [] decSignificand;
- decSignificand = newDecSignificand;
- }
-
- APInt::tcMultiplyPart(decSignificand, decSignificand, multiplier, val,
- partCount, partCount + 1, false);
-
- /* If we used another part (likely), increase the count. */
- if (decSignificand[partCount] != 0)
- partCount++;
- }
-
- /* Now decSignificand contains the supplied significand ignoring the
- decimal point. Figure out our effective exponent, which is the
- specified exponent adjusted for any decimal point. */
-
- if (p == firstSignificantDigit) {
- /* Ignore the exponent if we are zero - we cannot overflow. */
+ if (*D.firstSigDigit == '0') {
category = fcZero;
fs = opOK;
} else {
- int decimalExponent;
+ integerPart *decSignificand;
+ unsigned int partCount;
+
+ /* A tight upper bound on number of bits required to hold an
+ N-digit decimal integer is N * 256 / 77. 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);
+ decSignificand = new integerPart[partCount + 1];
+ partCount = 0;
+
+ /* Convert to binary efficiently - we do almost all multiplication
+ in an integerPart. When this would overflow do we do a single
+ bignum multiplication, and then revert again to multiplication
+ in an integerPart. */
+ do {
+ integerPart decValue, val, multiplier;
- if (dot)
- decimalExponent = dot + 1 - p;
- else
- decimalExponent = 0;
+ val = 0;
+ multiplier = 1;
+
+ do {
+ if (*p == '.')
+ p++;
- /* Add the given exponent. */
- if (*p == 'e' || *p == 'E')
- decimalExponent = totalExponent(p, decimalExponent);
+ decValue = decDigitValue(*p++);
+ multiplier *= 10;
+ val = val * 10 + decValue;
+ /* The maximum number that can be multiplied by ten with any
+ digit added without overflowing an integerPart. */
+ } while (p <= D.lastSigDigit && multiplier <= (~ (integerPart) 0 - 9) / 10);
+
+ /* Multiply out the current part. */
+ APInt::tcMultiplyPart(decSignificand, decSignificand, multiplier, val,
+ partCount, partCount + 1, false);
+
+ /* If we used another part (likely but not guaranteed), increase
+ the count. */
+ if (decSignificand[partCount])
+ partCount++;
+ } while (p <= D.lastSigDigit);
category = fcNormal;
fs = roundSignificandWithExponent(decSignificand, partCount,
- decimalExponent, rounding_mode);
- }
+ D.exponent, rounding_mode);
- delete [] decSignificand;
+ delete [] decSignificand;
+ }
return fs;
}
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++ = '-';