diff options
author | Derek Schuff <dschuff@chromium.org> | 2012-11-06 10:23:47 -0800 |
---|---|---|
committer | Derek Schuff <dschuff@chromium.org> | 2012-11-06 10:23:47 -0800 |
commit | 5bcab54cfde18b4b11f163d7d916711df70cbebf (patch) | |
tree | c5774bfc00faa412178497d9ae92dea73d717a7c /lib/Support/APFloat.cpp | |
parent | 96cb06677afe87ea958bf986ca2b9fb87daa2da1 (diff) | |
parent | cfe09ed28d8a65b671e8b7a716a933e98e810e32 (diff) |
Merge commit 'cfe09ed28d8a65b671e8b7a716a933e98e810e32'
Conflicts:
lib/Target/ARM/ARMFrameLowering.cpp
lib/Target/Mips/MipsRegisterInfo.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Transforms/IPO/ExtractGV.cpp
tools/Makefile
tools/gold/gold-plugin.cpp
The only interesting conflict was X86ISelLowering.ccp, which
meant I had to essentially revert r167104. The problem is that we are
using ESP as the stack pointer in X86ISelLowering and RSP as the
stack pointer in X86FrameLowering, and that revision made them
both consistently use X86RegisterInfo to determine which to use.
Diffstat (limited to 'lib/Support/APFloat.cpp')
-rw-r--r-- | lib/Support/APFloat.cpp | 219 |
1 files changed, 81 insertions, 138 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index d07a3c9e7f..43c68f4d1d 100644 --- a/lib/Support/APFloat.cpp +++ b/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. @@ -612,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); } @@ -707,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(); @@ -729,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(); @@ -740,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; @@ -767,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); } @@ -1561,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. */ @@ -1607,7 +1587,6 @@ APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode) { opStatus fs; - assertArithmeticOK(*semantics); sign ^= rhs.sign; fs = multiplySpecials(rhs); @@ -1627,7 +1606,6 @@ APFloat::divide(const APFloat &rhs, roundingMode rounding_mode) { opStatus fs; - assertArithmeticOK(*semantics); sign ^= rhs.sign; fs = divideSpecials(rhs); @@ -1649,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; @@ -1684,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) { @@ -1728,8 +1704,6 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand, { opStatus fs; - assertArithmeticOK(*semantics); - /* Post-multiplication sign, before addition. */ sign ^= multiplicand.sign; @@ -1770,7 +1744,6 @@ 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 @@ -1817,7 +1790,6 @@ APFloat::compare(const APFloat &rhs) const { cmpResult result; - assertArithmeticOK(*semantics); assert(semantics == rhs.semantics); switch (convolve(category, rhs.category)) { @@ -1902,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(); @@ -1988,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. */ @@ -2151,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(); @@ -2202,7 +2169,6 @@ APFloat::convertFromSignExtendedInteger(const integerPart *src, { opStatus status; - assertArithmeticOK(*semantics); if (isSigned && APInt::tcExtractBit(src, srcCount * integerPartWidth - 1)) { integerPart *copy; @@ -2336,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; @@ -2528,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. */ @@ -2580,8 +2545,6 @@ APFloat::convertToHexString(char *dst, unsigned int hexDigits, { char *p; - assertArithmeticOK(*semantics); - p = dst; if (sign) *dst++ = '-'; @@ -2790,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); } @@ -3045,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); } } @@ -3311,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)); } |