#define LLVM_ADT_APFLOAT_H
#include "llvm/ADT/APInt.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/ErrorHandling.h"
#include <memory>
/// @{
opStatus convert(const fltSemantics &, roundingMode, bool *);
- opStatus convertToInteger(integerPart *, unsigned int, bool, roundingMode,
- bool *) const;
+ opStatus convertToInteger(MutableArrayRef<integerPart>, unsigned int, bool,
+ roundingMode, bool *) const;
opStatus convertFromAPInt(const APInt &, bool, roundingMode);
opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
bool, roundingMode);
opStatus addOrSubtract(const IEEEFloat &, roundingMode, bool subtract);
opStatus handleOverflow(roundingMode);
bool roundAwayFromZero(roundingMode, lostFraction, unsigned int) const;
- opStatus convertToSignExtendedInteger(integerPart *, unsigned int, bool,
- roundingMode, bool *) const;
+ opStatus convertToSignExtendedInteger(MutableArrayRef<integerPart>,
+ unsigned int, bool, roundingMode,
+ bool *) const;
opStatus convertFromUnsignedParts(const integerPart *, unsigned int,
roundingMode);
opStatus convertFromHexadecimalString(StringRef, roundingMode);
opStatus convertFromString(StringRef, roundingMode);
opStatus next(bool nextDown);
- opStatus convertToInteger(integerPart *Input, unsigned int Width,
- bool IsSigned, roundingMode RM,
+ opStatus convertToInteger(MutableArrayRef<integerPart> Input,
+ unsigned int Width, bool IsSigned, roundingMode RM,
bool *IsExact) const;
opStatus convertFromAPInt(const APInt &Input, bool IsSigned, roundingMode RM);
opStatus convertFromSignExtendedInteger(const integerPart *Input,
opStatus convert(const fltSemantics &ToSemantics, roundingMode RM,
bool *losesInfo);
- opStatus convertToInteger(integerPart *Input, unsigned int Width,
- bool IsSigned, roundingMode RM,
+ opStatus convertToInteger(MutableArrayRef<integerPart> Input,
+ unsigned int Width, bool IsSigned, roundingMode RM,
bool *IsExact) const {
APFLOAT_DISPATCH_ON_SEMANTICS(
convertToInteger(Input, Width, IsSigned, RM, IsExact));
int parts = partCount();
integerPart *x = new integerPart[parts];
bool ignored;
- fs = V.convertToInteger(x, parts * integerPartWidth, true,
- rmNearestTiesToEven, &ignored);
- if (fs==opInvalidOp) {
+ fs = V.convertToInteger(makeMutableArrayRef(x, parts),
+ parts * integerPartWidth, true, rmNearestTiesToEven,
+ &ignored);
+ if (fs == opInvalidOp) {
delete[] x;
return fs;
}
int parts = partCount();
integerPart *x = new integerPart[parts];
bool ignored;
- fs = V.convertToInteger(x, parts * integerPartWidth, true,
- rmTowardZero, &ignored);
- if (fs==opInvalidOp) {
+ fs = V.convertToInteger(makeMutableArrayRef(x, parts),
+ parts * integerPartWidth, true, rmTowardZero,
+ &ignored);
+ if (fs == opInvalidOp) {
delete[] x;
return fs;
}
Note that for conversions to integer type the C standard requires
round-to-zero to always be used. */
IEEEFloat::opStatus IEEEFloat::convertToSignExtendedInteger(
- integerPart *parts, unsigned int width, bool isSigned,
+ MutableArrayRef<integerPart> parts, unsigned int width, bool isSigned,
roundingMode rounding_mode, bool *isExact) const {
lostFraction lost_fraction;
const integerPart *src;
return opInvalidOp;
dstPartsCount = partCountForBits(width);
+ assert(dstPartsCount <= parts.size() && "Integer too big");
if (category == fcZero) {
- APInt::tcSet(parts, 0, dstPartsCount);
+ APInt::tcSet(parts.data(), 0, dstPartsCount);
// Negative zero can't be represented as an int.
*isExact = !sign;
return opOK;
the destination. */
if (exponent < 0) {
/* Our absolute value is less than one; truncate everything. */
- APInt::tcSet(parts, 0, dstPartsCount);
+ APInt::tcSet(parts.data(), 0, dstPartsCount);
/* For exponent -1 the integer bit represents .5, look at that.
For smaller exponents leftmost truncated bit is 0. */
truncatedBits = semantics->precision -1U - exponent;
if (bits < semantics->precision) {
/* We truncate (semantics->precision - bits) bits. */
truncatedBits = semantics->precision - bits;
- APInt::tcExtract(parts, dstPartsCount, src, bits, truncatedBits);
+ APInt::tcExtract(parts.data(), dstPartsCount, src, bits, truncatedBits);
} else {
/* We want at least as many bits as are available. */
- APInt::tcExtract(parts, dstPartsCount, src, semantics->precision, 0);
- APInt::tcShiftLeft(parts, dstPartsCount, bits - semantics->precision);
+ APInt::tcExtract(parts.data(), dstPartsCount, src, semantics->precision,
+ 0);
+ APInt::tcShiftLeft(parts.data(), dstPartsCount,
+ bits - semantics->precision);
truncatedBits = 0;
}
}
truncatedBits);
if (lost_fraction != lfExactlyZero &&
roundAwayFromZero(rounding_mode, lost_fraction, truncatedBits)) {
- if (APInt::tcIncrement(parts, dstPartsCount))
+ if (APInt::tcIncrement(parts.data(), dstPartsCount))
return opInvalidOp; /* Overflow. */
}
} else {
}
/* Step 3: check if we fit in the destination. */
- unsigned int omsb = APInt::tcMSB(parts, dstPartsCount) + 1;
+ unsigned int omsb = APInt::tcMSB(parts.data(), dstPartsCount) + 1;
if (sign) {
if (!isSigned) {
/* It takes omsb bits to represent the unsigned integer value.
We lose a bit for the sign, but care is needed as the
maximally negative integer is a special case. */
- if (omsb == width && APInt::tcLSB(parts, dstPartsCount) + 1 != omsb)
+ if (omsb == width &&
+ APInt::tcLSB(parts.data(), dstPartsCount) + 1 != omsb)
return opInvalidOp;
/* This case can happen because of rounding. */
return opInvalidOp;
}
- APInt::tcNegate (parts, dstPartsCount);
+ APInt::tcNegate (parts.data(), dstPartsCount);
} else {
if (omsb >= width + !isSigned)
return opInvalidOp;
the original value. This is almost equivalent to result==opOK,
except for negative zeroes.
*/
-IEEEFloat::opStatus IEEEFloat::convertToInteger(integerPart *parts,
- unsigned int width,
- bool isSigned,
- roundingMode rounding_mode,
- bool *isExact) const {
+IEEEFloat::opStatus
+IEEEFloat::convertToInteger(MutableArrayRef<integerPart> parts,
+ unsigned int width, bool isSigned,
+ roundingMode rounding_mode, bool *isExact) const {
opStatus fs;
fs = convertToSignExtendedInteger(parts, width, isSigned, rounding_mode,
unsigned int bits, dstPartsCount;
dstPartsCount = partCountForBits(width);
+ assert(dstPartsCount <= parts.size() && "Integer too big");
if (category == fcNaN)
bits = 0;
else
bits = width - isSigned;
- APInt::tcSetLeastSignificantBits(parts, dstPartsCount, bits);
+ APInt::tcSetLeastSignificantBits(parts.data(), dstPartsCount, bits);
if (sign && isSigned)
- APInt::tcShiftLeft(parts, dstPartsCount, width - 1);
+ APInt::tcShiftLeft(parts.data(), dstPartsCount, width - 1);
}
return fs;
return Ret;
}
-APFloat::opStatus DoubleAPFloat::convertToInteger(integerPart *Input,
- unsigned int Width,
- bool IsSigned,
- roundingMode RM,
- bool *IsExact) const {
+APFloat::opStatus
+DoubleAPFloat::convertToInteger(MutableArrayRef<integerPart> Input,
+ unsigned int Width, bool IsSigned,
+ roundingMode RM, bool *IsExact) const {
assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics");
return APFloat(semPPCDoubleDoubleLegacy, bitcastToAPInt())
.convertToInteger(Input, Width, IsSigned, RM, IsExact);
bool *isExact) const {
unsigned bitWidth = result.getBitWidth();
SmallVector<uint64_t, 4> parts(result.getNumWords());
- opStatus status = convertToInteger(parts.data(), bitWidth, result.isSigned(),
+ opStatus status = convertToInteger(parts, bitWidth, result.isSigned(),
rounding_mode, isExact);
// Keeps the original signed-ness.
result = APInt(bitWidth, parts);