#include "llvm/ADT/APFloat.h"
#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"
#include <cstring>
#include <limits.h>
using namespace llvm;
#define PackCategoriesIntoKey(_lhs, _rhs) ((_lhs) * 4 + (_rhs))
static_assert(integerPartWidth % 4 == 0, "Part width must be divisible by 4!");
namespace llvm {
struct fltSemantics {
APFloat::ExponentType maxExponent;
APFloat::ExponentType minExponent;
unsigned int precision;
};
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 };
const fltSemantics APFloat::PPCDoubleDouble = { 1023, -1022 + 53, 53 + 53 };
const unsigned int maxExponent = 16383;
const unsigned int maxPrecision = 113;
const unsigned int maxPowerOfFiveExponent = maxExponent + maxPrecision - 1;
const unsigned int maxPowerOfFiveParts = 2 + ((maxPowerOfFiveExponent * 815)
/ (351 * integerPartWidth));
}
static inline unsigned int
partCountForBits(unsigned int bits)
{
return ((bits) + integerPartWidth - 1) / integerPartWidth;
}
static inline unsigned int
decDigitValue(unsigned int c)
{
return c - '0';
}
static int
readExponent(StringRef::iterator begin, StringRef::iterator end)
{
bool isNegative;
unsigned int absExponent;
const unsigned int overlargeExponent = 24000;
StringRef::iterator p = begin;
assert(p != end && "Exponent has no digits");
isNegative = (*p == '-');
if (*p == '-' || *p == '+') {
p++;
assert(p != end && "Exponent has no digits");
}
absExponent = decDigitValue(*p++);
assert(absExponent < 10U && "Invalid character in exponent");
for (; p != end; ++p) {
unsigned int value;
value = decDigitValue(*p);
assert(value < 10U && "Invalid character in exponent");
value += absExponent * 10;
if (absExponent >= overlargeExponent) {
absExponent = overlargeExponent;
p = end;
break;
}
absExponent = value;
}
assert(p == end && "Invalid exponent in exponent");
if (isNegative)
return -(int) absExponent;
else
return (int) absExponent;
}
static int
totalExponent(StringRef::iterator p, StringRef::iterator end,
int exponentAdjustment)
{
int unsignedExponent;
bool negative, overflow;
int exponent = 0;
assert(p != end && "Exponent has no digits");
negative = *p == '-';
if (*p == '-' || *p == '+') {
p++;
assert(p != end && "Exponent has no digits");
}
unsignedExponent = 0;
overflow = false;
for (; p != end; ++p) {
unsigned int value;
value = decDigitValue(*p);
assert(value < 10U && "Invalid character in exponent");
unsignedExponent = unsignedExponent * 10 + value;
if (unsignedExponent > 32767) {
overflow = true;
break;
}
}
if (exponentAdjustment > 32767 || exponentAdjustment < -32768)
overflow = true;
if (!overflow) {
exponent = unsignedExponent;
if (negative)
exponent = -exponent;
exponent += exponentAdjustment;
if (exponent > 32767 || exponent < -32768)
overflow = true;
}
if (overflow)
exponent = negative ? -32768: 32767;
return exponent;
}
static StringRef::iterator
skipLeadingZeroesAndAnyDot(StringRef::iterator begin, StringRef::iterator end,
StringRef::iterator *dot)
{
StringRef::iterator p = begin;
*dot = end;
while (p != end && *p == '0')
p++;
if (p != end && *p == '.') {
*dot = p++;
assert(end - begin != 1 && "Significand has no digits");
while (p != end && *p == '0')
p++;
}
return p;
}
struct decimalInfo {
const char *firstSigDigit;
const char *lastSigDigit;
int exponent;
int normalizedExponent;
};
static void
interpretDecimal(StringRef::iterator begin, StringRef::iterator end,
decimalInfo *D)
{
StringRef::iterator dot = end;
StringRef::iterator p = skipLeadingZeroesAndAnyDot (begin, end, &dot);
D->firstSigDigit = p;
D->exponent = 0;
D->normalizedExponent = 0;
for (; p != end; ++p) {
if (*p == '.') {
assert(dot == end && "String contains multiple dots");
dot = p++;
if (p == end)
break;
}
if (decDigitValue(*p) >= 10U)
break;
}
if (p != end) {
assert((*p == 'e' || *p == 'E') && "Invalid character in significand");
assert(p != begin && "Significand has no digits");
assert((dot == end || p - begin != 1) && "Significand has no digits");
D->exponent = readExponent(p + 1, end);
if (dot == end)
dot = p;
}
if (p != D->firstSigDigit) {
if (p != begin) {
do
do
p--;
while (p != begin && *p == '0');
while (p != begin && *p == '.');
}
D->exponent += static_cast<APFloat::ExponentType>((dot - p) - (dot > p));
D->normalizedExponent = (D->exponent +
static_cast<APFloat::ExponentType>((p - D->firstSigDigit)
- (dot > D->firstSigDigit && dot < p)));
}
D->lastSigDigit = p;
}
static lostFraction
trailingHexadecimalFraction(StringRef::iterator p, StringRef::iterator end,
unsigned int digitValue)
{
unsigned int hexDigit;
if (digitValue > 8)
return lfMoreThanHalf;
else if (digitValue < 8 && digitValue > 0)
return lfLessThanHalf;
while (p != end && (*p == '0' || *p == '.'))
p++;
assert(p != end && "Invalid trailing hexadecimal fraction!");
hexDigit = hexDigitValue(*p);
if (hexDigit == -1U)
return digitValue == 0 ? lfExactlyZero: lfExactlyHalf;
else
return digitValue == 0 ? lfLessThanHalf: lfMoreThanHalf;
}
static lostFraction
lostFractionThroughTruncation(const integerPart *parts,
unsigned int partCount,
unsigned int bits)
{
unsigned int lsb;
lsb = APInt::tcLSB(parts, partCount);
if (bits <= lsb)
return lfExactlyZero;
if (bits == lsb + 1)
return lfExactlyHalf;
if (bits <= partCount * integerPartWidth &&
APInt::tcExtractBit(parts, bits - 1))
return lfMoreThanHalf;
return lfLessThanHalf;
}
static lostFraction
shiftRight(integerPart *dst, unsigned int parts, unsigned int bits)
{
lostFraction lost_fraction;
lost_fraction = lostFractionThroughTruncation(dst, parts, bits);
APInt::tcShiftRight(dst, parts, bits);
return lost_fraction;
}
static lostFraction
combineLostFractions(lostFraction moreSignificant,
lostFraction lessSignificant)
{
if (lessSignificant != lfExactlyZero) {
if (moreSignificant == lfExactlyZero)
moreSignificant = lfLessThanHalf;
else if (moreSignificant == lfExactlyHalf)
moreSignificant = lfMoreThanHalf;
}
return moreSignificant;
}
static unsigned int
HUerrBound(bool inexactMultiply, unsigned int HUerr1, unsigned int HUerr2)
{
assert(HUerr1 < 2 || HUerr2 < 2 || (HUerr1 + HUerr2 < 8));
if (HUerr1 + HUerr2 == 0)
return inexactMultiply * 2;
else
return inexactMultiply + 2 * (HUerr1 + HUerr2);
}
static integerPart
ulpsFromBoundary(const integerPart *parts, unsigned int bits, bool isNearest)
{
unsigned int count, partBits;
integerPart part, boundary;
assert(bits != 0);
bits--;
count = bits / integerPartWidth;
partBits = bits % integerPartWidth + 1;
part = parts[count] & (~(integerPart) 0 >> (integerPartWidth - partBits));
if (isNearest)
boundary = (integerPart) 1 << (partBits - 1);
else
boundary = 0;
if (count == 0) {
if (part - boundary <= boundary - part)
return part - boundary;
else
return boundary - part;
}
if (part == boundary) {
while (--count)
if (parts[count])
return ~(integerPart) 0;
return parts[0];
} else if (part == boundary - 1) {
while (--count)
if (~parts[count])
return ~(integerPart) 0;
return -parts[0];
}
return ~(integerPart) 0;
}
static unsigned int
powerOf5(integerPart *dst, unsigned int power)
{
static const integerPart firstEightPowers[] = { 1, 5, 25, 125, 625, 3125,
15625, 78125 };
integerPart pow5s[maxPowerOfFiveParts * 2 + 5];
pow5s[0] = 78125 * 5;
unsigned int partsCount[16] = { 1 };
integerPart scratch[maxPowerOfFiveParts], *p1, *p2, *pow5;
unsigned int result;
assert(power <= maxExponent);
p1 = dst;
p2 = scratch;
*p1 = firstEightPowers[power & 7];
power >>= 3;
result = 1;
pow5 = pow5s;
for (unsigned int n = 0; power; power >>= 1, n++) {
unsigned int pc;
pc = partsCount[n];
if (pc == 0) {
pc = partsCount[n - 1];
APInt::tcFullMultiply(pow5, pow5 - pc, pow5 - pc, pc, pc);
pc *= 2;
if (pow5[pc - 1] == 0)
pc--;
partsCount[n] = pc;
}
if (power & 1) {
integerPart *tmp;
APInt::tcFullMultiply(p2, p1, pow5, result, pc);
result += pc;
if (p2[result - 1] == 0)
result--;
tmp = p1, p1 = p2, p2 = tmp;
}
pow5 += pc;
}
if (p1 != dst)
APInt::tcAssign(dst, p1, result);
return result;
}
static const char hexDigitsLower[] = "0123456789abcdef0";
static const char hexDigitsUpper[] = "0123456789ABCDEF0";
static const char infinityL[] = "infinity";
static const char infinityU[] = "INFINITY";
static const char NaNL[] = "nan";
static const char NaNU[] = "NAN";
static unsigned int
partAsHex (char *dst, integerPart part, unsigned int count,
const char *hexDigitChars)
{
unsigned int result = count;
assert(count != 0 && count <= integerPartWidth / 4);
part >>= (integerPartWidth - 4 * count);
while (count--) {
dst[count] = hexDigitChars[part & 0xf];
part >>= 4;
}
return result;
}
static char *
writeUnsignedDecimal (char *dst, unsigned int n)
{
char buff[40], *p;
p = buff;
do
*p++ = '0' + n % 10;
while (n /= 10);
do
*dst++ = *--p;
while (p != buff);
return dst;
}
static char *
writeSignedDecimal (char *dst, int value)
{
if (value < 0) {
*dst++ = '-';
dst = writeUnsignedDecimal(dst, -(unsigned) value);
} else
dst = writeUnsignedDecimal(dst, value);
return dst;
}
void
APFloat::initialize(const fltSemantics *ourSemantics)
{
unsigned int count;
semantics = ourSemantics;
count = partCount();
if (count > 1)
significand.parts = new integerPart[count];
}
void
APFloat::freeSignificand()
{
if (needsCleanup())
delete [] significand.parts;
}
void
APFloat::assign(const APFloat &rhs)
{
assert(semantics == rhs.semantics);
sign = rhs.sign;
category = rhs.category;
exponent = rhs.exponent;
if (isFiniteNonZero() || category == fcNaN)
copySignificand(rhs);
}
void
APFloat::copySignificand(const APFloat &rhs)
{
assert(isFiniteNonZero() || category == fcNaN);
assert(rhs.partCount() >= partCount());
APInt::tcAssign(significandParts(), rhs.significandParts(),
partCount());
}
void APFloat::makeNaN(bool SNaN, bool Negative, const APInt *fill)
{
category = fcNaN;
sign = Negative;
integerPart *significand = significandParts();
unsigned numParts = partCount();
if (!fill || fill->getNumWords() < numParts)
APInt::tcSet(significand, 0, numParts);
if (fill) {
APInt::tcAssign(significand, fill->getRawData(),
std::min(fill->getNumWords(), numParts));
unsigned bitsToPreserve = semantics->precision - 1;
unsigned part = bitsToPreserve / 64;
bitsToPreserve %= 64;
significand[part] &= ((1ULL << bitsToPreserve) - 1);
for (part++; part != numParts; ++part)
significand[part] = 0;
}
unsigned QNaNBit = semantics->precision - 2;
if (SNaN) {
APInt::tcClearBit(significand, QNaNBit);
if (APInt::tcIsZero(significand, numParts))
APInt::tcSetBit(significand, QNaNBit - 1);
} else {
APInt::tcSetBit(significand, QNaNBit);
}
if (semantics == &APFloat::x87DoubleExtended)
APInt::tcSetBit(significand, QNaNBit + 1);
}
APFloat APFloat::makeNaN(const fltSemantics &Sem, bool SNaN, bool Negative,
const APInt *fill) {
APFloat value(Sem, uninitialized);
value.makeNaN(SNaN, Negative, fill);
return value;
}
APFloat &
APFloat::operator=(const APFloat &rhs)
{
if (this != &rhs) {
if (semantics != rhs.semantics) {
freeSignificand();
initialize(rhs.semantics);
}
assign(rhs);
}
return *this;
}
APFloat &
APFloat::operator=(APFloat &&rhs) {
freeSignificand();
semantics = rhs.semantics;
significand = rhs.significand;
exponent = rhs.exponent;
category = rhs.category;
sign = rhs.sign;
rhs.semantics = &Bogus;
return *this;
}
bool
APFloat::isDenormal() const {
return isFiniteNonZero() && (exponent == semantics->minExponent) &&
(APInt::tcExtractBit(significandParts(),
semantics->precision - 1) == 0);
}
bool
APFloat::isSmallest() const {
return isFiniteNonZero() && exponent == semantics->minExponent &&
significandMSB() == 0;
}
bool APFloat::isSignificandAllOnes() const {
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 "
"fill than integerPartWidth");
const integerPart HighBitFill =
~integerPart(0) << (integerPartWidth - NumHighBits);
if (~(Parts[PartCount - 1] | HighBitFill))
return false;
return true;
}
bool APFloat::isSignificandAllZeros() const {
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 {
return isFiniteNonZero() && exponent == semantics->maxExponent
&& isSignificandAllOnes();
}
bool
APFloat::bitwiseIsEqual(const APFloat &rhs) const {
if (this == &rhs)
return true;
if (semantics != rhs.semantics ||
category != rhs.category ||
sign != rhs.sign)
return false;
if (category==fcZero || category==fcInfinity)
return true;
else if (isFiniteNonZero() && exponent!=rhs.exponent)
return false;
else {
int i= partCount();
const integerPart* p=significandParts();
const integerPart* q=rhs.significandParts();
for (; i>0; i--, p++, q++) {
if (*p != *q)
return false;
}
return true;
}
}
APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value) {
initialize(&ourSemantics);
sign = 0;
category = fcNormal;
zeroSignificand();
exponent = ourSemantics.precision - 1;
significandParts()[0] = value;
normalize(rmNearestTiesToEven, lfExactlyZero);
}
APFloat::APFloat(const fltSemantics &ourSemantics) {
initialize(&ourSemantics);
category = fcZero;
sign = false;
}
APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) {
initialize(&ourSemantics);
}
APFloat::APFloat(const fltSemantics &ourSemantics, StringRef text) {
initialize(&ourSemantics);
convertFromString(text, rmNearestTiesToEven);
}
APFloat::APFloat(const APFloat &rhs) {
initialize(rhs.semantics);
assign(rhs);
}
APFloat::APFloat(APFloat &&rhs) : semantics(&Bogus) {
*this = std::move(rhs);
}
APFloat::~APFloat()
{
freeSignificand();
}
void APFloat::Profile(FoldingSetNodeID& ID) const {
ID.Add(bitcastToAPInt());
}
unsigned int
APFloat::partCount() const
{
return partCountForBits(semantics->precision + 1);
}
unsigned int
APFloat::semanticsPrecision(const fltSemantics &semantics)
{
return semantics.precision;
}
const integerPart *
APFloat::significandParts() const
{
return const_cast<APFloat *>(this)->significandParts();
}
integerPart *
APFloat::significandParts()
{
if (partCount() > 1)
return significand.parts;
else
return &significand.part;
}
void
APFloat::zeroSignificand()
{
APInt::tcSet(significandParts(), 0, partCount());
}
void
APFloat::incrementSignificand()
{
integerPart carry;
carry = APInt::tcIncrement(significandParts(), partCount());
assert(carry == 0);
(void)carry;
}
integerPart
APFloat::addSignificand(const APFloat &rhs)
{
integerPart *parts;
parts = significandParts();
assert(semantics == rhs.semantics);
assert(exponent == rhs.exponent);
return APInt::tcAdd(parts, rhs.significandParts(), 0, partCount());
}
integerPart
APFloat::subtractSignificand(const APFloat &rhs, integerPart borrow)
{
integerPart *parts;
parts = significandParts();
assert(semantics == rhs.semantics);
assert(exponent == rhs.exponent);
return APInt::tcSubtract(parts, rhs.significandParts(), borrow,
partCount());
}
lostFraction
APFloat::multiplySignificand(const APFloat &rhs, const APFloat *addend)
{
unsigned int omsb; unsigned int partsCount, newPartsCount, precision;
integerPart *lhsSignificand;
integerPart scratch[4];
integerPart *fullSignificand;
lostFraction lost_fraction;
bool ignored;
assert(semantics == rhs.semantics);
precision = semantics->precision;
newPartsCount = partCountForBits(precision * 2 + 1);
if (newPartsCount > 4)
fullSignificand = new integerPart[newPartsCount];
else
fullSignificand = scratch;
lhsSignificand = significandParts();
partsCount = partCount();
APInt::tcFullMultiply(fullSignificand, lhsSignificand,
rhs.significandParts(), partsCount, partsCount);
lost_fraction = lfExactlyZero;
omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1;
exponent += rhs.exponent;
exponent += 2;
if (addend && addend->isNonZero()) {
Significand savedSignificand = significand;
const fltSemantics *savedSemantics = semantics;
fltSemantics extendedSemantics;
opStatus status;
unsigned int extendedPrecision;
extendedPrecision = 2 * precision + 1;
if (omsb != extendedPrecision - 1) {
assert(extendedPrecision > omsb);
APInt::tcShiftLeft(fullSignificand, newPartsCount,
(extendedPrecision - 1) - omsb);
exponent -= (extendedPrecision - 1) - omsb;
}
extendedSemantics = *semantics;
extendedSemantics.precision = extendedPrecision;
if (newPartsCount == 1)
significand.part = fullSignificand[0];
else
significand.parts = fullSignificand;
semantics = &extendedSemantics;
APFloat extendedAddend(*addend);
status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored);
assert(status == opOK);
(void)status;
lost_fraction = extendedAddend.shiftSignificandRight(1);
assert(lost_fraction == lfExactlyZero &&
"Lost precision while shifting addend for fused-multiply-add.");
lost_fraction = addOrSubtractSignificand(extendedAddend, false);
if (newPartsCount == 1)
fullSignificand[0] = significand.part;
significand = savedSignificand;
semantics = savedSemantics;
omsb = APInt::tcMSB(fullSignificand, newPartsCount) + 1;
}
exponent -= precision + 1;
if (omsb > precision) {
unsigned int bits, significantParts;
lostFraction lf;
bits = omsb - precision;
significantParts = partCountForBits(omsb);
lf = shiftRight(fullSignificand, significantParts, bits);
lost_fraction = combineLostFractions(lf, lost_fraction);
exponent += bits;
}
APInt::tcAssign(lhsSignificand, fullSignificand, partsCount);
if (newPartsCount > 4)
delete [] fullSignificand;
return lost_fraction;
}
lostFraction
APFloat::divideSignificand(const APFloat &rhs)
{
unsigned int bit, i, partsCount;
const integerPart *rhsSignificand;
integerPart *lhsSignificand, *dividend, *divisor;
integerPart scratch[4];
lostFraction lost_fraction;
assert(semantics == rhs.semantics);
lhsSignificand = significandParts();
rhsSignificand = rhs.significandParts();
partsCount = partCount();
if (partsCount > 2)
dividend = new integerPart[partsCount * 2];
else
dividend = scratch;
divisor = dividend + partsCount;
for (i = 0; i < partsCount; i++) {
dividend[i] = lhsSignificand[i];
divisor[i] = rhsSignificand[i];
lhsSignificand[i] = 0;
}
exponent -= rhs.exponent;
unsigned int precision = semantics->precision;
bit = precision - APInt::tcMSB(divisor, partsCount) - 1;
if (bit) {
exponent += bit;
APInt::tcShiftLeft(divisor, partsCount, bit);
}
bit = precision - APInt::tcMSB(dividend, partsCount) - 1;
if (bit) {
exponent -= bit;
APInt::tcShiftLeft(dividend, partsCount, bit);
}
if (APInt::tcCompare(dividend, divisor, partsCount) < 0) {
exponent--;
APInt::tcShiftLeft(dividend, partsCount, 1);
assert(APInt::tcCompare(dividend, divisor, partsCount) >= 0);
}
for (bit = precision; bit; bit -= 1) {
if (APInt::tcCompare(dividend, divisor, partsCount) >= 0) {
APInt::tcSubtract(dividend, divisor, 0, partsCount);
APInt::tcSetBit(lhsSignificand, bit - 1);
}
APInt::tcShiftLeft(dividend, partsCount, 1);
}
int cmp = APInt::tcCompare(dividend, divisor, partsCount);
if (cmp > 0)
lost_fraction = lfMoreThanHalf;
else if (cmp == 0)
lost_fraction = lfExactlyHalf;
else if (APInt::tcIsZero(dividend, partsCount))
lost_fraction = lfExactlyZero;
else
lost_fraction = lfLessThanHalf;
if (partsCount > 2)
delete [] dividend;
return lost_fraction;
}
unsigned int
APFloat::significandMSB() const
{
return APInt::tcMSB(significandParts(), partCount());
}
unsigned int
APFloat::significandLSB() const
{
return APInt::tcLSB(significandParts(), partCount());
}
lostFraction
APFloat::shiftSignificandRight(unsigned int bits)
{
assert((ExponentType) (exponent + bits) >= exponent);
exponent += bits;
return shiftRight(significandParts(), partCount(), bits);
}
void
APFloat::shiftSignificandLeft(unsigned int bits)
{
assert(bits < semantics->precision);
if (bits) {
unsigned int partsCount = partCount();
APInt::tcShiftLeft(significandParts(), partsCount, bits);
exponent -= bits;
assert(!APInt::tcIsZero(significandParts(), partsCount));
}
}
APFloat::cmpResult
APFloat::compareAbsoluteValue(const APFloat &rhs) const
{
int compare;
assert(semantics == rhs.semantics);
assert(isFiniteNonZero());
assert(rhs.isFiniteNonZero());
compare = exponent - rhs.exponent;
if (compare == 0)
compare = APInt::tcCompare(significandParts(), rhs.significandParts(),
partCount());
if (compare > 0)
return cmpGreaterThan;
else if (compare < 0)
return cmpLessThan;
else
return cmpEqual;
}
APFloat::opStatus
APFloat::handleOverflow(roundingMode rounding_mode)
{
if (rounding_mode == rmNearestTiesToEven ||
rounding_mode == rmNearestTiesToAway ||
(rounding_mode == rmTowardPositive && !sign) ||
(rounding_mode == rmTowardNegative && sign)) {
category = fcInfinity;
return (opStatus) (opOverflow | opInexact);
}
category = fcNormal;
exponent = semantics->maxExponent;
APInt::tcSetLeastSignificantBits(significandParts(), partCount(),
semantics->precision);
return opInexact;
}
bool
APFloat::roundAwayFromZero(roundingMode rounding_mode,
lostFraction lost_fraction,
unsigned int bit) const
{
assert(isFiniteNonZero() || category == fcZero);
assert(lost_fraction != lfExactlyZero);
switch (rounding_mode) {
case rmNearestTiesToAway:
return lost_fraction == lfExactlyHalf || lost_fraction == lfMoreThanHalf;
case rmNearestTiesToEven:
if (lost_fraction == lfMoreThanHalf)
return true;
if (lost_fraction == lfExactlyHalf && category != fcZero)
return APInt::tcExtractBit(significandParts(), bit);
return false;
case rmTowardZero:
return false;
case rmTowardPositive:
return sign == false;
case rmTowardNegative:
return sign == true;
}
llvm_unreachable("Invalid rounding mode found");
}
APFloat::opStatus
APFloat::normalize(roundingMode rounding_mode,
lostFraction lost_fraction)
{
unsigned int omsb;
int exponentChange;
if (!isFiniteNonZero())
return opOK;
omsb = significandMSB() + 1;
if (omsb) {
exponentChange = omsb - semantics->precision;
if (exponent + exponentChange > semantics->maxExponent)
return handleOverflow(rounding_mode);
if (exponent + exponentChange < semantics->minExponent)
exponentChange = semantics->minExponent - exponent;
if (exponentChange < 0) {
assert(lost_fraction == lfExactlyZero);
shiftSignificandLeft(-exponentChange);
return opOK;
}
if (exponentChange > 0) {
lostFraction lf;
lf = shiftSignificandRight(exponentChange);
lost_fraction = combineLostFractions(lf, lost_fraction);
if (omsb > (unsigned) exponentChange)
omsb -= exponentChange;
else
omsb = 0;
}
}
if (lost_fraction == lfExactlyZero) {
if (omsb == 0)
category = fcZero;
return opOK;
}
if (roundAwayFromZero(rounding_mode, lost_fraction, 0)) {
if (omsb == 0)
exponent = semantics->minExponent;
incrementSignificand();
omsb = significandMSB() + 1;
if (omsb == (unsigned) semantics->precision + 1) {
if (exponent == semantics->maxExponent) {
category = fcInfinity;
return (opStatus) (opOverflow | opInexact);
}
shiftSignificandRight(1);
return opInexact;
}
}
if (omsb == semantics->precision)
return opInexact;
assert(omsb < semantics->precision);
if (omsb == 0)
category = fcZero;
return (opStatus) (opUnderflow | opInexact);
}
APFloat::opStatus
APFloat::addOrSubtractSpecials(const APFloat &rhs, bool subtract)
{
switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
llvm_unreachable(nullptr);
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 PackCategoriesIntoKey(fcZero, fcNaN):
case PackCategoriesIntoKey(fcNormal, fcNaN):
case PackCategoriesIntoKey(fcInfinity, fcNaN):
sign = rhs.sign ^ subtract;
category = fcNaN;
copySignificand(rhs);
return opOK;
case PackCategoriesIntoKey(fcNormal, fcInfinity):
case PackCategoriesIntoKey(fcZero, fcInfinity):
category = fcInfinity;
sign = rhs.sign ^ subtract;
return opOK;
case PackCategoriesIntoKey(fcZero, fcNormal):
assign(rhs);
sign = rhs.sign ^ subtract;
return opOK;
case PackCategoriesIntoKey(fcZero, fcZero):
return opOK;
case PackCategoriesIntoKey(fcInfinity, fcInfinity):
if (((sign ^ rhs.sign)!=0) != subtract) {
makeNaN();
return opInvalidOp;
}
return opOK;
case PackCategoriesIntoKey(fcNormal, fcNormal):
return opDivByZero;
}
}
lostFraction
APFloat::addOrSubtractSignificand(const APFloat &rhs, bool subtract)
{
integerPart carry;
lostFraction lost_fraction;
int bits;
subtract ^= (sign ^ rhs.sign) ? true : false;
bits = exponent - rhs.exponent;
if (subtract) {
APFloat temp_rhs(rhs);
bool reverse;
if (bits == 0) {
reverse = compareAbsoluteValue(temp_rhs) == cmpLessThan;
lost_fraction = lfExactlyZero;
} else if (bits > 0) {
lost_fraction = temp_rhs.shiftSignificandRight(bits - 1);
shiftSignificandLeft(1);
reverse = false;
} else {
lost_fraction = shiftSignificandRight(-bits - 1);
temp_rhs.shiftSignificandLeft(1);
reverse = true;
}
if (reverse) {
carry = temp_rhs.subtractSignificand
(*this, lost_fraction != lfExactlyZero);
copySignificand(temp_rhs);
sign = !sign;
} else {
carry = subtractSignificand
(temp_rhs, lost_fraction != lfExactlyZero);
}
if (lost_fraction == lfLessThanHalf)
lost_fraction = lfMoreThanHalf;
else if (lost_fraction == lfMoreThanHalf)
lost_fraction = lfLessThanHalf;
assert(!carry);
(void)carry;
} else {
if (bits > 0) {
APFloat temp_rhs(rhs);
lost_fraction = temp_rhs.shiftSignificandRight(bits);
carry = addSignificand(temp_rhs);
} else {
lost_fraction = shiftSignificandRight(-bits);
carry = addSignificand(rhs);
}
assert(!carry);
(void)carry;
}
return lost_fraction;
}
APFloat::opStatus
APFloat::multiplySpecials(const APFloat &rhs)
{
switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
llvm_unreachable(nullptr);
case PackCategoriesIntoKey(fcNaN, fcZero):
case PackCategoriesIntoKey(fcNaN, fcNormal):
case PackCategoriesIntoKey(fcNaN, fcInfinity):
case PackCategoriesIntoKey(fcNaN, fcNaN):
sign = false;
return opOK;
case PackCategoriesIntoKey(fcZero, fcNaN):
case PackCategoriesIntoKey(fcNormal, fcNaN):
case PackCategoriesIntoKey(fcInfinity, fcNaN):
sign = false;
category = fcNaN;
copySignificand(rhs);
return opOK;
case PackCategoriesIntoKey(fcNormal, fcInfinity):
case PackCategoriesIntoKey(fcInfinity, fcNormal):
case PackCategoriesIntoKey(fcInfinity, fcInfinity):
category = fcInfinity;
return opOK;
case PackCategoriesIntoKey(fcZero, fcNormal):
case PackCategoriesIntoKey(fcNormal, fcZero):
case PackCategoriesIntoKey(fcZero, fcZero):
category = fcZero;
return opOK;
case PackCategoriesIntoKey(fcZero, fcInfinity):
case PackCategoriesIntoKey(fcInfinity, fcZero):
makeNaN();
return opInvalidOp;
case PackCategoriesIntoKey(fcNormal, fcNormal):
return opOK;
}
}
APFloat::opStatus
APFloat::divideSpecials(const APFloat &rhs)
{
switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
llvm_unreachable(nullptr);
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 PackCategoriesIntoKey(fcNormal, fcInfinity):
category = fcZero;
return opOK;
case PackCategoriesIntoKey(fcNormal, fcZero):
category = fcInfinity;
return opDivByZero;
case PackCategoriesIntoKey(fcInfinity, fcInfinity):
case PackCategoriesIntoKey(fcZero, fcZero):
makeNaN();
return opInvalidOp;
case PackCategoriesIntoKey(fcNormal, fcNormal):
return opOK;
}
}
APFloat::opStatus
APFloat::modSpecials(const APFloat &rhs)
{
switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
llvm_unreachable(nullptr);
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 PackCategoriesIntoKey(fcZero, fcNaN):
case PackCategoriesIntoKey(fcNormal, fcNaN):
case PackCategoriesIntoKey(fcInfinity, fcNaN):
sign = false;
category = fcNaN;
copySignificand(rhs);
return opOK;
case PackCategoriesIntoKey(fcNormal, fcZero):
case PackCategoriesIntoKey(fcInfinity, fcZero):
case PackCategoriesIntoKey(fcInfinity, fcNormal):
case PackCategoriesIntoKey(fcInfinity, fcInfinity):
case PackCategoriesIntoKey(fcZero, fcZero):
makeNaN();
return opInvalidOp;
case PackCategoriesIntoKey(fcNormal, fcNormal):
return opOK;
}
}
void
APFloat::changeSign()
{
sign = !sign;
}
void
APFloat::clearSign()
{
sign = 0;
}
void
APFloat::copySign(const APFloat &rhs)
{
sign = rhs.sign;
}
APFloat::opStatus
APFloat::addOrSubtract(const APFloat &rhs, roundingMode rounding_mode,
bool subtract)
{
opStatus fs;
fs = addOrSubtractSpecials(rhs, subtract);
if (fs == opDivByZero) {
lostFraction lost_fraction;
lost_fraction = addOrSubtractSignificand(rhs, subtract);
fs = normalize(rounding_mode, lost_fraction);
assert(category != fcZero || lost_fraction == lfExactlyZero);
}
if (category == fcZero) {
if (rhs.category != fcZero || (sign == rhs.sign) == subtract)
sign = (rounding_mode == rmTowardNegative);
}
return fs;
}
APFloat::opStatus
APFloat::add(const APFloat &rhs, roundingMode rounding_mode)
{
return addOrSubtract(rhs, rounding_mode, false);
}
APFloat::opStatus
APFloat::subtract(const APFloat &rhs, roundingMode rounding_mode)
{
return addOrSubtract(rhs, rounding_mode, true);
}
APFloat::opStatus
APFloat::multiply(const APFloat &rhs, roundingMode rounding_mode)
{
opStatus fs;
sign ^= rhs.sign;
fs = multiplySpecials(rhs);
if (isFiniteNonZero()) {
lostFraction lost_fraction = multiplySignificand(rhs, nullptr);
fs = normalize(rounding_mode, lost_fraction);
if (lost_fraction != lfExactlyZero)
fs = (opStatus) (fs | opInexact);
}
return fs;
}
APFloat::opStatus
APFloat::divide(const APFloat &rhs, roundingMode rounding_mode)
{
opStatus fs;
sign ^= rhs.sign;
fs = divideSpecials(rhs);
if (isFiniteNonZero()) {
lostFraction lost_fraction = divideSignificand(rhs);
fs = normalize(rounding_mode, lost_fraction);
if (lost_fraction != lfExactlyZero)
fs = (opStatus) (fs | opInexact);
}
return fs;
}
APFloat::opStatus
APFloat::remainder(const APFloat &rhs)
{
opStatus fs;
APFloat V = *this;
unsigned int origSign = sign;
fs = V.divide(rhs, rmNearestTiesToEven);
if (fs == opDivByZero)
return fs;
int parts = partCount();
integerPart *x = new integerPart[parts];
bool ignored;
fs = V.convertToInteger(x, parts * integerPartWidth, true,
rmNearestTiesToEven, &ignored);
if (fs==opInvalidOp)
return fs;
fs = V.convertFromZeroExtendedInteger(x, parts * integerPartWidth, true,
rmNearestTiesToEven);
assert(fs==opOK);
fs = V.multiply(rhs, rmNearestTiesToEven);
assert(fs==opOK || fs==opInexact);
fs = subtract(V, rmNearestTiesToEven);
assert(fs==opOK || fs==opInexact);
if (isZero())
sign = origSign; delete[] x;
return fs;
}
APFloat::opStatus
APFloat::mod(const APFloat &rhs, roundingMode rounding_mode)
{
opStatus fs;
fs = modSpecials(rhs);
if (isFiniteNonZero() && rhs.isFiniteNonZero()) {
APFloat V = *this;
unsigned int origSign = sign;
fs = V.divide(rhs, rmNearestTiesToEven);
if (fs == opDivByZero)
return fs;
int parts = partCount();
integerPart *x = new integerPart[parts];
bool ignored;
fs = V.convertToInteger(x, parts * integerPartWidth, true,
rmTowardZero, &ignored);
if (fs==opInvalidOp)
return fs;
fs = V.convertFromZeroExtendedInteger(x, parts * integerPartWidth, true,
rmNearestTiesToEven);
assert(fs==opOK);
fs = V.multiply(rhs, rounding_mode);
assert(fs==opOK || fs==opInexact);
fs = subtract(V, rounding_mode);
assert(fs==opOK || fs==opInexact);
if (isZero())
sign = origSign; delete[] x;
}
return fs;
}
APFloat::opStatus
APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
const APFloat &addend,
roundingMode rounding_mode)
{
opStatus fs;
sign ^= multiplicand.sign;
if (isFiniteNonZero() &&
multiplicand.isFiniteNonZero() &&
addend.isFinite()) {
lostFraction lost_fraction;
lost_fraction = multiplySignificand(multiplicand, &addend);
fs = normalize(rounding_mode, lost_fraction);
if (lost_fraction != lfExactlyZero)
fs = (opStatus) (fs | opInexact);
if (category == fcZero && !(fs & opUnderflow) && sign != addend.sign)
sign = (rounding_mode == rmTowardNegative);
} else {
fs = multiplySpecials(multiplicand);
if (fs == opOK)
fs = addOrSubtract(addend, rounding_mode, false);
}
return fs;
}
APFloat::opStatus APFloat::roundToIntegral(roundingMode rounding_mode) {
opStatus fs;
if (isFiniteNonZero() && exponent+1 >= (int)semanticsPrecision(*semantics))
return opOK;
APInt IntegerConstant(NextPowerOf2(semanticsPrecision(*semantics)), 1);
IntegerConstant <<= semanticsPrecision(*semantics)-1;
APFloat MagicConstant(*semantics);
fs = MagicConstant.convertFromAPInt(IntegerConstant, false,
rmNearestTiesToEven);
MagicConstant.copySign(*this);
if (fs != opOK)
return fs;
bool inputSign = isNegative();
fs = add(MagicConstant, rounding_mode);
if (fs != opOK && fs != opInexact)
return fs;
fs = subtract(MagicConstant, rounding_mode);
if (inputSign != isNegative())
changeSign();
return fs;
}
APFloat::cmpResult
APFloat::compare(const APFloat &rhs) const
{
cmpResult result;
assert(semantics == rhs.semantics);
switch (PackCategoriesIntoKey(category, rhs.category)) {
default:
llvm_unreachable(nullptr);
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 PackCategoriesIntoKey(fcInfinity, fcNormal):
case PackCategoriesIntoKey(fcInfinity, fcZero):
case PackCategoriesIntoKey(fcNormal, fcZero):
if (sign)
return cmpLessThan;
else
return cmpGreaterThan;
case PackCategoriesIntoKey(fcNormal, fcInfinity):
case PackCategoriesIntoKey(fcZero, fcInfinity):
case PackCategoriesIntoKey(fcZero, fcNormal):
if (rhs.sign)
return cmpGreaterThan;
else
return cmpLessThan;
case PackCategoriesIntoKey(fcInfinity, fcInfinity):
if (sign == rhs.sign)
return cmpEqual;
else if (sign)
return cmpLessThan;
else
return cmpGreaterThan;
case PackCategoriesIntoKey(fcZero, fcZero):
return cmpEqual;
case PackCategoriesIntoKey(fcNormal, fcNormal):
break;
}
if (sign != rhs.sign) {
if (sign)
result = cmpLessThan;
else
result = cmpGreaterThan;
} else {
result = compareAbsoluteValue(rhs);
if (sign) {
if (result == cmpLessThan)
result = cmpGreaterThan;
else if (result == cmpGreaterThan)
result = cmpLessThan;
}
}
return result;
}
APFloat::opStatus
APFloat::convert(const fltSemantics &toSemantics,
roundingMode rounding_mode, bool *losesInfo)
{
lostFraction lostFraction;
unsigned int newPartCount, oldPartCount;
opStatus fs;
int shift;
const fltSemantics &fromSemantics = *semantics;
lostFraction = lfExactlyZero;
newPartCount = partCountForBits(toSemantics.precision + 1);
oldPartCount = partCount();
shift = toSemantics.precision - fromSemantics.precision;
bool X86SpecialNan = false;
if (&fromSemantics == &APFloat::x87DoubleExtended &&
&toSemantics != &APFloat::x87DoubleExtended && category == fcNaN &&
(!(*significandParts() & 0x8000000000000000ULL) ||
!(*significandParts() & 0x4000000000000000ULL))) {
X86SpecialNan = true;
}
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 (shift < 0 && (isFiniteNonZero() || category==fcNaN))
lostFraction = shiftRight(significandParts(), oldPartCount, -shift);
if (newPartCount > oldPartCount) {
integerPart *newParts;
newParts = new integerPart[newPartCount];
APInt::tcSet(newParts, 0, newPartCount);
if (isFiniteNonZero() || category==fcNaN)
APInt::tcAssign(newParts, significandParts(), oldPartCount);
freeSignificand();
significand.parts = newParts;
} else if (newPartCount == 1 && oldPartCount != 1) {
integerPart newPart = 0;
if (isFiniteNonZero() || category==fcNaN)
newPart = significandParts()[0];
freeSignificand();
significand.part = newPart;
}
semantics = &toSemantics;
if (shift > 0 && (isFiniteNonZero() || category==fcNaN))
APInt::tcShiftLeft(significandParts(), newPartCount, shift);
if (isFiniteNonZero()) {
fs = normalize(rounding_mode, lostFraction);
*losesInfo = (fs != opOK);
} else if (category == fcNaN) {
*losesInfo = lostFraction != lfExactlyZero || X86SpecialNan;
if (!X86SpecialNan && semantics == &APFloat::x87DoubleExtended)
APInt::tcSetBit(significandParts(), semantics->precision - 1);
fs = opOK;
} else {
*losesInfo = false;
fs = opOK;
}
return fs;
}
APFloat::opStatus
APFloat::convertToSignExtendedInteger(integerPart *parts, unsigned int width,
bool isSigned,
roundingMode rounding_mode,
bool *isExact) const
{
lostFraction lost_fraction;
const integerPart *src;
unsigned int dstPartsCount, truncatedBits;
*isExact = false;
if (category == fcInfinity || category == fcNaN)
return opInvalidOp;
dstPartsCount = partCountForBits(width);
if (category == fcZero) {
APInt::tcSet(parts, 0, dstPartsCount);
*isExact = !sign;
return opOK;
}
src = significandParts();
if (exponent < 0) {
APInt::tcSet(parts, 0, dstPartsCount);
truncatedBits = semantics->precision -1U - exponent;
} else {
unsigned int bits = exponent + 1U;
if (bits > width)
return opInvalidOp;
if (bits < semantics->precision) {
truncatedBits = semantics->precision - bits;
APInt::tcExtract(parts, dstPartsCount, src, bits, truncatedBits);
} else {
APInt::tcExtract(parts, dstPartsCount, src, semantics->precision, 0);
APInt::tcShiftLeft(parts, dstPartsCount, bits - semantics->precision);
truncatedBits = 0;
}
}
if (truncatedBits) {
lost_fraction = lostFractionThroughTruncation(src, partCount(),
truncatedBits);
if (lost_fraction != lfExactlyZero &&
roundAwayFromZero(rounding_mode, lost_fraction, truncatedBits)) {
if (APInt::tcIncrement(parts, dstPartsCount))
return opInvalidOp;
}
} else {
lost_fraction = lfExactlyZero;
}
unsigned int omsb = APInt::tcMSB(parts, dstPartsCount) + 1;
if (sign) {
if (!isSigned) {
if (omsb != 0)
return opInvalidOp;
} else {
if (omsb == width && APInt::tcLSB(parts, dstPartsCount) + 1 != omsb)
return opInvalidOp;
if (omsb > width)
return opInvalidOp;
}
APInt::tcNegate (parts, dstPartsCount);
} else {
if (omsb >= width + !isSigned)
return opInvalidOp;
}
if (lost_fraction == lfExactlyZero) {
*isExact = true;
return opOK;
} else
return opInexact;
}
APFloat::opStatus
APFloat::convertToInteger(integerPart *parts, unsigned int width,
bool isSigned,
roundingMode rounding_mode, bool *isExact) const
{
opStatus fs;
fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode,
isExact);
if (fs == opInvalidOp) {
unsigned int bits, dstPartsCount;
dstPartsCount = partCountForBits(width);
if (category == fcNaN)
bits = 0;
else if (sign)
bits = isSigned;
else
bits = width - isSigned;
APInt::tcSetLeastSignificantBits(parts, dstPartsCount, bits);
if (sign && isSigned)
APInt::tcShiftLeft(parts, dstPartsCount, width - 1);
}
return fs;
}
APFloat::opStatus
APFloat::convertToInteger(APSInt &result,
roundingMode rounding_mode, bool *isExact) const
{
unsigned bitWidth = result.getBitWidth();
SmallVector<uint64_t, 4> parts(result.getNumWords());
opStatus status = convertToInteger(
parts.data(), bitWidth, result.isSigned(), rounding_mode, isExact);
result = APInt(bitWidth, parts);
return status;
}
APFloat::opStatus
APFloat::convertFromUnsignedParts(const integerPart *src,
unsigned int srcCount,
roundingMode rounding_mode)
{
unsigned int omsb, precision, dstCount;
integerPart *dst;
lostFraction lost_fraction;
category = fcNormal;
omsb = APInt::tcMSB(src, srcCount) + 1;
dst = significandParts();
dstCount = partCount();
precision = semantics->precision;
if (precision <= omsb) {
exponent = omsb - 1;
lost_fraction = lostFractionThroughTruncation(src, srcCount,
omsb - precision);
APInt::tcExtract(dst, dstCount, src, precision, omsb - precision);
} else {
exponent = precision - 1;
lost_fraction = lfExactlyZero;
APInt::tcExtract(dst, dstCount, src, omsb, 0);
}
return normalize(rounding_mode, lost_fraction);
}
APFloat::opStatus
APFloat::convertFromAPInt(const APInt &Val,
bool isSigned,
roundingMode rounding_mode)
{
unsigned int partCount = Val.getNumWords();
APInt api = Val;
sign = false;
if (isSigned && api.isNegative()) {
sign = true;
api = -api;
}
return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode);
}
APFloat::opStatus
APFloat::convertFromSignExtendedInteger(const integerPart *src,
unsigned int srcCount,
bool isSigned,
roundingMode rounding_mode)
{
opStatus status;
if (isSigned &&
APInt::tcExtractBit(src, srcCount * integerPartWidth - 1)) {
integerPart *copy;
sign = true;
copy = new integerPart[srcCount];
APInt::tcAssign(copy, src, srcCount);
APInt::tcNegate(copy, srcCount);
status = convertFromUnsignedParts(copy, srcCount, rounding_mode);
delete [] copy;
} else {
sign = false;
status = convertFromUnsignedParts(src, srcCount, rounding_mode);
}
return status;
}
APFloat::opStatus
APFloat::convertFromZeroExtendedInteger(const integerPart *parts,
unsigned int width, bool isSigned,
roundingMode rounding_mode)
{
unsigned int partCount = partCountForBits(width);
APInt api = APInt(width, makeArrayRef(parts, partCount));
sign = false;
if (isSigned && APInt::tcExtractBit(parts, width - 1)) {
sign = true;
api = -api;
}
return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode);
}
APFloat::opStatus
APFloat::convertFromHexadecimalString(StringRef s, roundingMode rounding_mode)
{
lostFraction lost_fraction = lfExactlyZero;
category = fcNormal;
zeroSignificand();
exponent = 0;
integerPart *significand = significandParts();
unsigned partsCount = partCount();
unsigned bitPos = partsCount * integerPartWidth;
bool computedTrailingFraction = false;
StringRef::iterator begin = s.begin();
StringRef::iterator end = s.end();
StringRef::iterator dot;
StringRef::iterator p = skipLeadingZeroesAndAnyDot(begin, end, &dot);
StringRef::iterator firstSignificantDigit = p;
while (p != end) {
integerPart hex_value;
if (*p == '.') {
assert(dot == end && "String contains multiple dots");
dot = p++;
continue;
}
hex_value = hexDigitValue(*p);
if (hex_value == -1U)
break;
p++;
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;
}
}
assert(p != end && "Hex strings require an exponent");
assert((*p == 'p' || *p == 'P') && "Invalid character in significand");
assert(p != begin && "Significand has no digits");
assert((dot == end || p - begin != 1) && "Significand has no digits");
if (p != firstSignificantDigit) {
int expAdjustment;
if (dot == end)
dot = p;
expAdjustment = static_cast<int>(dot - firstSignificantDigit);
if (expAdjustment < 0)
expAdjustment++;
expAdjustment = expAdjustment * 4 - 1;
expAdjustment += semantics->precision;
expAdjustment -= partsCount * integerPartWidth;
exponent = totalExponent(p + 1, end, expAdjustment);
}
return normalize(rounding_mode, lost_fraction);
}
APFloat::opStatus
APFloat::roundSignificandWithExponent(const integerPart *decSigParts,
unsigned sigPartCount, int exp,
roundingMode rounding_mode)
{
unsigned int parts, pow5PartCount;
fltSemantics calcSemantics = { 32767, -32767, 0 };
integerPart pow5Parts[maxPowerOfFiveParts];
bool isNearest;
isNearest = (rounding_mode == rmNearestTiesToEven ||
rounding_mode == rmNearestTiesToAway);
parts = partCountForBits(semantics->precision + 11);
pow5PartCount = powerOf5(pow5Parts, exp >= 0 ? exp: -exp);
for (;; parts *= 2) {
opStatus sigStatus, powStatus;
unsigned int excessPrecision, truncatedBits;
calcSemantics.precision = parts * integerPartWidth - 1;
excessPrecision = calcSemantics.precision - semantics->precision;
truncatedBits = excessPrecision;
APFloat decSig = APFloat::getZero(calcSemantics, sign);
APFloat pow5(calcSemantics);
sigStatus = decSig.convertFromUnsignedParts(decSigParts, sigPartCount,
rmNearestTiesToEven);
powStatus = pow5.convertFromUnsignedParts(pow5Parts, pow5PartCount,
rmNearestTiesToEven);
decSig.exponent += exp;
lostFraction calcLostFraction;
integerPart HUerr, HUdistance;
unsigned int powHUerr;
if (exp >= 0) {
calcLostFraction = decSig.multiplySignificand(pow5, nullptr);
powHUerr = powStatus != opOK;
} else {
calcLostFraction = decSig.divideSignificand(pow5);
if (decSig.exponent < semantics->minExponent) {
excessPrecision += (semantics->minExponent - decSig.exponent);
truncatedBits = excessPrecision;
if (excessPrecision > calcSemantics.precision)
excessPrecision = calcSemantics.precision;
}
powHUerr = (powStatus == opOK && calcLostFraction == lfExactlyZero) ? 0:2;
}
assert(APInt::tcExtractBit
(decSig.significandParts(), calcSemantics.precision - 1) == 1);
HUerr = HUerrBound(calcLostFraction != lfExactlyZero, sigStatus != opOK,
powHUerr);
HUdistance = 2 * ulpsFromBoundary(decSig.significandParts(),
excessPrecision, isNearest);
if (HUdistance >= HUerr) {
APInt::tcExtract(significandParts(), partCount(), decSig.significandParts(),
calcSemantics.precision - excessPrecision,
excessPrecision);
exponent = (decSig.exponent + semantics->precision
- (calcSemantics.precision - excessPrecision));
calcLostFraction = lostFractionThroughTruncation(decSig.significandParts(),
decSig.partCount(),
truncatedBits);
return normalize(rounding_mode, calcLostFraction);
}
}
}
APFloat::opStatus
APFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode)
{
decimalInfo D;
opStatus fs;
StringRef::iterator p = str.begin();
interpretDecimal(p, str.end(), &D);
if (D.firstSigDigit == str.end() || decDigitValue(*D.firstSigDigit) >= 10U) {
category = fcZero;
fs = opOK;
} else if (D.normalizedExponent - 1 > INT_MAX / 42039) {
fs = handleOverflow(rounding_mode);
} else if (D.normalizedExponent - 1 < INT_MIN / 42039 ||
(D.normalizedExponent + 1) * 28738 <=
8651 * (semantics->minExponent - (int) semantics->precision)) {
category = fcNormal;
zeroSignificand();
fs = normalize(rounding_mode, lfLessThanHalf);
} else if ((D.normalizedExponent - 1) * 42039
>= 12655 * semantics->maxExponent) {
fs = handleOverflow(rounding_mode);
} else {
integerPart *decSignificand;
unsigned int partCount;
partCount = static_cast<unsigned int>(D.lastSigDigit - D.firstSigDigit) + 1;
partCount = partCountForBits(1 + 196 * partCount / 59);
decSignificand = new integerPart[partCount + 1];
partCount = 0;
do {
integerPart decValue, val, multiplier;
val = 0;
multiplier = 1;
do {
if (*p == '.') {
p++;
if (p == str.end()) {
break;
}
}
decValue = decDigitValue(*p++);
assert(decValue < 10U && "Invalid character in significand");
multiplier *= 10;
val = val * 10 + decValue;
} while (p <= D.lastSigDigit && multiplier <= (~ (integerPart) 0 - 9) / 10);
APInt::tcMultiplyPart(decSignificand, decSignificand, multiplier, val,
partCount, partCount + 1, false);
if (decSignificand[partCount])
partCount++;
} while (p <= D.lastSigDigit);
category = fcNormal;
fs = roundSignificandWithExponent(decSignificand, partCount,
D.exponent, rounding_mode);
delete [] decSignificand;
}
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");
if (convertFromStringSpecials(str))
return opOK;
StringRef::iterator p = str.begin();
size_t slen = str.size();
sign = *p == '-' ? 1 : 0;
if (*p == '-' || *p == '+') {
p++;
slen--;
assert(slen && "String has no digits");
}
if (slen >= 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
assert(slen - 2 && "Invalid string");
return convertFromHexadecimalString(StringRef(p + 2, slen - 2),
rounding_mode);
}
return convertFromDecimalString(StringRef(p, slen), rounding_mode);
}
unsigned int
APFloat::convertToHexString(char *dst, unsigned int hexDigits,
bool upperCase, roundingMode rounding_mode) const
{
char *p;
p = dst;
if (sign)
*dst++ = '-';
switch (category) {
case fcInfinity:
memcpy (dst, upperCase ? infinityU: infinityL, sizeof infinityU - 1);
dst += sizeof infinityL - 1;
break;
case fcNaN:
memcpy (dst, upperCase ? NaNU: NaNL, sizeof NaNU - 1);
dst += sizeof NaNU - 1;
break;
case fcZero:
*dst++ = '0';
*dst++ = upperCase ? 'X': 'x';
*dst++ = '0';
if (hexDigits > 1) {
*dst++ = '.';
memset (dst, '0', hexDigits - 1);
dst += hexDigits - 1;
}
*dst++ = upperCase ? 'P': 'p';
*dst++ = '0';
break;
case fcNormal:
dst = convertNormalToHexString (dst, hexDigits, upperCase, rounding_mode);
break;
}
*dst = 0;
return static_cast<unsigned int>(dst - p);
}
char *
APFloat::convertNormalToHexString(char *dst, unsigned int hexDigits,
bool upperCase,
roundingMode rounding_mode) const
{
unsigned int count, valueBits, shift, partsCount, outputDigits;
const char *hexDigitChars;
const integerPart *significand;
char *p;
bool roundUp;
*dst++ = '0';
*dst++ = upperCase ? 'X': 'x';
roundUp = false;
hexDigitChars = upperCase ? hexDigitsUpper: hexDigitsLower;
significand = significandParts();
partsCount = partCount();
valueBits = semantics->precision + 3;
shift = integerPartWidth - valueBits % integerPartWidth;
outputDigits = (valueBits - significandLSB () + 3) / 4;
if (hexDigits) {
if (hexDigits < outputDigits) {
unsigned int bits;
lostFraction fraction;
bits = valueBits - hexDigits * 4;
fraction = lostFractionThroughTruncation (significand, partsCount, bits);
roundUp = roundAwayFromZero(rounding_mode, fraction, bits);
}
outputDigits = hexDigits;
}
p = ++dst;
count = (valueBits + integerPartWidth - 1) / integerPartWidth;
while (outputDigits && count) {
integerPart part;
if (--count == partsCount)
part = 0;
else
part = significand[count] << shift;
if (count && shift)
part |= significand[count - 1] >> (integerPartWidth - shift);
unsigned int curDigits = integerPartWidth / 4;
if (curDigits > outputDigits)
curDigits = outputDigits;
dst += partAsHex (dst, part, curDigits, hexDigitChars);
outputDigits -= curDigits;
}
if (roundUp) {
char *q = dst;
do {
q--;
*q = hexDigitChars[hexDigitValue (*q) + 1];
} while (*q == '0');
assert(q >= p);
} else {
memset (dst, '0', outputDigits);
dst += outputDigits;
}
p[-1] = p[0];
if (dst -1 == p)
dst--;
else
p[0] = '.';
*dst++ = upperCase ? 'P': 'p';
return writeSignedDecimal (dst, exponent);
}
hash_code llvm::hash_value(const APFloat &Arg) {
if (!Arg.isFiniteNonZero())
return hash_combine((uint8_t)Arg.category,
Arg.isNaN() ? (uint8_t)0 : (uint8_t)Arg.sign,
Arg.semantics->precision);
return hash_combine((uint8_t)Arg.category, (uint8_t)Arg.sign,
Arg.semantics->precision, Arg.exponent,
hash_combine_range(
Arg.significandParts(),
Arg.significandParts() + Arg.partCount()));
}
APInt
APFloat::convertF80LongDoubleAPFloatToAPInt() const
{
assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended);
assert(partCount()==2);
uint64_t myexponent, mysignificand;
if (isFiniteNonZero()) {
myexponent = exponent+16383; mysignificand = significandParts()[0];
if (myexponent==1 && !(mysignificand & 0x8000000000000000ULL))
myexponent = 0; } else if (category==fcZero) {
myexponent = 0;
mysignificand = 0;
} else if (category==fcInfinity) {
myexponent = 0x7fff;
mysignificand = 0x8000000000000000ULL;
} else {
assert(category == fcNaN && "Unknown category");
myexponent = 0x7fff;
mysignificand = significandParts()[0];
}
uint64_t words[2];
words[0] = mysignificand;
words[1] = ((uint64_t)(sign & 1) << 15) |
(myexponent & 0x7fffLL);
return APInt(80, words);
}
APInt
APFloat::convertPPCDoubleDoubleAPFloatToAPInt() const
{
assert(semantics == (const llvm::fltSemantics*)&PPCDoubleDouble);
assert(partCount()==2);
uint64_t words[2];
opStatus fs;
bool losesInfo;
fltSemantics extendedSemantics = *semantics;
extendedSemantics.minExponent = IEEEdouble.minExponent;
APFloat extended(*this);
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 (u.isFiniteNonZero() && 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 {
words[1] = 0;
}
return APInt(128, words);
}
APInt
APFloat::convertQuadrupleAPFloatToAPInt() const
{
assert(semantics == (const llvm::fltSemantics*)&IEEEquad);
assert(partCount()==2);
uint64_t myexponent, mysignificand, mysignificand2;
if (isFiniteNonZero()) {
myexponent = exponent+16383; mysignificand = significandParts()[0];
mysignificand2 = significandParts()[1];
if (myexponent==1 && !(mysignificand2 & 0x1000000000000LL))
myexponent = 0; } else if (category==fcZero) {
myexponent = 0;
mysignificand = mysignificand2 = 0;
} else if (category==fcInfinity) {
myexponent = 0x7fff;
mysignificand = mysignificand2 = 0;
} else {
assert(category == fcNaN && "Unknown category!");
myexponent = 0x7fff;
mysignificand = significandParts()[0];
mysignificand2 = significandParts()[1];
}
uint64_t words[2];
words[0] = mysignificand;
words[1] = ((uint64_t)(sign & 1) << 63) |
((myexponent & 0x7fff) << 48) |
(mysignificand2 & 0xffffffffffffLL);
return APInt(128, words);
}
APInt
APFloat::convertDoubleAPFloatToAPInt() const
{
assert(semantics == (const llvm::fltSemantics*)&IEEEdouble);
assert(partCount()==1);
uint64_t myexponent, mysignificand;
if (isFiniteNonZero()) {
myexponent = exponent+1023; mysignificand = *significandParts();
if (myexponent==1 && !(mysignificand & 0x10000000000000LL))
myexponent = 0; } else if (category==fcZero) {
myexponent = 0;
mysignificand = 0;
} else if (category==fcInfinity) {
myexponent = 0x7ff;
mysignificand = 0;
} else {
assert(category == fcNaN && "Unknown category!");
myexponent = 0x7ff;
mysignificand = *significandParts();
}
return APInt(64, ((((uint64_t)(sign & 1) << 63) |
((myexponent & 0x7ff) << 52) |
(mysignificand & 0xfffffffffffffLL))));
}
APInt
APFloat::convertFloatAPFloatToAPInt() const
{
assert(semantics == (const llvm::fltSemantics*)&IEEEsingle);
assert(partCount()==1);
uint32_t myexponent, mysignificand;
if (isFiniteNonZero()) {
myexponent = exponent+127; mysignificand = (uint32_t)*significandParts();
if (myexponent == 1 && !(mysignificand & 0x800000))
myexponent = 0; } else if (category==fcZero) {
myexponent = 0;
mysignificand = 0;
} else if (category==fcInfinity) {
myexponent = 0xff;
mysignificand = 0;
} else {
assert(category == fcNaN && "Unknown category!");
myexponent = 0xff;
mysignificand = (uint32_t)*significandParts();
}
return APInt(32, (((sign&1) << 31) | ((myexponent&0xff) << 23) |
(mysignificand & 0x7fffff)));
}
APInt
APFloat::convertHalfAPFloatToAPInt() const
{
assert(semantics == (const llvm::fltSemantics*)&IEEEhalf);
assert(partCount()==1);
uint32_t myexponent, mysignificand;
if (isFiniteNonZero()) {
myexponent = exponent+15; mysignificand = (uint32_t)*significandParts();
if (myexponent == 1 && !(mysignificand & 0x400))
myexponent = 0; } else if (category==fcZero) {
myexponent = 0;
mysignificand = 0;
} else if (category==fcInfinity) {
myexponent = 0x1f;
mysignificand = 0;
} else {
assert(category == fcNaN && "Unknown category!");
myexponent = 0x1f;
mysignificand = (uint32_t)*significandParts();
}
return APInt(16, (((sign&1) << 15) | ((myexponent&0x1f) << 10) |
(mysignificand & 0x3ff)));
}
APInt
APFloat::bitcastToAPInt() const
{
if (semantics == (const llvm::fltSemantics*)&IEEEhalf)
return convertHalfAPFloatToAPInt();
if (semantics == (const llvm::fltSemantics*)&IEEEsingle)
return convertFloatAPFloatToAPInt();
if (semantics == (const llvm::fltSemantics*)&IEEEdouble)
return convertDoubleAPFloatToAPInt();
if (semantics == (const llvm::fltSemantics*)&IEEEquad)
return convertQuadrupleAPFloatToAPInt();
if (semantics == (const llvm::fltSemantics*)&PPCDoubleDouble)
return convertPPCDoubleDoubleAPFloatToAPInt();
assert(semantics == (const llvm::fltSemantics*)&x87DoubleExtended &&
"unknown format!");
return convertF80LongDoubleAPFloatToAPInt();
}
float
APFloat::convertToFloat() const
{
assert(semantics == (const llvm::fltSemantics*)&IEEEsingle &&
"Float semantics are not IEEEsingle");
APInt api = bitcastToAPInt();
return api.bitsToFloat();
}
double
APFloat::convertToDouble() const
{
assert(semantics == (const llvm::fltSemantics*)&IEEEdouble &&
"Float semantics are not IEEEdouble");
APInt api = bitcastToAPInt();
return api.bitsToDouble();
}
void
APFloat::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);
uint64_t mysignificand = i1;
initialize(&APFloat::x87DoubleExtended);
assert(partCount()==2);
sign = static_cast<unsigned int>(i2>>15);
if (myexponent==0 && mysignificand==0) {
category = fcZero;
} else if (myexponent==0x7fff && mysignificand==0x8000000000000000ULL) {
category = fcInfinity;
} else if (myexponent==0x7fff && mysignificand!=0x8000000000000000ULL) {
category = fcNaN;
significandParts()[0] = mysignificand;
significandParts()[1] = 0;
} else {
category = fcNormal;
exponent = myexponent - 16383;
significandParts()[0] = mysignificand;
significandParts()[1] = 0;
if (myexponent==0) exponent = -16382;
}
}
void
APFloat::initFromPPCDoubleDoubleAPInt(const APInt &api)
{
assert(api.getBitWidth()==128);
uint64_t i1 = api.getRawData()[0];
uint64_t i2 = api.getRawData()[1];
opStatus fs;
bool losesInfo;
initFromDoubleAPInt(APInt(64, i1));
fs = convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
assert(fs == opOK && !losesInfo);
(void)fs;
if (isFiniteNonZero()) {
APFloat v(IEEEdouble, APInt(64, i2));
fs = v.convert(PPCDoubleDouble, rmNearestTiesToEven, &losesInfo);
assert(fs == opOK && !losesInfo);
(void)fs;
add(v, rmNearestTiesToEven);
}
}
void
APFloat::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;
uint64_t mysignificand = i1;
uint64_t mysignificand2 = i2 & 0xffffffffffffLL;
initialize(&APFloat::IEEEquad);
assert(partCount()==2);
sign = static_cast<unsigned int>(i2>>63);
if (myexponent==0 &&
(mysignificand==0 && mysignificand2==0)) {
category = fcZero;
} else if (myexponent==0x7fff &&
(mysignificand==0 && mysignificand2==0)) {
category = fcInfinity;
} else if (myexponent==0x7fff &&
(mysignificand!=0 || mysignificand2 !=0)) {
category = fcNaN;
significandParts()[0] = mysignificand;
significandParts()[1] = mysignificand2;
} else {
category = fcNormal;
exponent = myexponent - 16383;
significandParts()[0] = mysignificand;
significandParts()[1] = mysignificand2;
if (myexponent==0) exponent = -16382;
else
significandParts()[1] |= 0x1000000000000LL; }
}
void
APFloat::initFromDoubleAPInt(const APInt &api)
{
assert(api.getBitWidth()==64);
uint64_t i = *api.getRawData();
uint64_t myexponent = (i >> 52) & 0x7ff;
uint64_t mysignificand = i & 0xfffffffffffffLL;
initialize(&APFloat::IEEEdouble);
assert(partCount()==1);
sign = static_cast<unsigned int>(i>>63);
if (myexponent==0 && mysignificand==0) {
category = fcZero;
} else if (myexponent==0x7ff && mysignificand==0) {
category = fcInfinity;
} else if (myexponent==0x7ff && mysignificand!=0) {
category = fcNaN;
*significandParts() = mysignificand;
} else {
category = fcNormal;
exponent = myexponent - 1023;
*significandParts() = mysignificand;
if (myexponent==0) exponent = -1022;
else
*significandParts() |= 0x10000000000000LL; }
}
void
APFloat::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;
initialize(&APFloat::IEEEsingle);
assert(partCount()==1);
sign = i >> 31;
if (myexponent==0 && mysignificand==0) {
category = fcZero;
} else if (myexponent==0xff && mysignificand==0) {
category = fcInfinity;
} else if (myexponent==0xff && mysignificand!=0) {
category = fcNaN;
*significandParts() = mysignificand;
} else {
category = fcNormal;
exponent = myexponent - 127; *significandParts() = mysignificand;
if (myexponent==0) exponent = -126;
else
*significandParts() |= 0x800000; }
}
void
APFloat::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;
initialize(&APFloat::IEEEhalf);
assert(partCount()==1);
sign = i >> 15;
if (myexponent==0 && mysignificand==0) {
category = fcZero;
} else if (myexponent==0x1f && mysignificand==0) {
category = fcInfinity;
} else if (myexponent==0x1f && mysignificand!=0) {
category = fcNaN;
*significandParts() = mysignificand;
} else {
category = fcNormal;
exponent = myexponent - 15; *significandParts() = mysignificand;
if (myexponent==0) exponent = -14;
else
*significandParts() |= 0x400; }
}
void
APFloat::initFromAPInt(const fltSemantics* Sem, const APInt& api)
{
if (Sem == &IEEEhalf)
return initFromHalfAPInt(api);
if (Sem == &IEEEsingle)
return initFromFloatAPInt(api);
if (Sem == &IEEEdouble)
return initFromDoubleAPInt(api);
if (Sem == &x87DoubleExtended)
return initFromF80LongDoubleAPInt(api);
if (Sem == &IEEEquad)
return initFromQuadrupleAPInt(api);
if (Sem == &PPCDoubleDouble)
return initFromPPCDoubleDoubleAPInt(api);
llvm_unreachable(nullptr);
}
APFloat
APFloat::getAllOnesValue(unsigned BitWidth, bool 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");
}
}
void APFloat::makeLargest(bool Negative) {
category = fcNormal;
sign = Negative;
exponent = semantics->maxExponent;
integerPart *significand = significandParts();
unsigned PartCount = partCount();
memset(significand, 0xFF, sizeof(integerPart)*(PartCount - 1));
const unsigned NumUnusedHighBits =
PartCount*integerPartWidth - semantics->precision;
significand[PartCount - 1] = (NumUnusedHighBits < integerPartWidth)
? (~integerPart(0) >> NumUnusedHighBits)
: 0;
}
void APFloat::makeSmallest(bool Negative) {
category = fcNormal;
sign = Negative;
exponent = semantics->minExponent;
APInt::tcSet(significandParts(), 1, partCount());
}
APFloat APFloat::getLargest(const fltSemantics &Sem, bool Negative) {
APFloat Val(Sem, uninitialized);
Val.makeLargest(Negative);
return Val;
}
APFloat APFloat::getSmallest(const fltSemantics &Sem, bool Negative) {
APFloat Val(Sem, uninitialized);
Val.makeSmallest(Negative);
return Val;
}
APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) {
APFloat Val(Sem, uninitialized);
Val.category = fcNormal;
Val.zeroSignificand();
Val.sign = Negative;
Val.exponent = Sem.minExponent;
Val.significandParts()[partCountForBits(Sem.precision)-1] |=
(((integerPart) 1) << ((Sem.precision - 1) % integerPartWidth));
return Val;
}
APFloat::APFloat(const fltSemantics &Sem, const APInt &API) {
initFromAPInt(&Sem, API);
}
APFloat::APFloat(float f) {
initFromAPInt(&IEEEsingle, APInt::floatToBits(f));
}
APFloat::APFloat(double d) {
initFromAPInt(&IEEEdouble, APInt::doubleToBits(d));
}
namespace {
void append(SmallVectorImpl<char> &Buffer, StringRef Str) {
Buffer.append(Str.begin(), Str.end());
}
void AdjustToPrecision(APInt &significand,
int &exp, unsigned FormatPrecision) {
unsigned bits = significand.getActiveBits();
unsigned bitsRequired = (FormatPrecision * 196 + 58) / 59;
if (bits <= bitsRequired) return;
unsigned tensRemovable = (bits - bitsRequired) * 59 / 196;
if (!tensRemovable) return;
exp += tensRemovable;
APInt divisor(significand.getBitWidth(), 1);
APInt powten(significand.getBitWidth(), 10);
while (true) {
if (tensRemovable & 1)
divisor *= powten;
tensRemovable >>= 1;
if (!tensRemovable) break;
powten *= powten;
}
significand = significand.udiv(divisor);
significand = significand.trunc(significand.getActiveBits());
}
void AdjustToPrecision(SmallVectorImpl<char> &buffer,
int &exp, unsigned FormatPrecision) {
unsigned N = buffer.size();
if (N <= FormatPrecision) return;
unsigned FirstSignificant = N - FormatPrecision;
if (buffer[FirstSignificant - 1] < '5') {
while (FirstSignificant < N && buffer[FirstSignificant] == '0')
FirstSignificant++;
exp += FirstSignificant;
buffer.erase(&buffer[0], &buffer[FirstSignificant]);
return;
}
for (unsigned I = FirstSignificant; I != N; ++I) {
if (buffer[I] == '9') {
FirstSignificant++;
} else {
buffer[I]++;
break;
}
}
if (FirstSignificant == N) {
exp += FirstSignificant;
buffer.clear();
buffer.push_back('1');
return;
}
exp += FirstSignificant;
buffer.erase(&buffer[0], &buffer[FirstSignificant]);
}
}
void APFloat::toString(SmallVectorImpl<char> &Str,
unsigned FormatPrecision,
unsigned FormatMaxPadding) const {
switch (category) {
case fcInfinity:
if (isNegative())
return append(Str, "-Inf");
else
return append(Str, "+Inf");
case fcNaN: return append(Str, "NaN");
case fcZero:
if (isNegative())
Str.push_back('-');
if (!FormatMaxPadding)
append(Str, "0.0E+0");
else
Str.push_back('0');
return;
case fcNormal:
break;
}
if (isNegative())
Str.push_back('-');
int exp = exponent - ((int) semantics->precision - 1);
APInt significand(semantics->precision,
makeArrayRef(significandParts(),
partCountForBits(semantics->precision)));
if (!FormatPrecision) {
FormatPrecision = 2 + semantics->precision * 59 / 196;
}
int trailingZeros = significand.countTrailingZeros();
exp += trailingZeros;
significand = significand.lshr(trailingZeros);
if (exp == 0) {
} else if (exp > 0) {
significand = significand.zext(semantics->precision + exp);
significand <<= exp;
exp = 0;
} else {
int texp = -exp;
unsigned precision = semantics->precision + (137 * texp + 136) / 59;
significand = significand.zext(precision);
APInt five_to_the_i(precision, 5);
while (true) {
if (texp & 1) significand *= five_to_the_i;
texp >>= 1;
if (!texp) break;
five_to_the_i *= five_to_the_i;
}
}
AdjustToPrecision(significand, exp, FormatPrecision);
SmallVector<char, 256> buffer;
unsigned precision = significand.getBitWidth();
APInt ten(precision, 10);
APInt digit(precision, 0);
bool inTrail = true;
while (significand != 0) {
APInt::udivrem(significand, ten, significand, digit);
unsigned d = digit.getZExtValue();
if (inTrail && !d) exp++;
else {
buffer.push_back((char) ('0' + d));
inTrail = false;
}
}
assert(!buffer.empty() && "no characters in buffer!");
AdjustToPrecision(buffer, exp, FormatPrecision);
unsigned NDigits = buffer.size();
bool FormatScientific;
if (!FormatMaxPadding)
FormatScientific = true;
else {
if (exp >= 0) {
FormatScientific = ((unsigned) exp > FormatMaxPadding ||
NDigits + (unsigned) exp > FormatPrecision);
} else {
int MSD = exp + (int) (NDigits - 1);
if (MSD >= 0) {
FormatScientific = false;
} else {
FormatScientific = ((unsigned) -MSD) > FormatMaxPadding;
}
}
}
if (FormatScientific) {
exp += (NDigits - 1);
Str.push_back(buffer[NDigits-1]);
Str.push_back('.');
if (NDigits == 1)
Str.push_back('0');
else
for (unsigned I = 1; I != NDigits; ++I)
Str.push_back(buffer[NDigits-1-I]);
Str.push_back('E');
Str.push_back(exp >= 0 ? '+' : '-');
if (exp < 0) exp = -exp;
SmallVector<char, 6> expbuf;
do {
expbuf.push_back((char) ('0' + (exp % 10)));
exp /= 10;
} while (exp);
for (unsigned I = 0, E = expbuf.size(); I != E; ++I)
Str.push_back(expbuf[E-1-I]);
return;
}
if (exp >= 0) {
for (unsigned I = 0; I != NDigits; ++I)
Str.push_back(buffer[NDigits-1-I]);
for (unsigned I = 0; I != (unsigned) exp; ++I)
Str.push_back('0');
return;
}
int NWholeDigits = exp + (int) NDigits;
unsigned I = 0;
if (NWholeDigits > 0) {
for (; I != (unsigned) NWholeDigits; ++I)
Str.push_back(buffer[NDigits-I-1]);
Str.push_back('.');
} else {
unsigned NZeros = 1 + (unsigned) -NWholeDigits;
Str.push_back('0');
Str.push_back('.');
for (unsigned Z = 1; Z != NZeros; ++Z)
Str.push_back('0');
}
for (; I != NDigits; ++I)
Str.push_back(buffer[NDigits-I-1]);
}
bool APFloat::getExactInverse(APFloat *inv) const {
if (!isFiniteNonZero())
return false;
if (significandLSB() != semantics->precision - 1)
return false;
APFloat reciprocal(*semantics, 1ULL);
if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK)
return false;
if (reciprocal.isDenormal())
return false;
assert(reciprocal.isFiniteNonZero() &&
reciprocal.significandLSB() == reciprocal.semantics->precision - 1);
if (inv)
*inv = reciprocal;
return true;
}
bool APFloat::isSignaling() const {
if (!isNaN())
return false;
return !APInt::tcExtractBit(significandParts(), semantics->precision - 2);
}
APFloat::opStatus APFloat::next(bool nextDown) {
if (nextDown)
changeSign();
opStatus result = opOK;
switch (category) {
case fcInfinity:
if (!isNegative())
break;
makeLargest(true);
break;
case fcNaN:
if (isSignaling()) {
result = opInvalidOp;
makeNaN(false, isNegative(), nullptr);
}
break;
case fcZero:
makeSmallest(false);
break;
case fcNormal:
if (isSmallest() && isNegative()) {
APInt::tcSet(significandParts(), 0, partCount());
category = fcZero;
exponent = 0;
break;
}
if (isLargest() && !isNegative()) {
APInt::tcSet(significandParts(), 0, partCount());
category = fcInfinity;
exponent = semantics->maxExponent + 1;
break;
}
if (isNegative()) {
bool WillCrossBinadeBoundary =
exponent != semantics->minExponent && isSignificandAllZeros();
integerPart *Parts = significandParts();
APInt::tcDecrement(Parts, partCount());
if (WillCrossBinadeBoundary) {
APInt::tcSetBit(Parts, semantics->precision - 1);
exponent--;
}
} else {
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 (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());
}
APFloat llvm::scalbn(APFloat X, int Exp) {
if (X.isInfinity() || X.isZero() || X.isNaN())
return std::move(X);
auto MaxExp = X.getSemantics().maxExponent;
auto MinExp = X.getSemantics().minExponent;
if (Exp > (MaxExp - X.exponent))
return APFloat::getInf(X.getSemantics(), X.isNegative());
if (Exp < (MinExp - X.exponent))
return APFloat::getZero(X.getSemantics(), X.isNegative());
X.exponent += Exp;
return std::move(X);
}