// implementation classes. This struct should not define any non-static data
// members.
struct APFloatBase {
+ // TODO remove this and use APInt typedef directly.
+ typedef APInt::WordType integerPart;
+
/// A signed type to represent a floating point numbers unbiased exponent.
typedef signed short ExponentType;
template <typename T> class SmallVectorImpl;
template <typename T> class ArrayRef;
-// An unsigned host type used as a single part of a multi-part
-// bignum.
-typedef uint64_t integerPart;
-
-const unsigned int host_char_bit = 8;
-const unsigned int integerPartWidth =
- host_char_bit * static_cast<unsigned int>(sizeof(integerPart));
-
class APInt;
inline APInt operator-(APInt);
/// uses in its IR. This simplifies its use for LLVM.
///
class LLVM_NODISCARD APInt {
+public:
+ typedef uint64_t WordType;
+
+ /// This enum is used to hold the constants we needed for APInt.
+ enum : unsigned {
+ /// Byte size of a word.
+ APINT_WORD_SIZE = sizeof(WordType),
+ /// Bits in a word.
+ APINT_BITS_PER_WORD = APINT_WORD_SIZE * CHAR_BIT
+ };
+
+private:
unsigned BitWidth; ///< The number of bits in this APInt.
/// This union is used to store the integer value. When the
uint64_t *pVal; ///< Used to store the >64 bits integer value.
};
- /// This enum is used to hold the constants we needed for APInt.
- enum {
- /// Bits in a word
- APINT_BITS_PER_WORD =
- static_cast<unsigned int>(sizeof(uint64_t)) * CHAR_BIT,
- /// Byte size of a word
- APINT_WORD_SIZE = static_cast<unsigned int>(sizeof(uint64_t))
- };
-
friend struct DenseMapAPIntKeyInfo;
/// \brief Fast internal constructor
/// Sets the least significant part of a bignum to the input value, and zeroes
/// out higher parts.
- static void tcSet(integerPart *, integerPart, unsigned);
+ static void tcSet(WordType *, WordType, unsigned);
/// Assign one bignum to another.
- static void tcAssign(integerPart *, const integerPart *, unsigned);
+ static void tcAssign(WordType *, const WordType *, unsigned);
/// Returns true if a bignum is zero, false otherwise.
- static bool tcIsZero(const integerPart *, unsigned);
+ static bool tcIsZero(const WordType *, unsigned);
/// Extract the given bit of a bignum; returns 0 or 1. Zero-based.
- static int tcExtractBit(const integerPart *, unsigned bit);
+ static int tcExtractBit(const WordType *, unsigned bit);
/// Copy the bit vector of width srcBITS from SRC, starting at bit srcLSB, to
/// DST, of dstCOUNT parts, such that the bit srcLSB becomes the least
/// significant bit of DST. All high bits above srcBITS in DST are
/// zero-filled.
- static void tcExtract(integerPart *, unsigned dstCount,
- const integerPart *, unsigned srcBits,
+ static void tcExtract(WordType *, unsigned dstCount,
+ const WordType *, unsigned srcBits,
unsigned srcLSB);
/// Set the given bit of a bignum. Zero-based.
- static void tcSetBit(integerPart *, unsigned bit);
+ static void tcSetBit(WordType *, unsigned bit);
/// Clear the given bit of a bignum. Zero-based.
- static void tcClearBit(integerPart *, unsigned bit);
+ static void tcClearBit(WordType *, unsigned bit);
/// Returns the bit number of the least or most significant set bit of a
/// number. If the input number has no bits set -1U is returned.
- static unsigned tcLSB(const integerPart *, unsigned n);
- static unsigned tcMSB(const integerPart *parts, unsigned n);
+ static unsigned tcLSB(const WordType *, unsigned n);
+ static unsigned tcMSB(const WordType *parts, unsigned n);
/// Negate a bignum in-place.
- static void tcNegate(integerPart *, unsigned);
+ static void tcNegate(WordType *, unsigned);
/// DST += RHS + CARRY where CARRY is zero or one. Returns the carry flag.
- static integerPart tcAdd(integerPart *, const integerPart *,
- integerPart carry, unsigned);
+ static WordType tcAdd(WordType *, const WordType *,
+ WordType carry, unsigned);
/// DST -= RHS + CARRY where CARRY is zero or one. Returns the carry flag.
- static integerPart tcSubtract(integerPart *, const integerPart *,
- integerPart carry, unsigned);
+ static WordType tcSubtract(WordType *, const WordType *,
+ WordType carry, unsigned);
/// DST += SRC * MULTIPLIER + PART if add is true
/// DST = SRC * MULTIPLIER + PART if add is false
/// Otherwise DST is filled with the least significant DSTPARTS parts of the
/// result, and if all of the omitted higher parts were zero return zero,
/// otherwise overflow occurred and return one.
- static int tcMultiplyPart(integerPart *dst, const integerPart *src,
- integerPart multiplier, integerPart carry,
+ static int tcMultiplyPart(WordType *dst, const WordType *src,
+ WordType multiplier, WordType carry,
unsigned srcParts, unsigned dstParts,
bool add);
/// filled with the least significant parts of the result. Returns one if
/// overflow occurred, otherwise zero. DST must be disjoint from both
/// operands.
- static int tcMultiply(integerPart *, const integerPart *, const integerPart *,
+ static int tcMultiply(WordType *, const WordType *, const WordType *,
unsigned);
/// DST = LHS * RHS, where DST has width the sum of the widths of the
/// operands. No overflow occurs. DST must be disjoint from both
/// operands. Returns the number of parts required to hold the result.
- static unsigned tcFullMultiply(integerPart *, const integerPart *,
- const integerPart *, unsigned, unsigned);
+ static unsigned tcFullMultiply(WordType *, const WordType *,
+ const WordType *, unsigned, unsigned);
/// If RHS is zero LHS and REMAINDER are left unchanged, return one.
/// Otherwise set LHS to LHS / RHS with the fractional part discarded, set
/// SCRATCH is a bignum of the same size as the operands and result for use by
/// the routine; its contents need not be initialized and are destroyed. LHS,
/// REMAINDER and SCRATCH must be distinct.
- static int tcDivide(integerPart *lhs, const integerPart *rhs,
- integerPart *remainder, integerPart *scratch,
+ static int tcDivide(WordType *lhs, const WordType *rhs,
+ WordType *remainder, WordType *scratch,
unsigned parts);
/// Shift a bignum left COUNT bits. Shifted in bits are zero. There are no
/// restrictions on COUNT.
- static void tcShiftLeft(integerPart *, unsigned parts, unsigned count);
+ static void tcShiftLeft(WordType *, unsigned parts, unsigned count);
/// Shift a bignum right COUNT bits. Shifted in bits are zero. There are no
/// restrictions on COUNT.
- static void tcShiftRight(integerPart *, unsigned parts, unsigned count);
+ static void tcShiftRight(WordType *, unsigned parts, unsigned count);
/// The obvious AND, OR and XOR and complement operations.
- static void tcAnd(integerPart *, const integerPart *, unsigned);
- static void tcOr(integerPart *, const integerPart *, unsigned);
- static void tcXor(integerPart *, const integerPart *, unsigned);
- static void tcComplement(integerPart *, unsigned);
+ static void tcAnd(WordType *, const WordType *, unsigned);
+ static void tcOr(WordType *, const WordType *, unsigned);
+ static void tcXor(WordType *, const WordType *, unsigned);
+ static void tcComplement(WordType *, unsigned);
/// Comparison (unsigned) of two bignums.
- static int tcCompare(const integerPart *, const integerPart *, unsigned);
+ static int tcCompare(const WordType *, const WordType *, unsigned);
/// Increment a bignum in-place. Return the carry flag.
- static integerPart tcIncrement(integerPart *, unsigned);
+ static WordType tcIncrement(WordType *, unsigned);
/// Decrement a bignum in-place. Return the borrow flag.
- static integerPart tcDecrement(integerPart *, unsigned);
+ static WordType tcDecrement(WordType *, unsigned);
/// Set the least significant BITS and clear the rest.
- static void tcSetLeastSignificantBits(integerPart *, unsigned, unsigned bits);
+ static void tcSetLeastSignificantBits(WordType *, unsigned, unsigned bits);
/// \brief debug method
void dump() const;
using namespace llvm;
+// TODO: Remove these and use APInt qualified types directly.
+typedef APInt::WordType integerPart;
+const unsigned int integerPartWidth = APInt::APINT_BITS_PER_WORD;
+
/// 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.
unsigned APInt::countLeadingZerosSlowCase() const {
unsigned Count = 0;
for (int i = getNumWords()-1; i >= 0; --i) {
- integerPart V = pVal[i];
+ uint64_t V = pVal[i];
if (V == 0)
Count += APINT_BITS_PER_WORD;
else {
// Assumed by lowHalf, highHalf, partMSB and partLSB. A fairly safe
// and unrestricting assumption.
-static_assert(integerPartWidth % 2 == 0, "Part width must be divisible by 2!");
+static_assert(APInt::APINT_BITS_PER_WORD % 2 == 0,
+ "Part width must be divisible by 2!");
/* Some handy functions local to this file. */
/* Returns the integer part with the least significant BITS set.
BITS cannot be zero. */
-static inline integerPart lowBitMask(unsigned bits) {
- assert(bits != 0 && bits <= integerPartWidth);
+static inline APInt::WordType lowBitMask(unsigned bits) {
+ assert(bits != 0 && bits <= APInt::APINT_BITS_PER_WORD);
- return ~(integerPart) 0 >> (integerPartWidth - bits);
+ return ~(APInt::WordType) 0 >> (APInt::APINT_BITS_PER_WORD - bits);
}
/* Returns the value of the lower half of PART. */
-static inline integerPart lowHalf(integerPart part) {
- return part & lowBitMask(integerPartWidth / 2);
+static inline APInt::WordType lowHalf(APInt::WordType part) {
+ return part & lowBitMask(APInt::APINT_BITS_PER_WORD / 2);
}
/* Returns the value of the upper half of PART. */
-static inline integerPart highHalf(integerPart part) {
- return part >> (integerPartWidth / 2);
+static inline APInt::WordType highHalf(APInt::WordType part) {
+ return part >> (APInt::APINT_BITS_PER_WORD / 2);
}
/* Returns the bit number of the most significant set bit of a part.
If the input number has no bits set -1U is returned. */
-static unsigned partMSB(integerPart value) {
+static unsigned partMSB(APInt::WordType value) {
return findLastSet(value, ZB_Max);
}
/* Returns the bit number of the least significant set bit of a
part. If the input number has no bits set -1U is returned. */
-static unsigned partLSB(integerPart value) {
+static unsigned partLSB(APInt::WordType value) {
return findFirstSet(value, ZB_Max);
}
/* Sets the least significant part of a bignum to the input value, and
zeroes out higher parts. */
-void APInt::tcSet(integerPart *dst, integerPart part, unsigned parts) {
+void APInt::tcSet(WordType *dst, WordType part, unsigned parts) {
assert(parts > 0);
dst[0] = part;
}
/* Assign one bignum to another. */
-void APInt::tcAssign(integerPart *dst, const integerPart *src, unsigned parts) {
+void APInt::tcAssign(WordType *dst, const WordType *src, unsigned parts) {
for (unsigned i = 0; i < parts; i++)
dst[i] = src[i];
}
/* Returns true if a bignum is zero, false otherwise. */
-bool APInt::tcIsZero(const integerPart *src, unsigned parts) {
+bool APInt::tcIsZero(const WordType *src, unsigned parts) {
for (unsigned i = 0; i < parts; i++)
if (src[i])
return false;
}
/* Extract the given bit of a bignum; returns 0 or 1. */
-int APInt::tcExtractBit(const integerPart *parts, unsigned bit) {
- return (parts[bit / integerPartWidth] &
- ((integerPart) 1 << bit % integerPartWidth)) != 0;
+int APInt::tcExtractBit(const WordType *parts, unsigned bit) {
+ return (parts[bit / APINT_BITS_PER_WORD] &
+ ((WordType) 1 << bit % APINT_BITS_PER_WORD)) != 0;
}
/* Set the given bit of a bignum. */
-void APInt::tcSetBit(integerPart *parts, unsigned bit) {
- parts[bit / integerPartWidth] |= (integerPart) 1 << (bit % integerPartWidth);
+void APInt::tcSetBit(WordType *parts, unsigned bit) {
+ parts[bit / APINT_BITS_PER_WORD] |= (WordType) 1 << (bit % APINT_BITS_PER_WORD);
}
/* Clears the given bit of a bignum. */
-void APInt::tcClearBit(integerPart *parts, unsigned bit) {
- parts[bit / integerPartWidth] &=
- ~((integerPart) 1 << (bit % integerPartWidth));
+void APInt::tcClearBit(WordType *parts, unsigned bit) {
+ parts[bit / APINT_BITS_PER_WORD] &=
+ ~((WordType) 1 << (bit % APINT_BITS_PER_WORD));
}
/* Returns the bit number of the least significant set bit of a
number. If the input number has no bits set -1U is returned. */
-unsigned APInt::tcLSB(const integerPart *parts, unsigned n) {
+unsigned APInt::tcLSB(const WordType *parts, unsigned n) {
for (unsigned i = 0; i < n; i++) {
if (parts[i] != 0) {
unsigned lsb = partLSB(parts[i]);
- return lsb + i * integerPartWidth;
+ return lsb + i * APINT_BITS_PER_WORD;
}
}
/* Returns the bit number of the most significant set bit of a number.
If the input number has no bits set -1U is returned. */
-unsigned APInt::tcMSB(const integerPart *parts, unsigned n) {
+unsigned APInt::tcMSB(const WordType *parts, unsigned n) {
do {
--n;
if (parts[n] != 0) {
unsigned msb = partMSB(parts[n]);
- return msb + n * integerPartWidth;
+ return msb + n * APINT_BITS_PER_WORD;
}
} while (n);
the least significant bit of DST. All high bits above srcBITS in
DST are zero-filled. */
void
-APInt::tcExtract(integerPart *dst, unsigned dstCount, const integerPart *src,
+APInt::tcExtract(WordType *dst, unsigned dstCount, const WordType *src,
unsigned srcBits, unsigned srcLSB) {
- unsigned dstParts = (srcBits + integerPartWidth - 1) / integerPartWidth;
+ unsigned dstParts = (srcBits + APINT_BITS_PER_WORD - 1) / APINT_BITS_PER_WORD;
assert(dstParts <= dstCount);
- unsigned firstSrcPart = srcLSB / integerPartWidth;
+ unsigned firstSrcPart = srcLSB / APINT_BITS_PER_WORD;
tcAssign (dst, src + firstSrcPart, dstParts);
- unsigned shift = srcLSB % integerPartWidth;
+ unsigned shift = srcLSB % APINT_BITS_PER_WORD;
tcShiftRight (dst, dstParts, shift);
- /* We now have (dstParts * integerPartWidth - shift) bits from SRC
+ /* We now have (dstParts * APINT_BITS_PER_WORD - shift) bits from SRC
in DST. If this is less that srcBits, append the rest, else
clear the high bits. */
- unsigned n = dstParts * integerPartWidth - shift;
+ unsigned n = dstParts * APINT_BITS_PER_WORD - shift;
if (n < srcBits) {
- integerPart mask = lowBitMask (srcBits - n);
+ WordType mask = lowBitMask (srcBits - n);
dst[dstParts - 1] |= ((src[firstSrcPart + dstParts] & mask)
- << n % integerPartWidth);
+ << n % APINT_BITS_PER_WORD);
} else if (n > srcBits) {
- if (srcBits % integerPartWidth)
- dst[dstParts - 1] &= lowBitMask (srcBits % integerPartWidth);
+ if (srcBits % APINT_BITS_PER_WORD)
+ dst[dstParts - 1] &= lowBitMask (srcBits % APINT_BITS_PER_WORD);
}
/* Clear high parts. */
}
/* DST += RHS + C where C is zero or one. Returns the carry flag. */
-integerPart APInt::tcAdd(integerPart *dst, const integerPart *rhs,
- integerPart c, unsigned parts) {
+APInt::WordType APInt::tcAdd(WordType *dst, const WordType *rhs,
+ WordType c, unsigned parts) {
assert(c <= 1);
for (unsigned i = 0; i < parts; i++) {
- integerPart l = dst[i];
+ WordType l = dst[i];
if (c) {
dst[i] += rhs[i] + 1;
c = (dst[i] <= l);
}
/* DST -= RHS + C where C is zero or one. Returns the carry flag. */
-integerPart APInt::tcSubtract(integerPart *dst, const integerPart *rhs,
- integerPart c, unsigned parts)
-{
+APInt::WordType APInt::tcSubtract(WordType *dst, const WordType *rhs,
+ WordType c, unsigned parts) {
assert(c <= 1);
for (unsigned i = 0; i < parts; i++) {
- integerPart l = dst[i];
+ WordType l = dst[i];
if (c) {
dst[i] -= rhs[i] + 1;
c = (dst[i] >= l);
}
/* Negate a bignum in-place. */
-void APInt::tcNegate(integerPart *dst, unsigned parts) {
+void APInt::tcNegate(WordType *dst, unsigned parts) {
tcComplement(dst, parts);
tcIncrement(dst, parts);
}
DSTPARTS parts of the result, and if all of the omitted higher
parts were zero return zero, otherwise overflow occurred and
return one. */
-int APInt::tcMultiplyPart(integerPart *dst, const integerPart *src,
- integerPart multiplier, integerPart carry,
+int APInt::tcMultiplyPart(WordType *dst, const WordType *src,
+ WordType multiplier, WordType carry,
unsigned srcParts, unsigned dstParts,
bool add) {
/* Otherwise our writes of DST kill our later reads of SRC. */
unsigned i;
for (i = 0; i < n; i++) {
- integerPart low, mid, high, srcPart;
+ WordType low, mid, high, srcPart;
/* [ LOW, HIGH ] = MULTIPLIER * SRC[i] + DST[i] + CARRY.
mid = lowHalf(srcPart) * highHalf(multiplier);
high += highHalf(mid);
- mid <<= integerPartWidth / 2;
+ mid <<= APINT_BITS_PER_WORD / 2;
if (low + mid < low)
high++;
low += mid;
mid = highHalf(srcPart) * lowHalf(multiplier);
high += highHalf(mid);
- mid <<= integerPartWidth / 2;
+ mid <<= APINT_BITS_PER_WORD / 2;
if (low + mid < low)
high++;
low += mid;
is filled with the least significant parts of the result. Returns
one if overflow occurred, otherwise zero. DST must be disjoint
from both operands. */
-int APInt::tcMultiply(integerPart *dst, const integerPart *lhs,
- const integerPart *rhs, unsigned parts) {
+int APInt::tcMultiply(WordType *dst, const WordType *lhs,
+ const WordType *rhs, unsigned parts) {
assert(dst != lhs && dst != rhs);
int overflow = 0;
operands. No overflow occurs. DST must be disjoint from both
operands. Returns the number of parts required to hold the
result. */
-unsigned APInt::tcFullMultiply(integerPart *dst, const integerPart *lhs,
- const integerPart *rhs, unsigned lhsParts,
+unsigned APInt::tcFullMultiply(WordType *dst, const WordType *lhs,
+ const WordType *rhs, unsigned lhsParts,
unsigned rhsParts) {
/* Put the narrower number on the LHS for less loops below. */
if (lhsParts > rhsParts) {
use by the routine; its contents need not be initialized and are
destroyed. LHS, REMAINDER and SCRATCH must be distinct.
*/
-int APInt::tcDivide(integerPart *lhs, const integerPart *rhs,
- integerPart *remainder, integerPart *srhs,
+int APInt::tcDivide(WordType *lhs, const WordType *rhs,
+ WordType *remainder, WordType *srhs,
unsigned parts) {
assert(lhs != remainder && lhs != srhs && remainder != srhs);
if (shiftCount == 0)
return true;
- shiftCount = parts * integerPartWidth - shiftCount;
- unsigned n = shiftCount / integerPartWidth;
- integerPart mask = (integerPart) 1 << (shiftCount % integerPartWidth);
+ shiftCount = parts * APINT_BITS_PER_WORD - shiftCount;
+ unsigned n = shiftCount / APINT_BITS_PER_WORD;
+ WordType mask = (WordType) 1 << (shiftCount % APINT_BITS_PER_WORD);
tcAssign(srhs, rhs, parts);
tcShiftLeft(srhs, parts, shiftCount);
shiftCount--;
tcShiftRight(srhs, parts, 1);
if ((mask >>= 1) == 0) {
- mask = (integerPart) 1 << (integerPartWidth - 1);
+ mask = (WordType) 1 << (APINT_BITS_PER_WORD - 1);
n--;
}
}
/* Shift a bignum left COUNT bits in-place. Shifted in bits are zero.
There are no restrictions on COUNT. */
-void APInt::tcShiftLeft(integerPart *dst, unsigned parts, unsigned count) {
+void APInt::tcShiftLeft(WordType *dst, unsigned parts, unsigned count) {
if (count) {
/* Jump is the inter-part jump; shift is is intra-part shift. */
- unsigned jump = count / integerPartWidth;
- unsigned shift = count % integerPartWidth;
+ unsigned jump = count / APINT_BITS_PER_WORD;
+ unsigned shift = count % APINT_BITS_PER_WORD;
while (parts > jump) {
- integerPart part;
+ WordType part;
parts--;
if (shift) {
part <<= shift;
if (parts >= jump + 1)
- part |= dst[parts - jump - 1] >> (integerPartWidth - shift);
+ part |= dst[parts - jump - 1] >> (APINT_BITS_PER_WORD - shift);
}
dst[parts] = part;
/* Shift a bignum right COUNT bits in-place. Shifted in bits are
zero. There are no restrictions on COUNT. */
-void APInt::tcShiftRight(integerPart *dst, unsigned parts, unsigned count) {
+void APInt::tcShiftRight(WordType *dst, unsigned parts, unsigned count) {
if (count) {
/* Jump is the inter-part jump; shift is is intra-part shift. */
- unsigned jump = count / integerPartWidth;
- unsigned shift = count % integerPartWidth;
+ unsigned jump = count / APINT_BITS_PER_WORD;
+ unsigned shift = count % APINT_BITS_PER_WORD;
/* Perform the shift. This leaves the most significant COUNT bits
of the result at zero. */
for (unsigned i = 0; i < parts; i++) {
- integerPart part;
+ WordType part;
if (i + jump >= parts) {
part = 0;
if (shift) {
part >>= shift;
if (i + jump + 1 < parts)
- part |= dst[i + jump + 1] << (integerPartWidth - shift);
+ part |= dst[i + jump + 1] << (APINT_BITS_PER_WORD - shift);
}
}
}
/* Bitwise and of two bignums. */
-void APInt::tcAnd(integerPart *dst, const integerPart *rhs, unsigned parts) {
+void APInt::tcAnd(WordType *dst, const WordType *rhs, unsigned parts) {
for (unsigned i = 0; i < parts; i++)
dst[i] &= rhs[i];
}
/* Bitwise inclusive or of two bignums. */
-void APInt::tcOr(integerPart *dst, const integerPart *rhs, unsigned parts) {
+void APInt::tcOr(WordType *dst, const WordType *rhs, unsigned parts) {
for (unsigned i = 0; i < parts; i++)
dst[i] |= rhs[i];
}
/* Bitwise exclusive or of two bignums. */
-void APInt::tcXor(integerPart *dst, const integerPart *rhs, unsigned parts) {
+void APInt::tcXor(WordType *dst, const WordType *rhs, unsigned parts) {
for (unsigned i = 0; i < parts; i++)
dst[i] ^= rhs[i];
}
/* Complement a bignum in-place. */
-void APInt::tcComplement(integerPart *dst, unsigned parts) {
+void APInt::tcComplement(WordType *dst, unsigned parts) {
for (unsigned i = 0; i < parts; i++)
dst[i] = ~dst[i];
}
/* Comparison (unsigned) of two bignums. */
-int APInt::tcCompare(const integerPart *lhs, const integerPart *rhs,
+int APInt::tcCompare(const WordType *lhs, const WordType *rhs,
unsigned parts) {
while (parts) {
parts--;
}
/* Increment a bignum in-place, return the carry flag. */
-integerPart APInt::tcIncrement(integerPart *dst, unsigned parts) {
+APInt::WordType APInt::tcIncrement(WordType *dst, unsigned parts) {
unsigned i;
for (i = 0; i < parts; i++)
if (++dst[i] != 0)
}
/* Decrement a bignum in-place, return the borrow flag. */
-integerPart APInt::tcDecrement(integerPart *dst, unsigned parts) {
+APInt::WordType APInt::tcDecrement(WordType *dst, unsigned parts) {
for (unsigned i = 0; i < parts; i++) {
// If the current word is non-zero, then the decrement has no effect on the
// higher-order words of the integer and no borrow can occur. Exit early.
/* Set the least significant BITS bits of a bignum, clear the
rest. */
-void APInt::tcSetLeastSignificantBits(integerPart *dst, unsigned parts,
+void APInt::tcSetLeastSignificantBits(WordType *dst, unsigned parts,
unsigned bits) {
unsigned i = 0;
- while (bits > integerPartWidth) {
- dst[i++] = ~(integerPart) 0;
- bits -= integerPartWidth;
+ while (bits > APINT_BITS_PER_WORD) {
+ dst[i++] = ~(WordType) 0;
+ bits -= APINT_BITS_PER_WORD;
}
if (bits)
- dst[i++] = ~(integerPart) 0 >> (integerPartWidth - bits);
+ dst[i++] = ~(WordType) 0 >> (APINT_BITS_PER_WORD - bits);
while (i < parts)
dst[i++] = 0;
// Multiword check.
uint64_t N = 0xEB6EB136591CBA21ULL;
- integerPart E2[4] = {
+ APInt::WordType E2[4] = {
N,
0x7B9358BD6A33F10AULL,
0x7E7FFA5EADD8846ULL,
0x305F341CA00B613DULL
};
- APInt A2(integerPartWidth*4, E2);
+ APInt A2(APInt::APINT_BITS_PER_WORD*4, E2);
EXPECT_EQ(A2 & N, N);
EXPECT_EQ(A2 & 0, 0);
// No out borrow.
{
- integerPart singleWord = ~integerPart(0) << (integerPartWidth - 1);
- integerPart carry = APInt::tcDecrement(&singleWord, 1);
- EXPECT_EQ(carry, integerPart(0));
- EXPECT_EQ(singleWord, ~integerPart(0) >> 1);
+ APInt::WordType singleWord = ~APInt::WordType(0) << (APInt::APINT_BITS_PER_WORD - 1);
+ APInt::WordType carry = APInt::tcDecrement(&singleWord, 1);
+ EXPECT_EQ(carry, APInt::WordType(0));
+ EXPECT_EQ(singleWord, ~APInt::WordType(0) >> 1);
}
// With out borrow.
{
- integerPart singleWord = 0;
- integerPart carry = APInt::tcDecrement(&singleWord, 1);
- EXPECT_EQ(carry, integerPart(1));
- EXPECT_EQ(singleWord, ~integerPart(0));
+ APInt::WordType singleWord = 0;
+ APInt::WordType carry = APInt::tcDecrement(&singleWord, 1);
+ EXPECT_EQ(carry, APInt::WordType(1));
+ EXPECT_EQ(singleWord, ~APInt::WordType(0));
}
// Test multiword decrement.
// No across word borrow, no out borrow.
{
- integerPart test[4] = {0x1, 0x1, 0x1, 0x1};
- integerPart expected[4] = {0x0, 0x1, 0x1, 0x1};
+ APInt::WordType test[4] = {0x1, 0x1, 0x1, 0x1};
+ APInt::WordType expected[4] = {0x0, 0x1, 0x1, 0x1};
APInt::tcDecrement(test, 4);
EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
}
// 1 across word borrow, no out borrow.
{
- integerPart test[4] = {0x0, 0xF, 0x1, 0x1};
- integerPart expected[4] = {~integerPart(0), 0xE, 0x1, 0x1};
- integerPart carry = APInt::tcDecrement(test, 4);
- EXPECT_EQ(carry, integerPart(0));
+ APInt::WordType test[4] = {0x0, 0xF, 0x1, 0x1};
+ APInt::WordType expected[4] = {~APInt::WordType(0), 0xE, 0x1, 0x1};
+ APInt::WordType carry = APInt::tcDecrement(test, 4);
+ EXPECT_EQ(carry, APInt::WordType(0));
EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
}
// 2 across word borrow, no out borrow.
{
- integerPart test[4] = {0x0, 0x0, 0xC, 0x1};
- integerPart expected[4] = {~integerPart(0), ~integerPart(0), 0xB, 0x1};
- integerPart carry = APInt::tcDecrement(test, 4);
- EXPECT_EQ(carry, integerPart(0));
+ APInt::WordType test[4] = {0x0, 0x0, 0xC, 0x1};
+ APInt::WordType expected[4] = {~APInt::WordType(0), ~APInt::WordType(0), 0xB, 0x1};
+ APInt::WordType carry = APInt::tcDecrement(test, 4);
+ EXPECT_EQ(carry, APInt::WordType(0));
EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
}
// 3 across word borrow, no out borrow.
{
- integerPart test[4] = {0x0, 0x0, 0x0, 0x1};
- integerPart expected[4] = {~integerPart(0), ~integerPart(0), ~integerPart(0), 0x0};
- integerPart carry = APInt::tcDecrement(test, 4);
- EXPECT_EQ(carry, integerPart(0));
+ APInt::WordType test[4] = {0x0, 0x0, 0x0, 0x1};
+ APInt::WordType expected[4] = {~APInt::WordType(0), ~APInt::WordType(0), ~APInt::WordType(0), 0x0};
+ APInt::WordType carry = APInt::tcDecrement(test, 4);
+ EXPECT_EQ(carry, APInt::WordType(0));
EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
}
// 3 across word borrow, with out borrow.
{
- integerPart test[4] = {0x0, 0x0, 0x0, 0x0};
- integerPart expected[4] = {~integerPart(0), ~integerPart(0), ~integerPart(0), ~integerPart(0)};
- integerPart carry = APInt::tcDecrement(test, 4);
- EXPECT_EQ(carry, integerPart(1));
+ APInt::WordType test[4] = {0x0, 0x0, 0x0, 0x0};
+ APInt::WordType expected[4] = {~APInt::WordType(0), ~APInt::WordType(0), ~APInt::WordType(0), ~APInt::WordType(0)};
+ APInt::WordType carry = APInt::tcDecrement(test, 4);
+ EXPECT_EQ(carry, APInt::WordType(1));
EXPECT_EQ(APInt::tcCompare(test, expected, 4), 0);
}
}
}
// Multiword check.
- integerPart E2[4] = {
+ APInt::WordType E2[4] = {
0xEB6EB136591CBA21ULL,
0x7B9358BD6A33F10AULL,
0x7E7FFA5EADD8846ULL,
0x305F341CA00B613DULL
};
- APInt A2(integerPartWidth*4, E2);
+ APInt A2(APInt::APINT_BITS_PER_WORD*4, E2);
for (unsigned i = 0; i < 4; ++i) {
- for (unsigned j = 0; j < integerPartWidth; ++j) {
+ for (unsigned j = 0; j < APInt::APINT_BITS_PER_WORD; ++j) {
EXPECT_EQ(bool(E2[i] & (1ULL << j)),
- A2[i*integerPartWidth + j]);
+ A2[i*APInt::APINT_BITS_PER_WORD + j]);
}
}
}
// Multiple word check.
// Test round up.
- integerPart I4[4] = {0x0, 0xF, 0x18, 0x0};
- APInt A4(integerPartWidth*4, I4);
+ APInt::WordType I4[4] = {0x0, 0xF, 0x18, 0x0};
+ APInt A4(APInt::APINT_BITS_PER_WORD*4, I4);
EXPECT_EQ(A4.nearestLogBase2(), A4.ceilLogBase2());
// Test round down.
- integerPart I5[4] = {0x0, 0xF, 0x10, 0x0};
- APInt A5(integerPartWidth*4, I5);
+ APInt::WordType I5[4] = {0x0, 0xF, 0x10, 0x0};
+ APInt A5(APInt::APINT_BITS_PER_WORD*4, I5);
EXPECT_EQ(A5.nearestLogBase2(), A5.logBase2());
// Test ties round up.
uint64_t I6[4] = {0x0, 0x0, 0x0, 0x18};
- APInt A6(integerPartWidth*4, I6);
+ APInt A6(APInt::APINT_BITS_PER_WORD*4, I6);
EXPECT_EQ(A6.nearestLogBase2(), A6.ceilLogBase2());
// Test BitWidth == 1 special cases.