diff options
Diffstat (limited to 'llvm/lib/Support/APFloat.cpp')
-rw-r--r-- | llvm/lib/Support/APFloat.cpp | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/llvm/lib/Support/APFloat.cpp b/llvm/lib/Support/APFloat.cpp index 7abca8391f70..4b75c9db8526 100644 --- a/llvm/lib/Support/APFloat.cpp +++ b/llvm/lib/Support/APFloat.cpp @@ -92,7 +92,7 @@ namespace llvm { Note: we need to make the value different from semBogus as otherwise an unsafe optimization may collapse both values to a single address, and we heavily rely on them having distinct addresses. */ - static const fltSemantics semPPCDoubleDouble = {-1, 0, 0, 0}; + static const fltSemantics semPPCDoubleDouble = {-1, 0, 0, 128}; /* These are legacy semantics for the fallback, inaccrurate implementation of IBM double-double, if the accurate semPPCDoubleDouble doesn't handle the @@ -1288,6 +1288,23 @@ IEEEFloat::compareAbsoluteValue(const IEEEFloat &rhs) const { return cmpEqual; } +/* Set the least significant BITS bits of a bignum, clear the + rest. */ +static void tcSetLeastSignificantBits(APInt::WordType *dst, unsigned parts, + unsigned bits) { + unsigned i = 0; + while (bits > APInt::APINT_BITS_PER_WORD) { + dst[i++] = ~(APInt::WordType)0; + bits -= APInt::APINT_BITS_PER_WORD; + } + + if (bits) + dst[i++] = ~(APInt::WordType)0 >> (APInt::APINT_BITS_PER_WORD - bits); + + while (i < parts) + dst[i++] = 0; +} + /* Handle overflow. Sign is preserved. We either become infinity or the largest finite number. */ IEEEFloat::opStatus IEEEFloat::handleOverflow(roundingMode rounding_mode) { @@ -1303,8 +1320,8 @@ IEEEFloat::opStatus IEEEFloat::handleOverflow(roundingMode rounding_mode) { /* Otherwise we become the largest finite number. */ category = fcNormal; exponent = semantics->maxExponent; - APInt::tcSetLeastSignificantBits(significandParts(), partCount(), - semantics->precision); + tcSetLeastSignificantBits(significandParts(), partCount(), + semantics->precision); return opInexact; } @@ -2412,7 +2429,7 @@ IEEEFloat::convertToInteger(MutableArrayRef<integerPart> parts, else bits = width - isSigned; - APInt::tcSetLeastSignificantBits(parts.data(), dstPartsCount, bits); + tcSetLeastSignificantBits(parts.data(), dstPartsCount, bits); if (sign && isSigned) APInt::tcShiftLeft(parts.data(), dstPartsCount, width - 1); } @@ -3379,7 +3396,6 @@ double IEEEFloat::convertToDouble() const { /// exponent = 0, integer bit 1 ("pseudodenormal") /// At the moment, the first three are treated as NaNs, the last one as Normal. void IEEEFloat::initFromF80LongDoubleAPInt(const APInt &api) { - assert(api.getBitWidth()==80); uint64_t i1 = api.getRawData()[0]; uint64_t i2 = api.getRawData()[1]; uint64_t myexponent = (i2 & 0x7fff); @@ -3411,7 +3427,6 @@ void IEEEFloat::initFromF80LongDoubleAPInt(const APInt &api) { } void IEEEFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) { - assert(api.getBitWidth()==128); uint64_t i1 = api.getRawData()[0]; uint64_t i2 = api.getRawData()[1]; opStatus fs; @@ -3435,7 +3450,6 @@ void IEEEFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) { } void IEEEFloat::initFromQuadrupleAPInt(const APInt &api) { - assert(api.getBitWidth()==128); uint64_t i1 = api.getRawData()[0]; uint64_t i2 = api.getRawData()[1]; uint64_t myexponent = (i2 >> 48) & 0x7fff; @@ -3471,7 +3485,6 @@ void IEEEFloat::initFromQuadrupleAPInt(const APInt &api) { } void IEEEFloat::initFromDoubleAPInt(const APInt &api) { - assert(api.getBitWidth()==64); uint64_t i = *api.getRawData(); uint64_t myexponent = (i >> 52) & 0x7ff; uint64_t mysignificand = i & 0xfffffffffffffLL; @@ -3500,7 +3513,6 @@ void IEEEFloat::initFromDoubleAPInt(const APInt &api) { } void IEEEFloat::initFromFloatAPInt(const APInt &api) { - assert(api.getBitWidth()==32); uint32_t i = (uint32_t)*api.getRawData(); uint32_t myexponent = (i >> 23) & 0xff; uint32_t mysignificand = i & 0x7fffff; @@ -3529,7 +3541,6 @@ void IEEEFloat::initFromFloatAPInt(const APInt &api) { } void IEEEFloat::initFromBFloatAPInt(const APInt &api) { - assert(api.getBitWidth() == 16); uint32_t i = (uint32_t)*api.getRawData(); uint32_t myexponent = (i >> 7) & 0xff; uint32_t mysignificand = i & 0x7f; @@ -3558,7 +3569,6 @@ void IEEEFloat::initFromBFloatAPInt(const APInt &api) { } void IEEEFloat::initFromHalfAPInt(const APInt &api) { - assert(api.getBitWidth()==16); uint32_t i = (uint32_t)*api.getRawData(); uint32_t myexponent = (i >> 10) & 0x1f; uint32_t mysignificand = i & 0x3ff; @@ -3591,6 +3601,7 @@ void IEEEFloat::initFromHalfAPInt(const APInt &api) { /// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful /// when the size is anything else). void IEEEFloat::initFromAPInt(const fltSemantics *Sem, const APInt &api) { + assert(api.getBitWidth() == Sem->sizeInBits); if (Sem == &semIEEEhalf) return initFromHalfAPInt(api); if (Sem == &semBFloat) @@ -4847,9 +4858,8 @@ APFloat::opStatus APFloat::convert(const fltSemantics &ToSemantics, llvm_unreachable("Unexpected semantics"); } -APFloat APFloat::getAllOnesValue(const fltSemantics &Semantics, - unsigned BitWidth) { - return APFloat(Semantics, APInt::getAllOnesValue(BitWidth)); +APFloat APFloat::getAllOnesValue(const fltSemantics &Semantics) { + return APFloat(Semantics, APInt::getAllOnes(Semantics.sizeInBits)); } void APFloat::print(raw_ostream &OS) const { |