From 7aa1c321f00d29fdc84e9a03080853aa25dd06fc Mon Sep 17 00:00:00 2001 From: Shuxin Yang Date: Mon, 7 Jan 2013 18:59:35 +0000 Subject: Implement APFloat::isDenormal() git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171764 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/APFloat.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'lib/Support/APFloat.cpp') diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 17f38918b3..0e3c619170 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -696,6 +696,13 @@ APFloat::operator=(const APFloat &rhs) return *this; } +bool +APFloat::isDenormal() const { + return isNormal() && (exponent == semantics->minExponent) && + (APInt::tcExtractBit(significandParts(), + semantics->precision - 1) == 0); +} + bool APFloat::bitwiseIsEqual(const APFloat &rhs) const { if (this == &rhs) -- cgit v1.2.3-18-g5258 From 96f498bd9f140a98321c478f517877c4767b94fa Mon Sep 17 00:00:00 2001 From: Dmitri Gribenko Date: Sun, 13 Jan 2013 16:01:15 +0000 Subject: Remove redundant 'llvm::' qualifications git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172358 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/APFloat.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib/Support/APFloat.cpp') diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 0e3c619170..4a7a5d1a05 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -3448,7 +3448,7 @@ void APFloat::toString(SmallVectorImpl &Str, AdjustToPrecision(significand, exp, FormatPrecision); - llvm::SmallVector buffer; + SmallVector buffer; // Fill the buffer. unsigned precision = significand.getBitWidth(); -- cgit v1.2.3-18-g5258 From 8a53a8329f47f86757af17dbea2864aa95414615 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Fri, 18 Jan 2013 21:45:30 +0000 Subject: Add llvm::hexDigitValue to convert single characters to hex. This is duplicated in a couple places in the codebase. Adopt this in APFloat. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@172851 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/APFloat.cpp | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) (limited to 'lib/Support/APFloat.cpp') diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 4a7a5d1a05..2ac86a289a 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/APSInt.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/Hashing.h" +#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" @@ -101,26 +102,6 @@ decDigitValue(unsigned int c) return c - '0'; } -static unsigned int -hexDigitValue(unsigned int c) -{ - unsigned int r; - - r = c - '0'; - if (r <= 9) - return r; - - r = c - 'A'; - if (r <= 5) - return r + 10; - - r = c - 'a'; - if (r <= 5) - return r + 10; - - return -1U; -} - /* Return the value of a decimal exponent of the form [+-]ddddddd. -- cgit v1.2.3-18-g5258 From 0a29cb045444c13160e90fe7942a9d7c720185ed Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Tue, 22 Jan 2013 09:46:31 +0000 Subject: Make APFloat constructor require explicit semantics. Previously we tried to infer it from the bit width size, with an added IsIEEE argument for the PPC/IEEE 128-bit case, which had a default value. This default value allowed bugs to creep in, where it was inappropriate. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173138 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/APFloat.cpp | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-) (limited to 'lib/Support/APFloat.cpp') diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 2ac86a289a..686f91b087 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -3013,7 +3013,7 @@ APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api) // Unless we have a special case, add in second double. if (category == fcNormal) { - APFloat v(APInt(64, i2)); + APFloat v(IEEEdouble, APInt(64, i2)); fs = v.convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo); assert(fs == opOK && !losesInfo); (void)fs; @@ -3166,27 +3166,43 @@ APFloat::initFromHalfAPInt(const APInt & api) /// isIEEE argument distinguishes between PPC128 and IEEE128 (not meaningful /// when the size is anything else). void -APFloat::initFromAPInt(const APInt& api, bool isIEEE) +APFloat::initFromAPInt(const fltSemantics* Sem, const APInt& api) { - if (api.getBitWidth() == 16) + if (Sem == &IEEEhalf) return initFromHalfAPInt(api); - else if (api.getBitWidth() == 32) + if (Sem == &IEEEsingle) return initFromFloatAPInt(api); - else if (api.getBitWidth()==64) + if (Sem == &IEEEdouble) return initFromDoubleAPInt(api); - else if (api.getBitWidth()==80) + if (Sem == &x87DoubleExtended) return initFromF80LongDoubleAPInt(api); - else if (api.getBitWidth()==128) - return (isIEEE ? - initFromQuadrupleAPInt(api) : initFromPPCDoubleDoubleAPInt(api)); - else - llvm_unreachable(0); + if (Sem == &IEEEquad) + return initFromQuadrupleAPInt(api); + if (Sem == &PPCDoubleDouble) + return initFromPPCDoubleDoubleAPInt(api); + + llvm_unreachable(0); } APFloat APFloat::getAllOnesValue(unsigned BitWidth, bool isIEEE) { - return APFloat(APInt::getAllOnesValue(BitWidth), isIEEE); + switch (BitWidth) { + case 16: + return APFloat(IEEEhalf, APInt::getAllOnesValue(BitWidth)); + case 32: + return APFloat(IEEEsingle, APInt::getAllOnesValue(BitWidth)); + case 64: + return APFloat(IEEEdouble, APInt::getAllOnesValue(BitWidth)); + case 80: + return APFloat(x87DoubleExtended, APInt::getAllOnesValue(BitWidth)); + case 128: + if (isIEEE) + return APFloat(IEEEquad, APInt::getAllOnesValue(BitWidth)); + return APFloat(PPCDoubleDouble, APInt::getAllOnesValue(BitWidth)); + default: + llvm_unreachable("Unknown floating bit width"); + } } APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) { @@ -3244,16 +3260,16 @@ APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) { return Val; } -APFloat::APFloat(const APInt& api, bool isIEEE) { - initFromAPInt(api, isIEEE); +APFloat::APFloat(const fltSemantics &Sem, const APInt &API) { + initFromAPInt(&Sem, API); } APFloat::APFloat(float f) { - initFromAPInt(APInt::floatToBits(f)); + initFromAPInt(&IEEEsingle, APInt::floatToBits(f)); } APFloat::APFloat(double d) { - initFromAPInt(APInt::doubleToBits(d)); + initFromAPInt(&IEEEdouble, APInt::doubleToBits(d)); } namespace { -- cgit v1.2.3-18-g5258 From bd7561ea29649625775ef814dded2856d91c4dcf Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Fri, 25 Jan 2013 17:01:00 +0000 Subject: APFloat: Make sure that we get a well-formed x87 NaN when converting from a smaller type. Fixes PR15054. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173459 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Support/APFloat.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'lib/Support/APFloat.cpp') diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp index 686f91b087..5b68fbb270 100644 --- a/lib/Support/APFloat.cpp +++ b/lib/Support/APFloat.cpp @@ -1913,6 +1913,12 @@ APFloat::convert(const fltSemantics &toSemantics, *losesInfo = (fs != opOK); } else if (category == fcNaN) { *losesInfo = lostFraction != lfExactlyZero || X86SpecialNan; + + // For x87 extended precision, we want to make a NaN, not a special NaN if + // the input wasn't special either. + if (!X86SpecialNan && semantics == &APFloat::x87DoubleExtended) + APInt::tcSetBit(significandParts(), semantics->precision - 1); + // gcc forces the Quiet bit on, which means (float)(double)(float_sNan) // does not give you back the same bits. This is dubious, and we // don't currently do it. You're really supposed to get -- cgit v1.2.3-18-g5258