Whether arithmetic is supported is a property of the semantics. Make it

so, and clean up the checks by putting them in an inline function.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@42965 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Neil Booth
2007-10-14 10:29:28 +00:00
parent 1870f29c6c
commit caf19d79e5

View File

@@ -40,18 +40,21 @@ namespace llvm {
/* Number of bits in the significand. This includes the integer /* Number of bits in the significand. This includes the integer
bit. */ bit. */
unsigned int precision; unsigned int precision;
/* True if arithmetic is supported. */
unsigned int arithmeticOK;
}; };
const fltSemantics APFloat::IEEEsingle = { 127, -126, 24 }; const fltSemantics APFloat::IEEEsingle = { 127, -126, 24, true };
const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53 }; const fltSemantics APFloat::IEEEdouble = { 1023, -1022, 53, true };
const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113 }; const fltSemantics APFloat::IEEEquad = { 16383, -16382, 113, true };
const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64 }; const fltSemantics APFloat::x87DoubleExtended = { 16383, -16382, 64, true };
const fltSemantics APFloat::Bogus = { 0, 0, 0 }; const fltSemantics APFloat::Bogus = { 0, 0, 0, true };
// The PowerPC format consists of two doubles. It does not map cleanly // The PowerPC format consists of two doubles. It does not map cleanly
// onto the usual format above. For now only storage of constants of // onto the usual format above. For now only storage of constants of
// this type is supported, no arithmetic. // 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 /* A tight upper bound on number of parts required to hold the value
pow(5, power) is pow(5, power) is
@@ -107,6 +110,12 @@ namespace {
return -1U; 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 /* Return the value of a decimal exponent of the form
[+-]ddddddd. [+-]ddddddd.
@@ -623,8 +632,7 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value)
{ {
assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && assertArithmeticOK(ourSemantics);
"Compile-time arithmetic on PPC long double not supported yet");
initialize(&ourSemantics); initialize(&ourSemantics);
sign = 0; sign = 0;
zeroSignificand(); zeroSignificand();
@@ -636,8 +644,7 @@ APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value)
APFloat::APFloat(const fltSemantics &ourSemantics, APFloat::APFloat(const fltSemantics &ourSemantics,
fltCategory ourCategory, bool negative) fltCategory ourCategory, bool negative)
{ {
assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && assertArithmeticOK(ourSemantics);
"Compile-time arithmetic on PPC long double not supported yet");
initialize(&ourSemantics); initialize(&ourSemantics);
category = ourCategory; category = ourCategory;
sign = negative; sign = negative;
@@ -647,8 +654,7 @@ APFloat::APFloat(const fltSemantics &ourSemantics,
APFloat::APFloat(const fltSemantics &ourSemantics, const char *text) APFloat::APFloat(const fltSemantics &ourSemantics, const char *text)
{ {
assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && assertArithmeticOK(ourSemantics);
"Compile-time arithmetic on PPC long double not supported yet");
initialize(&ourSemantics); initialize(&ourSemantics);
convertFromString(text, rmNearestTiesToEven); convertFromString(text, rmNearestTiesToEven);
} }
@@ -1405,6 +1411,8 @@ APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode,
{ {
opStatus fs; opStatus fs;
assertArithmeticOK(*semantics);
fs = addOrSubtractSpecials(rhs, subtract); fs = addOrSubtractSpecials(rhs, subtract);
/* This return code means it was not a simple case. */ /* This return code means it was not a simple case. */
@@ -1433,8 +1441,6 @@ APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode,
APFloat::opStatus APFloat::opStatus
APFloat::add(const APFloat &rhs, roundingMode rounding_mode) 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); return addOrSubtract(rhs, rounding_mode, false);
} }
@@ -1442,8 +1448,6 @@ APFloat::add(const APFloat &rhs, roundingMode rounding_mode)
APFloat::opStatus APFloat::opStatus
APFloat::subtract(const APFloat &rhs, roundingMode rounding_mode) 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); return addOrSubtract(rhs, rounding_mode, true);
} }
@@ -1451,10 +1455,9 @@ APFloat::subtract(const APFloat &rhs, roundingMode rounding_mode)
APFloat::opStatus APFloat::opStatus
APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode) 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; opStatus fs;
assertArithmeticOK(*semantics);
sign ^= rhs.sign; sign ^= rhs.sign;
fs = multiplySpecials(rhs); fs = multiplySpecials(rhs);
@@ -1472,10 +1475,9 @@ APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode)
APFloat::opStatus APFloat::opStatus
APFloat::divide(const APFloat &rhs, roundingMode rounding_mode) 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; opStatus fs;
assertArithmeticOK(*semantics);
sign ^= rhs.sign; sign ^= rhs.sign;
fs = divideSpecials(rhs); fs = divideSpecials(rhs);
@@ -1493,11 +1495,11 @@ APFloat::divide(const APFloat &rhs, roundingMode rounding_mode)
APFloat::opStatus APFloat::opStatus
APFloat::mod(const APFloat &rhs, roundingMode rounding_mode) 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; opStatus fs;
APFloat V = *this; APFloat V = *this;
unsigned int origSign = sign; unsigned int origSign = sign;
assertArithmeticOK(*semantics);
fs = V.divide(rhs, rmNearestTiesToEven); fs = V.divide(rhs, rmNearestTiesToEven);
if (fs == opDivByZero) if (fs == opDivByZero)
return fs; return fs;
@@ -1531,10 +1533,10 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
const APFloat &addend, const APFloat &addend,
roundingMode rounding_mode) roundingMode rounding_mode)
{ {
assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
"Compile-time arithmetic on PPC long double not supported yet");
opStatus fs; opStatus fs;
assertArithmeticOK(*semantics);
/* Post-multiplication sign, before addition. */ /* Post-multiplication sign, before addition. */
sign ^= multiplicand.sign; sign ^= multiplicand.sign;
@@ -1576,10 +1578,9 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
APFloat::cmpResult APFloat::cmpResult
APFloat::compare(const APFloat &rhs) const 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; cmpResult result;
assertArithmeticOK(*semantics);
assert(semantics == rhs.semantics); assert(semantics == rhs.semantics);
switch(convolve(category, rhs.category)) { switch(convolve(category, rhs.category)) {
@@ -1651,12 +1652,11 @@ APFloat::opStatus
APFloat::convert(const fltSemantics &toSemantics, APFloat::convert(const fltSemantics &toSemantics,
roundingMode rounding_mode) roundingMode rounding_mode)
{ {
assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
"Compile-time arithmetic on PPC long double not supported yet");
lostFraction lostFraction; lostFraction lostFraction;
unsigned int newPartCount, oldPartCount; unsigned int newPartCount, oldPartCount;
opStatus fs; opStatus fs;
assertArithmeticOK(*semantics);
lostFraction = lfExactlyZero; lostFraction = lfExactlyZero;
newPartCount = partCountForBits(toSemantics.precision + 1); newPartCount = partCountForBits(toSemantics.precision + 1);
oldPartCount = partCount(); oldPartCount = partCount();
@@ -1730,12 +1730,11 @@ APFloat::convertToInteger(integerPart *parts, unsigned int width,
bool isSigned, bool isSigned,
roundingMode rounding_mode) const roundingMode rounding_mode) const
{ {
assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
"Compile-time arithmetic on PPC long double not supported yet");
lostFraction lost_fraction; lostFraction lost_fraction;
unsigned int msb, partsCount; unsigned int msb, partsCount;
int bits; int bits;
assertArithmeticOK(*semantics);
partsCount = partCountForBits(width); partsCount = partCountForBits(width);
/* Handle the three special cases first. We produce /* Handle the three special cases first. We produce
@@ -1830,6 +1829,7 @@ APFloat::convertFromUnsignedParts(const integerPart *src,
integerPart *dst; integerPart *dst;
lostFraction lost_fraction; lostFraction lost_fraction;
assertArithmeticOK(*semantics);
category = fcNormal; category = fcNormal;
omsb = APInt::tcMSB(src, srcCount) + 1; omsb = APInt::tcMSB(src, srcCount) + 1;
dst = significandParts(); dst = significandParts();
@@ -1861,10 +1861,9 @@ APFloat::convertFromSignExtendedInteger(const integerPart *src,
bool isSigned, bool isSigned,
roundingMode rounding_mode) roundingMode rounding_mode)
{ {
assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
"Compile-time arithmetic on PPC long double not supported yet");
opStatus status; opStatus status;
assertArithmeticOK(*semantics);
if (isSigned if (isSigned
&& APInt::tcExtractBit(src, srcCount * integerPartWidth - 1)) { && APInt::tcExtractBit(src, srcCount * integerPartWidth - 1)) {
integerPart *copy; integerPart *copy;
@@ -1890,8 +1889,6 @@ APFloat::convertFromZeroExtendedInteger(const integerPart *parts,
unsigned int width, bool isSigned, unsigned int width, bool isSigned,
roundingMode rounding_mode) 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); unsigned int partCount = partCountForBits(width);
APInt api = APInt(width, partCount, parts); APInt api = APInt(width, partCount, parts);
@@ -1908,8 +1905,6 @@ APFloat::opStatus
APFloat::convertFromHexadecimalString(const char *p, APFloat::convertFromHexadecimalString(const char *p,
roundingMode rounding_mode) roundingMode rounding_mode)
{ {
assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble &&
"Compile-time arithmetic on PPC long double not supported yet");
lostFraction lost_fraction; lostFraction lost_fraction;
integerPart *significand; integerPart *significand;
unsigned int bitPos, partsCount; unsigned int bitPos, partsCount;
@@ -1992,7 +1987,7 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts,
roundingMode rounding_mode) roundingMode rounding_mode)
{ {
unsigned int parts, pow5PartCount; unsigned int parts, pow5PartCount;
fltSemantics calcSemantics = { 32767, -32767, 0 }; fltSemantics calcSemantics = { 32767, -32767, 0, true };
integerPart pow5Parts[maxPowerOfFiveParts]; integerPart pow5Parts[maxPowerOfFiveParts];
bool isNearest; bool isNearest;
@@ -2139,8 +2134,8 @@ APFloat::convertFromDecimalString(const char *p, roundingMode rounding_mode)
APFloat::opStatus APFloat::opStatus
APFloat::convertFromString(const char *p, roundingMode rounding_mode) APFloat::convertFromString(const char *p, roundingMode rounding_mode)
{ {
assert(semantics != (const llvm::fltSemantics* const)&PPCDoubleDouble && assertArithmeticOK(*semantics);
"Compile-time arithmetic on PPC long double not supported yet");
/* Handle a leading minus sign. */ /* Handle a leading minus sign. */
if(*p == '-') if(*p == '-')
sign = 1, p++; sign = 1, p++;
@@ -2181,10 +2176,10 @@ unsigned int
APFloat::convertToHexString(char *dst, unsigned int hexDigits, APFloat::convertToHexString(char *dst, unsigned int hexDigits,
bool upperCase, roundingMode rounding_mode) const 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; char *p;
assertArithmeticOK(*semantics);
p = dst; p = dst;
if (sign) if (sign)
*dst++ = '-'; *dst++ = '-';