summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Support/APFloat.cpp
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2014-03-21 17:53:59 +0000
committerdim <dim@FreeBSD.org>2014-03-21 17:53:59 +0000
commit9cedb8bb69b89b0f0c529937247a6a80cabdbaec (patch)
treec978f0e9ec1ab92dc8123783f30b08a7fd1e2a39 /contrib/llvm/lib/Support/APFloat.cpp
parent03fdc2934eb61c44c049a02b02aa974cfdd8a0eb (diff)
downloadFreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.zip
FreeBSD-src-9cedb8bb69b89b0f0c529937247a6a80cabdbaec.tar.gz
MFC 261991:
Upgrade our copy of llvm/clang to 3.4 release. This version supports all of the features in the current working draft of the upcoming C++ standard, provisionally named C++1y. The code generator's performance is greatly increased, and the loop auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The PowerPC backend has made several major improvements to code generation quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ backends have all seen major feature work. Release notes for llvm and clang can be found here: <http://llvm.org/releases/3.4/docs/ReleaseNotes.html> <http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html> MFC 262121 (by emaste): Update lldb for clang/llvm 3.4 import This commit largely restores the lldb source to the upstream r196259 snapshot with the addition of threaded inferior support and a few bug fixes. Specific upstream lldb revisions restored include: SVN git 181387 779e6ac 181703 7bef4e2 182099 b31044e 182650 f2dcf35 182683 0d91b80 183862 15c1774 183929 99447a6 184177 0b2934b 184948 4dc3761 184954 007e7bc 186990 eebd175 Sponsored by: DARPA, AFRL MFC 262186 (by emaste): Fix mismerge in r262121 A break statement was lost in the merge. The error had no functional impact, but restore it to reduce the diff against upstream. MFC 262303: Pull in r197521 from upstream clang trunk (by rdivacky): Use the integrated assembler by default on FreeBSD/ppc and ppc64. Requested by: jhibbits MFC 262611: Pull in r196874 from upstream llvm trunk: Fix a crash that occurs when PWD is invalid. MCJIT needs to be able to run in hostile environments, even when PWD is invalid. There's no need to crash MCJIT in this case. The obvious fix is to simply leave MCContext's CompilationDir empty when PWD can't be determined. This way, MCJIT clients, and other clients that link with LLVM don't need a valid working directory. If we do want to guarantee valid CompilationDir, that should be done only for clients of getCompilationDir(). This is as simple as checking for an empty string. The only current use of getCompilationDir is EmitGenDwarfInfo, which won't conceivably run with an invalid working dir. However, in the purely hypothetically and untestable case that this happens, the AT_comp_dir will be omitted from the compilation_unit DIE. This should help fix assertions occurring with ports-mgmt/tinderbox, when it is using jails, and sometimes invalidates clang's current working directory. Reported by: decke MFC 262809: Pull in r203007 from upstream clang trunk: Don't produce an alias between destructors with different calling conventions. Fixes pr19007. (Please note that is an LLVM PR identifier, not a FreeBSD one.) This should fix Firefox and/or libxul crashes (due to problems with regparm/stdcall calling conventions) on i386. Reported by: multiple users on freebsd-current PR: bin/187103 MFC 263048: Repair recognition of "CC" as an alias for the C++ compiler, since it was silently broken by upstream for a Windows-specific use-case. Apparently some versions of CMake still rely on this archaic feature... Reported by: rakuco MFC 263049: Garbage collect the old way of adding the libstdc++ include directories in clang's InitHeaderSearch.cpp. This has been superseded by David Chisnall's commit in r255321. Moreover, if libc++ is used, the libstdc++ include directories should not be in the search path at all. These directories are now only used if you pass -stdlib=libstdc++.
Diffstat (limited to 'contrib/llvm/lib/Support/APFloat.cpp')
-rw-r--r--contrib/llvm/lib/Support/APFloat.cpp696
1 files changed, 495 insertions, 201 deletions
diff --git a/contrib/llvm/lib/Support/APFloat.cpp b/contrib/llvm/lib/Support/APFloat.cpp
index 6182e34..676e2d4 100644
--- a/contrib/llvm/lib/Support/APFloat.cpp
+++ b/contrib/llvm/lib/Support/APFloat.cpp
@@ -25,7 +25,13 @@
using namespace llvm;
-#define convolve(lhs, rhs) ((lhs) * 4 + (rhs))
+/// A macro used to combine two fcCategory enums into one key which can be used
+/// in a switch statement to classify how the interaction of two APFloat's
+/// categories affects an operation.
+///
+/// TODO: If clang source code is ever allowed to use constexpr in its own
+/// codebase, change this into a static inline function.
+#define PackCategoriesIntoKey(_lhs, _rhs) ((_lhs) * 4 + (_rhs))
/* Assumed in hexadecimal significand parsing, and conversion to
hexadecimal strings. */
@@ -38,11 +44,11 @@ namespace llvm {
struct fltSemantics {
/* The largest E such that 2^E is representable; this matches the
definition of IEEE 754. */
- exponent_t maxExponent;
+ APFloat::ExponentType maxExponent;
/* The smallest E such that 2^E is a normalized number; this
matches the definition of IEEE 754. */
- exponent_t minExponent;
+ APFloat::ExponentType minExponent;
/* Number of bits in the significand. This includes the integer
bit. */
@@ -288,9 +294,9 @@ interpretDecimal(StringRef::iterator begin, StringRef::iterator end,
}
/* Adjust the exponents for any decimal point. */
- D->exponent += static_cast<exponent_t>((dot - p) - (dot > p));
+ D->exponent += static_cast<APFloat::ExponentType>((dot - p) - (dot > p));
D->normalizedExponent = (D->exponent +
- static_cast<exponent_t>((p - D->firstSigDigit)
+ static_cast<APFloat::ExponentType>((p - D->firstSigDigit)
- (dot > D->firstSigDigit && dot < p)));
}
@@ -313,8 +319,8 @@ trailingHexadecimalFraction(StringRef::iterator p, StringRef::iterator end,
else if (digitValue < 8 && digitValue > 0)
return lfLessThanHalf;
- /* Otherwise we need to find the first non-zero digit. */
- while (*p == '0')
+ // Otherwise we need to find the first non-zero digit.
+ while (p != end && (*p == '0' || *p == '.'))
p++;
assert(p != end && "Invalid trailing hexadecimal fraction!");
@@ -580,7 +586,7 @@ APFloat::initialize(const fltSemantics *ourSemantics)
void
APFloat::freeSignificand()
{
- if (partCount() > 1)
+ if (needsCleanup())
delete [] significand.parts;
}
@@ -592,14 +598,14 @@ APFloat::assign(const APFloat &rhs)
sign = rhs.sign;
category = rhs.category;
exponent = rhs.exponent;
- if (category == fcNormal || category == fcNaN)
+ if (isFiniteNonZero() || category == fcNaN)
copySignificand(rhs);
}
void
APFloat::copySignificand(const APFloat &rhs)
{
- assert(category == fcNormal || category == fcNaN);
+ assert(isFiniteNonZero() || category == fcNaN);
assert(rhs.partCount() >= partCount());
APInt::tcAssign(significandParts(), rhs.significandParts(),
@@ -679,12 +685,73 @@ APFloat::operator=(const APFloat &rhs)
bool
APFloat::isDenormal() const {
- return isNormal() && (exponent == semantics->minExponent) &&
+ return isFiniteNonZero() && (exponent == semantics->minExponent) &&
(APInt::tcExtractBit(significandParts(),
semantics->precision - 1) == 0);
}
bool
+APFloat::isSmallest() const {
+ // The smallest number by magnitude in our format will be the smallest
+ // denormal, i.e. the floating point number with exponent being minimum
+ // exponent and significand bitwise equal to 1 (i.e. with MSB equal to 0).
+ return isFiniteNonZero() && exponent == semantics->minExponent &&
+ significandMSB() == 0;
+}
+
+bool APFloat::isSignificandAllOnes() const {
+ // Test if the significand excluding the integral bit is all ones. This allows
+ // us to test for binade boundaries.
+ const integerPart *Parts = significandParts();
+ const unsigned PartCount = partCount();
+ for (unsigned i = 0; i < PartCount - 1; i++)
+ if (~Parts[i])
+ return false;
+
+ // Set the unused high bits to all ones when we compare.
+ const unsigned NumHighBits =
+ PartCount*integerPartWidth - semantics->precision + 1;
+ assert(NumHighBits <= integerPartWidth && "Can not have more high bits to "
+ "fill than integerPartWidth");
+ const integerPart HighBitFill =
+ ~integerPart(0) << (integerPartWidth - NumHighBits);
+ if (~(Parts[PartCount - 1] | HighBitFill))
+ return false;
+
+ return true;
+}
+
+bool APFloat::isSignificandAllZeros() const {
+ // Test if the significand excluding the integral bit is all zeros. This
+ // allows us to test for binade boundaries.
+ const integerPart *Parts = significandParts();
+ const unsigned PartCount = partCount();
+
+ for (unsigned i = 0; i < PartCount - 1; i++)
+ if (Parts[i])
+ return false;
+
+ const unsigned NumHighBits =
+ PartCount*integerPartWidth - semantics->precision + 1;
+ assert(NumHighBits <= integerPartWidth && "Can not have more high bits to "
+ "clear than integerPartWidth");
+ const integerPart HighBitMask = ~integerPart(0) >> NumHighBits;
+
+ if (Parts[PartCount - 1] & HighBitMask)
+ return false;
+
+ return true;
+}
+
+bool
+APFloat::isLargest() const {
+ // The largest number by magnitude in our format will be the floating point
+ // number with maximum exponent and with significand that is all ones.
+ return isFiniteNonZero() && exponent == semantics->maxExponent
+ && isSignificandAllOnes();
+}
+
+bool
APFloat::bitwiseIsEqual(const APFloat &rhs) const {
if (this == &rhs)
return true;
@@ -694,7 +761,7 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
return false;
if (category==fcZero || category==fcInfinity)
return true;
- else if (category==fcNormal && exponent!=rhs.exponent)
+ else if (isFiniteNonZero() && exponent!=rhs.exponent)
return false;
else {
int i= partCount();
@@ -711,6 +778,7 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) {
initialize(&ourSemantics);
sign = 0;
+ category = fcNormal;
zeroSignificand();
exponent = ourSemantics.precision - 1;
significandParts()[0] = value;
@@ -728,17 +796,6 @@ APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) {
initialize(&ourSemantics);
}
-APFloat::APFloat(const fltSemantics &ourSemantics,
- fltCategory ourCategory, bool negative) {
- initialize(&ourSemantics);
- category = ourCategory;
- sign = negative;
- if (category == fcNormal)
- category = fcZero;
- else if (ourCategory == fcNaN)
- makeNaN();
-}
-
APFloat::APFloat(const fltSemantics &ourSemantics, StringRef text) {
initialize(&ourSemantics);
convertFromString(text, rmNearestTiesToEven);
@@ -780,8 +837,6 @@ APFloat::significandParts() const
integerPart *
APFloat::significandParts()
{
- assert(category == fcNormal || category == fcNaN);
-
if (partCount() > 1)
return significand.parts;
else
@@ -791,7 +846,6 @@ APFloat::significandParts()
void
APFloat::zeroSignificand()
{
- category = fcNormal;
APInt::tcSet(significandParts(), 0, partCount());
}
@@ -872,7 +926,21 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend)
omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1;
exponent += rhs.exponent;
+ // Assume the operands involved in the multiplication are single-precision
+ // FP, and the two multiplicants are:
+ // *this = a23 . a22 ... a0 * 2^e1
+ // rhs = b23 . b22 ... b0 * 2^e2
+ // the result of multiplication is:
+ // *this = c47 c46 . c45 ... c0 * 2^(e1+e2)
+ // Note that there are two significant bits at the left-hand side of the
+ // radix point. Move the radix point toward left by one bit, and adjust
+ // exponent accordingly.
+ exponent += 1;
+
if (addend) {
+ // The intermediate result of the multiplication has "2 * precision"
+ // signicant bit; adjust the addend to be consistent with mul result.
+ //
Significand savedSignificand = significand;
const fltSemantics *savedSemantics = semantics;
fltSemantics extendedSemantics;
@@ -880,8 +948,9 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend)
unsigned int extendedPrecision;
/* Normalize our MSB. */
- extendedPrecision = precision + precision - 1;
+ extendedPrecision = 2 * precision;
if (omsb != extendedPrecision) {
+ assert(extendedPrecision > omsb);
APInt::tcShiftLeft(fullSignificand, newPartsCount,
extendedPrecision - omsb);
exponent -= extendedPrecision - omsb;
@@ -912,8 +981,18 @@ APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend)
omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1;
}
- exponent -= (precision - 1);
+ // Convert the result having "2 * precision" significant-bits back to the one
+ // having "precision" significant-bits. First, move the radix point from
+ // poision "2*precision - 1" to "precision - 1". The exponent need to be
+ // adjusted by "2*precision - 1" - "precision - 1" = "precision".
+ exponent -= precision;
+ // In case MSB resides at the left-hand side of radix point, shift the
+ // mantissa right by some amount to make sure the MSB reside right before
+ // the radix point (i.e. "MSB . rest-significant-bits").
+ //
+ // Note that the result is not normalized when "omsb < precision". So, the
+ // caller needs to call APFloat::normalize() if normalized value is expected.
if (omsb > precision) {
unsigned int bits, significantParts;
lostFraction lf;
@@ -1035,7 +1114,7 @@ lostFraction
APFloat::shiftSignificandRight(unsigned int bits)
{
/* Our exponent should not overflow. */
- assert((exponent_t) (exponent + bits) >= exponent);
+ assert((ExponentType) (exponent + bits) >= exponent);
exponent += bits;
@@ -1064,8 +1143,8 @@ APFloat::compareAbsoluteValue(const APFloat &rhs) const
int compare;
assert(semantics == rhs.semantics);
- assert(category == fcNormal);
- assert(rhs.category == fcNormal);
+ assert(isFiniteNonZero());
+ assert(rhs.isFiniteNonZero());
compare = exponent - rhs.exponent;
@@ -1117,7 +1196,7 @@ APFloat::roundAwayFromZero(roundingMode rounding_mode,
unsigned int bit) const
{
/* NaNs and infinities should not have lost fractions. */
- assert(category == fcNormal || category == fcZero);
+ assert(isFiniteNonZero() || category == fcZero);
/* Current callers never pass this so we don't handle it. */
assert(lost_fraction != lfExactlyZero);
@@ -1155,7 +1234,7 @@ APFloat::normalize(roundingMode rounding_mode,
unsigned int omsb; /* One, not zero, based MSB. */
int exponentChange;
- if (category != fcNormal)
+ if (!isFiniteNonZero())
return opOK;
/* Before rounding normalize the exponent of fcNormal numbers. */
@@ -1259,42 +1338,43 @@ APFloat::normalize(roundingMode rounding_mode,
APFloat::opStatus
APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract)
{
- switch (convolve(category, rhs.category)) {
+ switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
llvm_unreachable(0);
- case convolve(fcNaN, fcZero):
- case convolve(fcNaN, fcNormal):
- case convolve(fcNaN, fcInfinity):
- case convolve(fcNaN, fcNaN):
- case convolve(fcNormal, fcZero):
- case convolve(fcInfinity, fcNormal):
- case convolve(fcInfinity, fcZero):
+ case PackCategoriesIntoKey(fcNaN, fcZero):
+ case PackCategoriesIntoKey(fcNaN, fcNormal):
+ case PackCategoriesIntoKey(fcNaN, fcInfinity):
+ case PackCategoriesIntoKey(fcNaN, fcNaN):
+ case PackCategoriesIntoKey(fcNormal, fcZero):
+ case PackCategoriesIntoKey(fcInfinity, fcNormal):
+ case PackCategoriesIntoKey(fcInfinity, fcZero):
return opOK;
- case convolve(fcZero, fcNaN):
- case convolve(fcNormal, fcNaN):
- case convolve(fcInfinity, fcNaN):
+ case PackCategoriesIntoKey(fcZero, fcNaN):
+ case PackCategoriesIntoKey(fcNormal, fcNaN):
+ case PackCategoriesIntoKey(fcInfinity, fcNaN):
+ sign = false;
category = fcNaN;
copySignificand(rhs);
return opOK;
- case convolve(fcNormal, fcInfinity):
- case convolve(fcZero, fcInfinity):
+ case PackCategoriesIntoKey(fcNormal, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcInfinity):
category = fcInfinity;
sign = rhs.sign ^ subtract;
return opOK;
- case convolve(fcZero, fcNormal):
+ case PackCategoriesIntoKey(fcZero, fcNormal):
assign(rhs);
sign = rhs.sign ^ subtract;
return opOK;
- case convolve(fcZero, fcZero):
+ case PackCategoriesIntoKey(fcZero, fcZero):
/* Sign depends on rounding mode; handled by caller. */
return opOK;
- case convolve(fcInfinity, fcInfinity):
+ case PackCategoriesIntoKey(fcInfinity, fcInfinity):
/* Differently signed infinities can only be validly
subtracted. */
if (((sign ^ rhs.sign)!=0) != subtract) {
@@ -1304,7 +1384,7 @@ APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract)
return opOK;
- case convolve(fcNormal, fcNormal):
+ case PackCategoriesIntoKey(fcNormal, fcNormal):
return opDivByZero;
}
}
@@ -1385,41 +1465,43 @@ APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract)
APFloat::opStatus
APFloat::multiplySpecials(const APFloat &rhs)
{
- switch (convolve(category, rhs.category)) {
+ switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
llvm_unreachable(0);
- case convolve(fcNaN, fcZero):
- case convolve(fcNaN, fcNormal):
- case convolve(fcNaN, fcInfinity):
- case convolve(fcNaN, fcNaN):
+ case PackCategoriesIntoKey(fcNaN, fcZero):
+ case PackCategoriesIntoKey(fcNaN, fcNormal):
+ case PackCategoriesIntoKey(fcNaN, fcInfinity):
+ case PackCategoriesIntoKey(fcNaN, fcNaN):
+ sign = false;
return opOK;
- case convolve(fcZero, fcNaN):
- case convolve(fcNormal, fcNaN):
- case convolve(fcInfinity, fcNaN):
+ case PackCategoriesIntoKey(fcZero, fcNaN):
+ case PackCategoriesIntoKey(fcNormal, fcNaN):
+ case PackCategoriesIntoKey(fcInfinity, fcNaN):
+ sign = false;
category = fcNaN;
copySignificand(rhs);
return opOK;
- case convolve(fcNormal, fcInfinity):
- case convolve(fcInfinity, fcNormal):
- case convolve(fcInfinity, fcInfinity):
+ case PackCategoriesIntoKey(fcNormal, fcInfinity):
+ case PackCategoriesIntoKey(fcInfinity, fcNormal):
+ case PackCategoriesIntoKey(fcInfinity, fcInfinity):
category = fcInfinity;
return opOK;
- case convolve(fcZero, fcNormal):
- case convolve(fcNormal, fcZero):
- case convolve(fcZero, fcZero):
+ case PackCategoriesIntoKey(fcZero, fcNormal):
+ case PackCategoriesIntoKey(fcNormal, fcZero):
+ case PackCategoriesIntoKey(fcZero, fcZero):
category = fcZero;
return opOK;
- case convolve(fcZero, fcInfinity):
- case convolve(fcInfinity, fcZero):
+ case PackCategoriesIntoKey(fcZero, fcInfinity):
+ case PackCategoriesIntoKey(fcInfinity, fcZero):
makeNaN();
return opInvalidOp;
- case convolve(fcNormal, fcNormal):
+ case PackCategoriesIntoKey(fcNormal, fcNormal):
return opOK;
}
}
@@ -1427,41 +1509,40 @@ APFloat::multiplySpecials(const APFloat &rhs)
APFloat::opStatus
APFloat::divideSpecials(const APFloat &rhs)
{
- switch (convolve(category, rhs.category)) {
+ switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
llvm_unreachable(0);
- case convolve(fcNaN, fcZero):
- case convolve(fcNaN, fcNormal):
- case convolve(fcNaN, fcInfinity):
- case convolve(fcNaN, fcNaN):
- case convolve(fcInfinity, fcZero):
- case convolve(fcInfinity, fcNormal):
- case convolve(fcZero, fcInfinity):
- case convolve(fcZero, fcNormal):
- return opOK;
-
- case convolve(fcZero, fcNaN):
- case convolve(fcNormal, fcNaN):
- case convolve(fcInfinity, fcNaN):
+ case PackCategoriesIntoKey(fcZero, fcNaN):
+ case PackCategoriesIntoKey(fcNormal, fcNaN):
+ case PackCategoriesIntoKey(fcInfinity, fcNaN):
category = fcNaN;
copySignificand(rhs);
+ case PackCategoriesIntoKey(fcNaN, fcZero):
+ case PackCategoriesIntoKey(fcNaN, fcNormal):
+ case PackCategoriesIntoKey(fcNaN, fcInfinity):
+ case PackCategoriesIntoKey(fcNaN, fcNaN):
+ sign = false;
+ case PackCategoriesIntoKey(fcInfinity, fcZero):
+ case PackCategoriesIntoKey(fcInfinity, fcNormal):
+ case PackCategoriesIntoKey(fcZero, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcNormal):
return opOK;
- case convolve(fcNormal, fcInfinity):
+ case PackCategoriesIntoKey(fcNormal, fcInfinity):
category = fcZero;
return opOK;
- case convolve(fcNormal, fcZero):
+ case PackCategoriesIntoKey(fcNormal, fcZero):
category = fcInfinity;
return opDivByZero;
- case convolve(fcInfinity, fcInfinity):
- case convolve(fcZero, fcZero):
+ case PackCategoriesIntoKey(fcInfinity, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcZero):
makeNaN();
return opInvalidOp;
- case convolve(fcNormal, fcNormal):
+ case PackCategoriesIntoKey(fcNormal, fcNormal):
return opOK;
}
}
@@ -1469,35 +1550,36 @@ APFloat::divideSpecials(const APFloat &rhs)
APFloat::opStatus
APFloat::modSpecials(const APFloat &rhs)
{
- switch (convolve(category, rhs.category)) {
+ switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
llvm_unreachable(0);
- case convolve(fcNaN, fcZero):
- case convolve(fcNaN, fcNormal):
- case convolve(fcNaN, fcInfinity):
- case convolve(fcNaN, fcNaN):
- case convolve(fcZero, fcInfinity):
- case convolve(fcZero, fcNormal):
- case convolve(fcNormal, fcInfinity):
+ case PackCategoriesIntoKey(fcNaN, fcZero):
+ case PackCategoriesIntoKey(fcNaN, fcNormal):
+ case PackCategoriesIntoKey(fcNaN, fcInfinity):
+ case PackCategoriesIntoKey(fcNaN, fcNaN):
+ case PackCategoriesIntoKey(fcZero, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcNormal):
+ case PackCategoriesIntoKey(fcNormal, fcInfinity):
return opOK;
- case convolve(fcZero, fcNaN):
- case convolve(fcNormal, fcNaN):
- case convolve(fcInfinity, fcNaN):
+ case PackCategoriesIntoKey(fcZero, fcNaN):
+ case PackCategoriesIntoKey(fcNormal, fcNaN):
+ case PackCategoriesIntoKey(fcInfinity, fcNaN):
+ sign = false;
category = fcNaN;
copySignificand(rhs);
return opOK;
- case convolve(fcNormal, fcZero):
- case convolve(fcInfinity, fcZero):
- case convolve(fcInfinity, fcNormal):
- case convolve(fcInfinity, fcInfinity):
- case convolve(fcZero, fcZero):
+ case PackCategoriesIntoKey(fcNormal, fcZero):
+ case PackCategoriesIntoKey(fcInfinity, fcZero):
+ case PackCategoriesIntoKey(fcInfinity, fcNormal):
+ case PackCategoriesIntoKey(fcInfinity, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcZero):
makeNaN();
return opInvalidOp;
- case convolve(fcNormal, fcNormal):
+ case PackCategoriesIntoKey(fcNormal, fcNormal):
return opOK;
}
}
@@ -1578,7 +1660,7 @@ APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode)
sign ^= rhs.sign;
fs = multiplySpecials(rhs);
- if (category == fcNormal) {
+ if (isFiniteNonZero()) {
lostFraction lost_fraction = multiplySignificand(rhs, 0);
fs = normalize(rounding_mode, lost_fraction);
if (lost_fraction != lfExactlyZero)
@@ -1597,7 +1679,7 @@ APFloat::divide(const APFloat &rhs, roundingMode rounding_mode)
sign ^= rhs.sign;
fs = divideSpecials(rhs);
- if (category == fcNormal) {
+ if (isFiniteNonZero()) {
lostFraction lost_fraction = divideSignificand(rhs);
fs = normalize(rounding_mode, lost_fraction);
if (lost_fraction != lfExactlyZero)
@@ -1651,7 +1733,7 @@ APFloat::mod(const APFloat &rhs, roundingMode rounding_mode)
opStatus fs;
fs = modSpecials(rhs);
- if (category == fcNormal && rhs.category == fcNormal) {
+ if (isFiniteNonZero() && rhs.isFiniteNonZero()) {
APFloat V = *this;
unsigned int origSign = sign;
@@ -1697,9 +1779,9 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
/* If and only if all arguments are normal do we need to do an
extended-precision calculation. */
- if (category == fcNormal &&
- multiplicand.category == fcNormal &&
- addend.category == fcNormal) {
+ if (isFiniteNonZero() &&
+ multiplicand.isFiniteNonZero() &&
+ addend.isFiniteNonZero()) {
lostFraction lost_fraction;
lost_fraction = multiplySignificand(multiplicand, &addend);
@@ -1736,7 +1818,7 @@ APFloat::opStatus APFloat::roundToIntegral(roundingMode rounding_mode) {
// 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 (category == fcNormal && exponent+1 >= (int)semanticsPrecision(*semantics))
+ if (isFiniteNonZero() && exponent+1 >= (int)semanticsPrecision(*semantics))
return opOK;
// The algorithm here is quite simple: we add 2^(p-1), where p is the
@@ -1780,36 +1862,36 @@ APFloat::compare(const APFloat &rhs) const
assert(semantics == rhs.semantics);
- switch (convolve(category, rhs.category)) {
+ switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
llvm_unreachable(0);
- case convolve(fcNaN, fcZero):
- case convolve(fcNaN, fcNormal):
- case convolve(fcNaN, fcInfinity):
- case convolve(fcNaN, fcNaN):
- case convolve(fcZero, fcNaN):
- case convolve(fcNormal, fcNaN):
- case convolve(fcInfinity, fcNaN):
+ case PackCategoriesIntoKey(fcNaN, fcZero):
+ case PackCategoriesIntoKey(fcNaN, fcNormal):
+ case PackCategoriesIntoKey(fcNaN, fcInfinity):
+ case PackCategoriesIntoKey(fcNaN, fcNaN):
+ case PackCategoriesIntoKey(fcZero, fcNaN):
+ case PackCategoriesIntoKey(fcNormal, fcNaN):
+ case PackCategoriesIntoKey(fcInfinity, fcNaN):
return cmpUnordered;
- case convolve(fcInfinity, fcNormal):
- case convolve(fcInfinity, fcZero):
- case convolve(fcNormal, fcZero):
+ case PackCategoriesIntoKey(fcInfinity, fcNormal):
+ case PackCategoriesIntoKey(fcInfinity, fcZero):
+ case PackCategoriesIntoKey(fcNormal, fcZero):
if (sign)
return cmpLessThan;
else
return cmpGreaterThan;
- case convolve(fcNormal, fcInfinity):
- case convolve(fcZero, fcInfinity):
- case convolve(fcZero, fcNormal):
+ case PackCategoriesIntoKey(fcNormal, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcInfinity):
+ case PackCategoriesIntoKey(fcZero, fcNormal):
if (rhs.sign)
return cmpGreaterThan;
else
return cmpLessThan;
- case convolve(fcInfinity, fcInfinity):
+ case PackCategoriesIntoKey(fcInfinity, fcInfinity):
if (sign == rhs.sign)
return cmpEqual;
else if (sign)
@@ -1817,10 +1899,10 @@ APFloat::compare(const APFloat &rhs) const
else
return cmpGreaterThan;
- case convolve(fcZero, fcZero):
+ case PackCategoriesIntoKey(fcZero, fcZero):
return cmpEqual;
- case convolve(fcNormal, fcNormal):
+ case PackCategoriesIntoKey(fcNormal, fcNormal):
break;
}
@@ -1877,8 +1959,25 @@ APFloat::convert(const fltSemantics &toSemantics,
X86SpecialNan = true;
}
+ // If this is a truncation of a denormal number, and the target semantics
+ // has larger exponent range than the source semantics (this can happen
+ // when truncating from PowerPC double-double to double format), the
+ // right shift could lose result mantissa bits. Adjust exponent instead
+ // of performing excessive shift.
+ if (shift < 0 && isFiniteNonZero()) {
+ int exponentChange = significandMSB() + 1 - fromSemantics.precision;
+ if (exponent + exponentChange < toSemantics.minExponent)
+ exponentChange = toSemantics.minExponent - exponent;
+ if (exponentChange < shift)
+ exponentChange = shift;
+ if (exponentChange < 0) {
+ shift -= exponentChange;
+ exponent += exponentChange;
+ }
+ }
+
// If this is a truncation, perform the shift before we narrow the storage.
- if (shift < 0 && (category==fcNormal || category==fcNaN))
+ if (shift < 0 && (isFiniteNonZero() || category==fcNaN))
lostFraction = shiftRight(significandParts(), oldPartCount, -shift);
// Fix the storage so it can hold to new value.
@@ -1887,14 +1986,14 @@ APFloat::convert(const fltSemantics &toSemantics,
integerPart *newParts;
newParts = new integerPart[newPartCount];
APInt::tcSet(newParts, 0, newPartCount);
- if (category==fcNormal || category==fcNaN)
+ if (isFiniteNonZero() || category==fcNaN)
APInt::tcAssign(newParts, significandParts(), oldPartCount);
freeSignificand();
significand.parts = newParts;
} else if (newPartCount == 1 && oldPartCount != 1) {
// Switch to built-in storage for a single part.
integerPart newPart = 0;
- if (category==fcNormal || category==fcNaN)
+ if (isFiniteNonZero() || category==fcNaN)
newPart = significandParts()[0];
freeSignificand();
significand.part = newPart;
@@ -1905,10 +2004,10 @@ APFloat::convert(const fltSemantics &toSemantics,
// If this is an extension, perform the shift now that the storage is
// available.
- if (shift > 0 && (category==fcNormal || category==fcNaN))
+ if (shift > 0 && (isFiniteNonZero() || category==fcNaN))
APInt::tcShiftLeft(significandParts(), newPartCount, shift);
- if (category == fcNormal) {
+ if (isFiniteNonZero()) {
fs = normalize(rounding_mode, lostFraction);
*losesInfo = (fs != opOK);
} else if (category == fcNaN) {
@@ -2204,56 +2303,46 @@ APFloat::opStatus
APFloat::convertFromHexadecimalString(StringRef s, roundingMode rounding_mode)
{
lostFraction lost_fraction = lfExactlyZero;
- integerPart *significand;
- unsigned int bitPos, partsCount;
- StringRef::iterator dot, firstSignificantDigit;
+ category = fcNormal;
zeroSignificand();
exponent = 0;
- category = fcNormal;
- significand = significandParts();
- partsCount = partCount();
- bitPos = partsCount * integerPartWidth;
+ integerPart *significand = significandParts();
+ unsigned partsCount = partCount();
+ unsigned bitPos = partsCount * integerPartWidth;
+ bool computedTrailingFraction = false;
- /* Skip leading zeroes and any (hexa)decimal point. */
+ // Skip leading zeroes and any (hexa)decimal point.
StringRef::iterator begin = s.begin();
StringRef::iterator end = s.end();
+ StringRef::iterator dot;
StringRef::iterator p = skipLeadingZeroesAndAnyDot(begin, end, &dot);
- firstSignificantDigit = p;
+ StringRef::iterator firstSignificantDigit = p;
- for (; p != end;) {
+ while (p != end) {
integerPart hex_value;
if (*p == '.') {
assert(dot == end && "String contains multiple dots");
dot = p++;
- if (p == end) {
- break;
- }
+ continue;
}
hex_value = hexDigitValue(*p);
- if (hex_value == -1U) {
+ if (hex_value == -1U)
break;
- }
p++;
- if (p == end) {
- break;
- } else {
- /* Store the number whilst 4-bit nibbles remain. */
- if (bitPos) {
- bitPos -= 4;
- hex_value <<= bitPos % integerPartWidth;
- significand[bitPos / integerPartWidth] |= hex_value;
- } else {
- lost_fraction = trailingHexadecimalFraction(p, end, hex_value);
- while (p != end && hexDigitValue(*p) != -1U)
- p++;
- break;
- }
+ // Store the number while we have space.
+ if (bitPos) {
+ bitPos -= 4;
+ hex_value <<= bitPos % integerPartWidth;
+ significand[bitPos / integerPartWidth] |= hex_value;
+ } else if (!computedTrailingFraction) {
+ lost_fraction = trailingHexadecimalFraction(p, end, hex_value);
+ computedTrailingFraction = true;
}
}
@@ -2316,8 +2405,8 @@ APFloat::roundSignificandWithExponent(const integerPart *decSigParts,
excessPrecision = calcSemantics.precision - semantics->precision;
truncatedBits = excessPrecision;
- APFloat decSig(calcSemantics, fcZero, sign);
- APFloat pow5(calcSemantics, fcZero, false);
+ APFloat decSig = APFloat::getZero(calcSemantics, sign);
+ APFloat pow5(calcSemantics);
sigStatus = decSig.convertFromUnsignedParts(decSigParts, sigPartCount,
rmNearestTiesToEven);
@@ -2402,7 +2491,14 @@ APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode)
42039/12655 < L < 28738/8651 [ numerator <= 65536 ]
*/
- if (decDigitValue(*D.firstSigDigit) >= 10U) {
+ // Test if we have a zero number allowing for strings with no null terminators
+ // and zero decimals with non-zero exponents.
+ //
+ // We computed firstSigDigit by ignoring all zeros and dots. Thus if
+ // D->firstSigDigit equals str.end(), every digit must be a zero and there can
+ // be at most one dot. On the other hand, if we have a zero with a non-zero
+ // exponent, then we know that D.firstSigDigit will be non-numeric.
+ if (D.firstSigDigit == str.end() || decDigitValue(*D.firstSigDigit) >= 10U) {
category = fcZero;
fs = opOK;
@@ -2419,6 +2515,7 @@ APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode)
(D.normalizedExponent + 1) * 28738 <=
8651 * (semantics->minExponent - (int) semantics->precision)) {
/* Underflow to zero and round. */
+ category = fcNormal;
zeroSignificand();
fs = normalize(rounding_mode, lfLessThanHalf);
@@ -2485,11 +2582,40 @@ APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode)
return fs;
}
+bool
+APFloat::convertFromStringSpecials(StringRef str) {
+ if (str.equals("inf") || str.equals("INFINITY")) {
+ makeInf(false);
+ return true;
+ }
+
+ if (str.equals("-inf") || str.equals("-INFINITY")) {
+ makeInf(true);
+ return true;
+ }
+
+ if (str.equals("nan") || str.equals("NaN")) {
+ makeNaN(false, false);
+ return true;
+ }
+
+ if (str.equals("-nan") || str.equals("-NaN")) {
+ makeNaN(false, true);
+ return true;
+ }
+
+ return false;
+}
+
APFloat::opStatus
APFloat::convertFromString(StringRef str, roundingMode rounding_mode)
{
assert(!str.empty() && "Invalid string length");
+ // Handle special cases.
+ if (convertFromStringSpecials(str))
+ return opOK;
+
/* Handle a leading minus sign. */
StringRef::iterator p = str.begin();
size_t slen = str.size();
@@ -2686,7 +2812,7 @@ APFloat::convertNormalToHexString(char *dst, unsigned int hexDigits,
}
hash_code llvm::hash_value(const APFloat &Arg) {
- if (Arg.category != APFloat::fcNormal)
+ if (!Arg.isFiniteNonZero())
return hash_combine((uint8_t)Arg.category,
// NaN has no sign, fix it at zero.
Arg.isNaN() ? (uint8_t)0 : (uint8_t)Arg.sign,
@@ -2717,7 +2843,7 @@ APFloat::convertF80LongDoubleAPFloatToAPInt() const
uint64_t myexponent, mysignificand;
- if (category==fcNormal) {
+ if (isFiniteNonZero()) {
myexponent = exponent+16383; //bias
mysignificand = significandParts()[0];
if (myexponent==1 && !(mysignificand & 0x8000000000000000ULL))
@@ -2774,7 +2900,7 @@ APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const
// 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) {
+ if (u.isFiniteNonZero() && losesInfo) {
fs = u.convert(extendedSemantics, rmNearestTiesToEven, &losesInfo);
assert(fs == opOK && !losesInfo);
(void)fs;
@@ -2800,7 +2926,7 @@ APFloat::convertQuadrupleAPFloatToAPInt() const
uint64_t myexponent, mysignificand, mysignificand2;
- if (category==fcNormal) {
+ if (isFiniteNonZero()) {
myexponent = exponent+16383; //bias
mysignificand = significandParts()[0];
mysignificand2 = significandParts()[1];
@@ -2836,7 +2962,7 @@ APFloat::convertDoubleAPFloatToAPInt() const
uint64_t myexponent, mysignificand;
- if (category==fcNormal) {
+ if (isFiniteNonZero()) {
myexponent = exponent+1023; //bias
mysignificand = *significandParts();
if (myexponent==1 && !(mysignificand & 0x10000000000000LL))
@@ -2866,7 +2992,7 @@ APFloat::convertFloatAPFloatToAPInt() const
uint32_t myexponent, mysignificand;
- if (category==fcNormal) {
+ if (isFiniteNonZero()) {
myexponent = exponent+127; //bias
mysignificand = (uint32_t)*significandParts();
if (myexponent == 1 && !(mysignificand & 0x800000))
@@ -2895,7 +3021,7 @@ APFloat::convertHalfAPFloatToAPInt() const
uint32_t myexponent, mysignificand;
- if (category==fcNormal) {
+ if (isFiniteNonZero()) {
myexponent = exponent+15; //bias
mysignificand = (uint32_t)*significandParts();
if (myexponent == 1 && !(mysignificand & 0x400))
@@ -3018,7 +3144,7 @@ APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api)
(void)fs;
// Unless we have a special case, add in second double.
- if (category == fcNormal) {
+ if (isFiniteNonZero()) {
APFloat v(IEEEdouble, APInt(64, i2));
fs = v.convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
assert(fs == opOK && !losesInfo);
@@ -3211,55 +3337,75 @@ APFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE)
}
}
-APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) {
- APFloat Val(Sem, fcNormal, Negative);
-
+/// Make this number the largest magnitude normal number in the given
+/// semantics.
+void APFloat::makeLargest(bool Negative) {
// We want (in interchange format):
// sign = {Negative}
// exponent = 1..10
// significand = 1..1
+ category = fcNormal;
+ sign = Negative;
+ exponent = semantics->maxExponent;
- Val.exponent = Sem.maxExponent; // unbiased
+ // Use memset to set all but the highest integerPart to all ones.
+ integerPart *significand = significandParts();
+ unsigned PartCount = partCount();
+ memset(significand, 0xFF, sizeof(integerPart)*(PartCount - 1));
- // 1-initialize all bits....
- Val.zeroSignificand();
- integerPart *significand = Val.significandParts();
- unsigned N = partCountForBits(Sem.precision);
- for (unsigned i = 0; i != N; ++i)
- significand[i] = ~((integerPart) 0);
+ // Set the high integerPart especially setting all unused top bits for
+ // internal consistency.
+ const unsigned NumUnusedHighBits =
+ PartCount*integerPartWidth - semantics->precision;
+ significand[PartCount - 1] = ~integerPart(0) >> NumUnusedHighBits;
+}
+
+/// Make this number the smallest magnitude denormal number in the given
+/// semantics.
+void APFloat::makeSmallest(bool Negative) {
+ // We want (in interchange format):
+ // sign = {Negative}
+ // exponent = 0..0
+ // significand = 0..01
+ category = fcNormal;
+ sign = Negative;
+ exponent = semantics->minExponent;
+ APInt::tcSet(significandParts(), 1, partCount());
+}
- // ...and then clear the top bits for internal consistency.
- if (Sem.precision % integerPartWidth != 0)
- significand[N-1] &=
- (((integerPart) 1) << (Sem.precision % integerPartWidth)) - 1;
+APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) {
+ // We want (in interchange format):
+ // sign = {Negative}
+ // exponent = 1..10
+ // significand = 1..1
+ APFloat Val(Sem, uninitialized);
+ Val.makeLargest(Negative);
return Val;
}
APFloat APFloat::getSmallest(const fltSemantics &Sem, bool Negative) {
- APFloat Val(Sem, fcNormal, Negative);
-
// We want (in interchange format):
// sign = {Negative}
// exponent = 0..0
// significand = 0..01
-
- Val.exponent = Sem.minExponent; // unbiased
- Val.zeroSignificand();
- Val.significandParts()[0] = 1;
+ APFloat Val(Sem, uninitialized);
+ Val.makeSmallest(Negative);
return Val;
}
APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) {
- APFloat Val(Sem, fcNormal, Negative);
+ APFloat Val(Sem, uninitialized);
// We want (in interchange format):
// sign = {Negative}
// exponent = 0..0
// significand = 10..0
- Val.exponent = Sem.minExponent;
+ Val.category = fcNormal;
Val.zeroSignificand();
+ Val.sign = Negative;
+ Val.exponent = Sem.minExponent;
Val.significandParts()[partCountForBits(Sem.precision)-1] |=
(((integerPart) 1) << ((Sem.precision - 1) % integerPartWidth));
@@ -3400,11 +3546,14 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
// Set FormatPrecision if zero. We want to do this before we
// truncate trailing zeros, as those are part of the precision.
if (!FormatPrecision) {
- // It's an interesting question whether to use the nominal
- // precision or the active precision here for denormals.
+ // We use enough digits so the number can be round-tripped back to an
+ // APFloat. The formula comes from "How to Print Floating-Point Numbers
+ // Accurately" by Steele and White.
+ // FIXME: Using a formula based purely on the precision is conservative;
+ // we can print fewer digits depending on the actual value being printed.
- // FormatPrecision = ceil(significandBits / lg_2(10))
- FormatPrecision = (semantics->precision * 59 + 195) / 196;
+ // FormatPrecision = 2 + floor(significandBits / lg_2(10))
+ FormatPrecision = 2 + semantics->precision * 59 / 196;
}
// Ignore trailing binary zeros.
@@ -3564,7 +3713,7 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
bool APFloat::getExactInverse(APFloat *inv) const {
// Special floats and denormals have no exact inverse.
- if (category != fcNormal)
+ if (!isFiniteNonZero())
return false;
// Check that the number is a power of two by making sure that only the
@@ -3579,10 +3728,10 @@ bool APFloat::getExactInverse(APFloat *inv) const {
// Avoid multiplication with a denormal, it is not safe on all platforms and
// may be slower than a normal division.
- if (reciprocal.significandMSB() + 1 < reciprocal.semantics->precision)
+ if (reciprocal.isDenormal())
return false;
- assert(reciprocal.category == fcNormal &&
+ assert(reciprocal.isFiniteNonZero() &&
reciprocal.significandLSB() == reciprocal.semantics->precision - 1);
if (inv)
@@ -3590,3 +3739,148 @@ bool APFloat::getExactInverse(APFloat *inv) const {
return true;
}
+
+bool APFloat::isSignaling() const {
+ if (!isNaN())
+ return false;
+
+ // IEEE-754R 2008 6.2.1: A signaling NaN bit string should be encoded with the
+ // first bit of the trailing significand being 0.
+ return !APInt::tcExtractBit(significandParts(), semantics->precision - 2);
+}
+
+/// IEEE-754R 2008 5.3.1: nextUp/nextDown.
+///
+/// *NOTE* since nextDown(x) = -nextUp(-x), we only implement nextUp with
+/// appropriate sign switching before/after the computation.
+APFloat::opStatus APFloat::next(bool nextDown) {
+ // If we are performing nextDown, swap sign so we have -x.
+ if (nextDown)
+ changeSign();
+
+ // Compute nextUp(x)
+ opStatus result = opOK;
+
+ // Handle each float category separately.
+ switch (category) {
+ case fcInfinity:
+ // nextUp(+inf) = +inf
+ if (!isNegative())
+ break;
+ // nextUp(-inf) = -getLargest()
+ makeLargest(true);
+ break;
+ case fcNaN:
+ // IEEE-754R 2008 6.2 Par 2: nextUp(sNaN) = qNaN. Set Invalid flag.
+ // IEEE-754R 2008 6.2: nextUp(qNaN) = qNaN. Must be identity so we do not
+ // change the payload.
+ if (isSignaling()) {
+ result = opInvalidOp;
+ // For consistency, propogate the sign of the sNaN to the qNaN.
+ makeNaN(false, isNegative(), 0);
+ }
+ break;
+ case fcZero:
+ // nextUp(pm 0) = +getSmallest()
+ makeSmallest(false);
+ break;
+ case fcNormal:
+ // nextUp(-getSmallest()) = -0
+ if (isSmallest() && isNegative()) {
+ APInt::tcSet(significandParts(), 0, partCount());
+ category = fcZero;
+ exponent = 0;
+ break;
+ }
+
+ // nextUp(getLargest()) == INFINITY
+ if (isLargest() && !isNegative()) {
+ APInt::tcSet(significandParts(), 0, partCount());
+ category = fcInfinity;
+ exponent = semantics->maxExponent + 1;
+ break;
+ }
+
+ // nextUp(normal) == normal + inc.
+ if (isNegative()) {
+ // If we are negative, we need to decrement the significand.
+
+ // We only cross a binade boundary that requires adjusting the exponent
+ // if:
+ // 1. exponent != semantics->minExponent. This implies we are not in the
+ // smallest binade or are dealing with denormals.
+ // 2. Our significand excluding the integral bit is all zeros.
+ bool WillCrossBinadeBoundary =
+ exponent != semantics->minExponent && isSignificandAllZeros();
+
+ // Decrement the significand.
+ //
+ // We always do this since:
+ // 1. If we are dealing with a non binade decrement, by definition we
+ // just decrement the significand.
+ // 2. If we are dealing with a normal -> normal binade decrement, since
+ // we have an explicit integral bit the fact that all bits but the
+ // integral bit are zero implies that subtracting one will yield a
+ // significand with 0 integral bit and 1 in all other spots. Thus we
+ // must just adjust the exponent and set the integral bit to 1.
+ // 3. If we are dealing with a normal -> denormal binade decrement,
+ // since we set the integral bit to 0 when we represent denormals, we
+ // just decrement the significand.
+ integerPart *Parts = significandParts();
+ APInt::tcDecrement(Parts, partCount());
+
+ if (WillCrossBinadeBoundary) {
+ // Our result is a normal number. Do the following:
+ // 1. Set the integral bit to 1.
+ // 2. Decrement the exponent.
+ APInt::tcSetBit(Parts, semantics->precision - 1);
+ exponent--;
+ }
+ } else {
+ // If we are positive, we need to increment the significand.
+
+ // We only cross a binade boundary that requires adjusting the exponent if
+ // the input is not a denormal and all of said input's significand bits
+ // are set. If all of said conditions are true: clear the significand, set
+ // the integral bit to 1, and increment the exponent. If we have a
+ // denormal always increment since moving denormals and the numbers in the
+ // smallest normal binade have the same exponent in our representation.
+ bool WillCrossBinadeBoundary = !isDenormal() && isSignificandAllOnes();
+
+ if (WillCrossBinadeBoundary) {
+ integerPart *Parts = significandParts();
+ APInt::tcSet(Parts, 0, partCount());
+ APInt::tcSetBit(Parts, semantics->precision - 1);
+ assert(exponent != semantics->maxExponent &&
+ "We can not increment an exponent beyond the maxExponent allowed"
+ " by the given floating point semantics.");
+ exponent++;
+ } else {
+ incrementSignificand();
+ }
+ }
+ break;
+ }
+
+ // If we are performing nextDown, swap sign so we have -nextUp(-x)
+ if (nextDown)
+ changeSign();
+
+ return result;
+}
+
+void
+APFloat::makeInf(bool Negative) {
+ category = fcInfinity;
+ sign = Negative;
+ exponent = semantics->maxExponent + 1;
+ APInt::tcSet(significandParts(), 0, partCount());
+}
+
+void
+APFloat::makeZero(bool Negative) {
+ category = fcZero;
+ sign = Negative;
+ exponent = semantics->minExponent-1;
+ APInt::tcSet(significandParts(), 0, partCount());
+}
OpenPOWER on IntegriCloud