summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Support/APFloat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Support/APFloat.cpp')
-rw-r--r--contrib/llvm/lib/Support/APFloat.cpp230
1 files changed, 85 insertions, 145 deletions
diff --git a/contrib/llvm/lib/Support/APFloat.cpp b/contrib/llvm/lib/Support/APFloat.cpp
index ed261a4..7e8b4a3 100644
--- a/contrib/llvm/lib/Support/APFloat.cpp
+++ b/contrib/llvm/lib/Support/APFloat.cpp
@@ -46,22 +46,27 @@ namespace llvm {
/* 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::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 };
- 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, false };
+ const fltSemantics APFloat::IEEEhalf = { 15, -14, 11 };
+ 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 };
+
+ /* The PowerPC format consists of two doubles. It does not map cleanly
+ onto the usual format above. It is approximated using twice the
+ mantissa bits. Note that for exponents near the double minimum,
+ we no longer can represent the full 106 mantissa bits, so those
+ will be treated as denormal numbers.
+
+ FIXME: While this approximation is equivalent to what GCC uses for
+ compile-time arithmetic on PPC double-double numbers, it is not able
+ to represent all possible values held by a PPC double-double number,
+ for example: (long double) 1.0 + (long double) 0x1p-106
+ Should this be replaced by a full emulation of PPC double-double? */
+ const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022 + 53, 53 + 53 };
/* A tight upper bound on number of parts required to hold the value
pow(5, power) is
@@ -116,12 +121,6 @@ hexDigitValue(unsigned int c)
return -1U;
}
-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.
@@ -196,8 +195,10 @@ totalExponent(StringRef::iterator p, StringRef::iterator end,
assert(value < 10U && "Invalid character in exponent");
unsignedExponent = unsignedExponent * 10 + value;
- if (unsignedExponent > 32767)
+ if (unsignedExponent > 32767) {
overflow = true;
+ break;
+ }
}
if (exponentAdjustment > 32767 || exponentAdjustment < -32768)
@@ -610,8 +611,6 @@ APFloat::assign(const APFloat &rhs)
sign = rhs.sign;
category = rhs.category;
exponent = rhs.exponent;
- sign2 = rhs.sign2;
- exponent2 = rhs.exponent2;
if (category == fcNormal || category == fcNaN)
copySignificand(rhs);
}
@@ -705,16 +704,10 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
category != rhs.category ||
sign != rhs.sign)
return false;
- 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*)&PPCDoubleDouble &&
- exponent2!=rhs.exponent2)
- return false;
else {
int i= partCount();
const integerPart* p=significandParts();
@@ -727,9 +720,7 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
}
}
-APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value)
- : exponent2(0), sign2(0) {
- assertArithmeticOK(ourSemantics);
+APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) {
initialize(&ourSemantics);
sign = 0;
zeroSignificand();
@@ -738,24 +729,19 @@ APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value)
normalize(rmNearestTiesToEven, lfExactlyZero);
}
-APFloat::APFloat(const fltSemantics &ourSemantics) : exponent2(0), sign2(0) {
- assertArithmeticOK(ourSemantics);
+APFloat::APFloat(const fltSemantics &ourSemantics) {
initialize(&ourSemantics);
category = fcZero;
sign = false;
}
-APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag)
- : exponent2(0), sign2(0) {
- assertArithmeticOK(ourSemantics);
+APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) {
// Allocates storage if necessary but does not initialize it.
initialize(&ourSemantics);
}
APFloat::APFloat(const fltSemantics &ourSemantics,
- fltCategory ourCategory, bool negative)
- : exponent2(0), sign2(0) {
- assertArithmeticOK(ourSemantics);
+ fltCategory ourCategory, bool negative) {
initialize(&ourSemantics);
category = ourCategory;
sign = negative;
@@ -765,14 +751,12 @@ APFloat::APFloat(const fltSemantics &ourSemantics,
makeNaN();
}
-APFloat::APFloat(const fltSemantics &ourSemantics, StringRef text)
- : exponent2(0), sign2(0) {
- assertArithmeticOK(ourSemantics);
+APFloat::APFloat(const fltSemantics &ourSemantics, StringRef text) {
initialize(&ourSemantics);
convertFromString(text, rmNearestTiesToEven);
}
-APFloat::APFloat(const APFloat &rhs) : exponent2(0), sign2(0) {
+APFloat::APFloat(const APFloat &rhs) {
initialize(rhs.semantics);
assign(rhs);
}
@@ -1559,8 +1543,6 @@ APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode,
{
opStatus fs;
- assertArithmeticOK(*semantics);
-
fs = addOrSubtractSpecials(rhs, subtract);
/* This return code means it was not a simple case. */
@@ -1605,7 +1587,6 @@ APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode)
{
opStatus fs;
- assertArithmeticOK(*semantics);
sign ^= rhs.sign;
fs = multiplySpecials(rhs);
@@ -1625,7 +1606,6 @@ APFloat::divide(const APFloat &rhs, roundingMode rounding_mode)
{
opStatus fs;
- assertArithmeticOK(*semantics);
sign ^= rhs.sign;
fs = divideSpecials(rhs);
@@ -1647,7 +1627,6 @@ APFloat::remainder(const APFloat &rhs)
APFloat V = *this;
unsigned int origSign = sign;
- assertArithmeticOK(*semantics);
fs = V.divide(rhs, rmNearestTiesToEven);
if (fs == opDivByZero)
return fs;
@@ -1682,7 +1661,6 @@ APFloat::opStatus
APFloat::mod(const APFloat &rhs, roundingMode rounding_mode)
{
opStatus fs;
- assertArithmeticOK(*semantics);
fs = modSpecials(rhs);
if (category == fcNormal && rhs.category == fcNormal) {
@@ -1726,8 +1704,6 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
{
opStatus fs;
- assertArithmeticOK(*semantics);
-
/* Post-multiplication sign, before addition. */
sign ^= multiplicand.sign;
@@ -1768,12 +1744,11 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
/* Rounding-mode corrrect round to integral value. */
APFloat::opStatus APFloat::roundToIntegral(roundingMode rounding_mode) {
opStatus fs;
- assertArithmeticOK(*semantics);
// If the exponent is large enough, we know that this value is already
// integral, and the arithmetic below would potentially cause it to saturate
// to +/-Inf. Bail out early instead.
- if (exponent+1 >= (int)semanticsPrecision(*semantics))
+ if (category == fcNormal && exponent+1 >= (int)semanticsPrecision(*semantics))
return opOK;
// The algorithm here is quite simple: we add 2^(p-1), where p is the
@@ -1815,7 +1790,6 @@ APFloat::compare(const APFloat &rhs) const
{
cmpResult result;
- assertArithmeticOK(*semantics);
assert(semantics == rhs.semantics);
switch (convolve(category, rhs.category)) {
@@ -1900,8 +1874,6 @@ APFloat::convert(const fltSemantics &toSemantics,
int shift;
const fltSemantics &fromSemantics = *semantics;
- assertArithmeticOK(fromSemantics);
- assertArithmeticOK(toSemantics);
lostFraction = lfExactlyZero;
newPartCount = partCountForBits(toSemantics.precision + 1);
oldPartCount = partCount();
@@ -1986,8 +1958,6 @@ APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width,
const integerPart *src;
unsigned int dstPartsCount, truncatedBits;
- assertArithmeticOK(*semantics);
-
*isExact = false;
/* Handle the three special cases first. */
@@ -2149,7 +2119,6 @@ APFloat::convertFromUnsignedParts(const integerPart *src,
integerPart *dst;
lostFraction lost_fraction;
- assertArithmeticOK(*semantics);
category = fcNormal;
omsb = APInt::tcMSB(src, srcCount) + 1;
dst = significandParts();
@@ -2200,7 +2169,6 @@ APFloat::convertFromSignExtendedInteger(const integerPart *src,
{
opStatus status;
- assertArithmeticOK(*semantics);
if (isSigned &&
APInt::tcExtractBit(src, srcCount * integerPartWidth - 1)) {
integerPart *copy;
@@ -2334,7 +2302,7 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts,
roundingMode rounding_mode)
{
unsigned int parts, pow5PartCount;
- fltSemantics calcSemantics = { 32767, -32767, 0, true };
+ fltSemantics calcSemantics = { 32767, -32767, 0 };
integerPart pow5Parts[maxPowerOfFiveParts];
bool isNearest;
@@ -2526,7 +2494,6 @@ APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode)
APFloat::opStatus
APFloat::convertFromString(StringRef str, roundingMode rounding_mode)
{
- assertArithmeticOK(*semantics);
assert(!str.empty() && "Invalid string length");
/* Handle a leading minus sign. */
@@ -2578,8 +2545,6 @@ APFloat::convertToHexString(char *dst, unsigned int hexDigits,
{
char *p;
- assertArithmeticOK(*semantics);
-
p = dst;
if (sign)
*dst++ = '-';
@@ -2788,42 +2753,46 @@ APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const
assert(semantics == (const llvm::fltSemantics*)&PPCDoubleDouble);
assert(partCount()==2);
- uint64_t myexponent, mysignificand, myexponent2, mysignificand2;
-
- if (category==fcNormal) {
- myexponent = exponent + 1023; //bias
- myexponent2 = exponent2 + 1023;
- mysignificand = significandParts()[0];
- mysignificand2 = significandParts()[1];
- if (myexponent==1 && !(mysignificand & 0x10000000000000LL))
- myexponent = 0; // denormal
- if (myexponent2==1 && !(mysignificand2 & 0x10000000000000LL))
- myexponent2 = 0; // denormal
- } else if (category==fcZero) {
- myexponent = 0;
- mysignificand = 0;
- myexponent2 = 0;
- mysignificand2 = 0;
- } else if (category==fcInfinity) {
- myexponent = 0x7ff;
- myexponent2 = 0;
- mysignificand = 0;
- mysignificand2 = 0;
+ uint64_t words[2];
+ opStatus fs;
+ bool losesInfo;
+
+ // Convert number to double. To avoid spurious underflows, we re-
+ // normalize against the "double" minExponent first, and only *then*
+ // truncate the mantissa. The result of that second conversion
+ // may be inexact, but should never underflow.
+ APFloat extended(*this);
+ fltSemantics extendedSemantics = *semantics;
+ extendedSemantics.minExponent = IEEEdouble.minExponent;
+ fs = extended.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
+
+ APFloat u(extended);
+ fs = u.convert(IEEEdouble, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK || fs == opInexact);
+ (void)fs;
+ words[0] = *u.convertDoubleAPFloatToAPInt().getRawData();
+
+ // If conversion was exact or resulted in a special case, we're done;
+ // just set the second double to zero. Otherwise, re-convert back to
+ // the extended format and compute the difference. This now should
+ // convert exactly to double.
+ if (u.category == fcNormal && losesInfo) {
+ fs = u.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
+
+ APFloat v(extended);
+ v.subtract(u, rmNearestTiesToEven);
+ fs = v.convert(IEEEdouble, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
+ words[1] = *v.convertDoubleAPFloatToAPInt().getRawData();
} else {
- assert(category == fcNaN && "Unknown category");
- myexponent = 0x7ff;
- mysignificand = significandParts()[0];
- myexponent2 = exponent2;
- mysignificand2 = significandParts()[1];
+ words[1] = 0;
}
- uint64_t words[2];
- words[0] = ((uint64_t)(sign & 1) << 63) |
- ((myexponent & 0x7ff) << 52) |
- (mysignificand & 0xfffffffffffffLL);
- words[1] = ((uint64_t)(sign2 & 1) << 63) |
- ((myexponent2 & 0x7ff) << 52) |
- (mysignificand2 & 0xfffffffffffffLL);
return APInt(128, words);
}
@@ -3043,47 +3012,23 @@ APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api)
assert(api.getBitWidth()==128);
uint64_t i1 = api.getRawData()[0];
uint64_t i2 = api.getRawData()[1];
- uint64_t myexponent = (i1 >> 52) & 0x7ff;
- uint64_t mysignificand = i1 & 0xfffffffffffffLL;
- uint64_t myexponent2 = (i2 >> 52) & 0x7ff;
- uint64_t mysignificand2 = i2 & 0xfffffffffffffLL;
+ opStatus fs;
+ bool losesInfo;
- initialize(&APFloat::PPCDoubleDouble);
- assert(partCount()==2);
+ // Get the first double and convert to our format.
+ initFromDoubleAPInt(APInt(64, i1));
+ fs = convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
- sign = static_cast<unsigned int>(i1>>63);
- sign2 = static_cast<unsigned int>(i2>>63);
- if (myexponent==0 && mysignificand==0) {
- // exponent, significand meaningless
- // exponent2 and significand2 are required to be 0; we don't check
- category = fcZero;
- } else if (myexponent==0x7ff && mysignificand==0) {
- // exponent, significand meaningless
- // exponent2 and significand2 are required to be 0; we don't check
- category = fcInfinity;
- } else if (myexponent==0x7ff && mysignificand!=0) {
- // exponent meaningless. So is the whole second word, but keep it
- // for determinism.
- category = fcNaN;
- exponent2 = myexponent2;
- significandParts()[0] = mysignificand;
- significandParts()[1] = mysignificand2;
- } else {
- category = fcNormal;
- // Note there is no category2; the second word is treated as if it is
- // fcNormal, although it might be something else considered by itself.
- exponent = myexponent - 1023;
- exponent2 = myexponent2 - 1023;
- significandParts()[0] = mysignificand;
- significandParts()[1] = mysignificand2;
- if (myexponent==0) // denormal
- exponent = -1022;
- else
- significandParts()[0] |= 0x10000000000000LL; // integer bit
- if (myexponent2==0)
- exponent2 = -1022;
- else
- significandParts()[1] |= 0x10000000000000LL; // integer bit
+ // Unless we have a special case, add in second double.
+ if (category == fcNormal) {
+ APFloat v(APInt(64, i2));
+ fs = v.convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
+ assert(fs == opOK && !losesInfo);
+ (void)fs;
+
+ add(v, rmNearestTiesToEven);
}
}
@@ -3309,15 +3254,15 @@ APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) {
return Val;
}
-APFloat::APFloat(const APInt& api, bool isIEEE) : exponent2(0), sign2(0) {
+APFloat::APFloat(const APInt& api, bool isIEEE) {
initFromAPInt(api, isIEEE);
}
-APFloat::APFloat(float f) : exponent2(0), sign2(0) {
+APFloat::APFloat(float f) {
initFromAPInt(APInt::floatToBits(f));
}
-APFloat::APFloat(double d) : exponent2(0), sign2(0) {
+APFloat::APFloat(double d) {
initFromAPInt(APInt::doubleToBits(d));
}
@@ -3608,11 +3553,6 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
}
bool APFloat::getExactInverse(APFloat *inv) const {
- // We can only guarantee the existence of an exact inverse for IEEE floats.
- if (semantics != &IEEEhalf && semantics != &IEEEsingle &&
- semantics != &IEEEdouble && semantics != &IEEEquad)
- return false;
-
// Special floats and denormals have no exact inverse.
if (category != fcNormal)
return false;
OpenPOWER on IntegriCloud