#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include <math.h>
+#include <limits>
#include <cstring>
#include <cstdlib>
#ifndef NDEBUG
return result;
}
-APInt::APInt(uint32_t numBits, uint64_t val, bool isSigned )
+APInt::APInt(uint32_t numBits, uint64_t val, bool isSigned)
: BitWidth(numBits), VAL(0) {
assert(BitWidth >= IntegerType::MIN_INT_BITS && "bitwidth too small");
assert(BitWidth <= IntegerType::MAX_INT_BITS && "bitwidth too large");
}
// Set all the bits in all the words.
- for (uint32_t i = 0; i < getNumWords() - 1; ++i)
+ for (uint32_t i = 0; i < getNumWords(); ++i)
pVal[i] = -1ULL;
// Clear the unused ones
return clearUnusedBits();
return *this;
}
+uint32_t APInt::getBitsNeeded(const char* str, uint32_t slen, uint8_t radix) {
+ assert(str != 0 && "Invalid value string");
+ assert(slen > 0 && "Invalid string length");
+
+ // Each computation below needs to know if its negative
+ uint32_t isNegative = str[0] == '-';
+ if (isNegative) {
+ slen--;
+ str++;
+ }
+ // For radixes of power-of-two values, the bits required is accurately and
+ // easily computed
+ if (radix == 2)
+ return slen + isNegative;
+ if (radix == 8)
+ return slen * 3 + isNegative;
+ if (radix == 16)
+ return slen * 4 + isNegative;
+
+ // Otherwise it must be radix == 10, the hard case
+ assert(radix == 10 && "Invalid radix");
+
+ // This is grossly inefficient but accurate. We could probably do something
+ // with a computation of roughly slen*64/20 and then adjust by the value of
+ // the first few digits. But, I'm not sure how accurate that could be.
+
+ // Compute a sufficient number of bits that is always large enough but might
+ // be too large. This avoids the assertion in the constructor.
+ uint32_t sufficient = slen*64/18;
+
+ // Convert to the actual binary value.
+ APInt tmp(sufficient, str, slen, radix);
+
+ // Compute how many bits are required.
+ return isNegative + tmp.logBase2() + 1;
+}
+
uint64_t APInt::getHashValue() const {
// Put the bit width into the low order bits.
uint64_t hash = BitWidth;
APInt APInt::byteSwap() const {
assert(BitWidth >= 16 && BitWidth % 16 == 0 && "Cannot byteswap!");
if (BitWidth == 16)
- return APInt(BitWidth, ByteSwap_16(VAL));
+ return APInt(BitWidth, ByteSwap_16(uint16_t(VAL)));
else if (BitWidth == 32)
- return APInt(BitWidth, ByteSwap_32(VAL));
+ return APInt(BitWidth, ByteSwap_32(uint32_t(VAL)));
else if (BitWidth == 48) {
- uint64_t Tmp1 = ((VAL >> 32) << 16) | (VAL & 0xFFFF);
+ uint32_t Tmp1 = uint32_t(VAL >> 16);
Tmp1 = ByteSwap_32(Tmp1);
- uint64_t Tmp2 = (VAL >> 16) & 0xFFFF;
+ uint16_t Tmp2 = uint16_t(VAL);
Tmp2 = ByteSwap_16(Tmp2);
- return
- APInt(BitWidth,
- (Tmp1 & 0xff) | ((Tmp1<<16) & 0xffff00000000ULL) | (Tmp2 << 16));
+ return APInt(BitWidth, (uint64_t(Tmp2) << 32) | Tmp1);
} else if (BitWidth == 64)
return APInt(BitWidth, ByteSwap_64(VAL));
else {
// Return infinity for exponent overflow
if (exp > 1023) {
if (!isSigned || !isNeg)
- return double(1.0E300 * 1.0E300); // positive infinity
+ return std::numeric_limits<double>::infinity();
else
- return double(-1.0E300 * 1.0E300); // negative infinity
+ return -std::numeric_limits<double>::infinity();
}
exp += 1023; // Increment for 1023 bias
// If all the bits were shifted out, the result is, technically, undefined.
// We return -1 if it was negative, 0 otherwise. We check this early to avoid
// issues in the algorithm below.
- if (shiftAmt == BitWidth)
+ if (shiftAmt == BitWidth) {
if (isNegative())
return APInt(BitWidth, -1ULL);
else
return APInt(BitWidth, 0);
+ }
// Create some space for the result.
uint64_t * val = new uint64_t[getNumWords()];
// Deal with sign extenstion in the break word, and possibly the word before
// it.
- if (isNegative())
+ if (isNegative()) {
if (wordShift > bitsInWord) {
if (breakWord > 0)
val[breakWord-1] |=
val[breakWord] |= ~0ULL;
} else
val[breakWord] |= (~0ULL << (bitsInWord - wordShift));
+ }
}
// Remaining words are 0 or -1, just assign them.
/// Logical right-shift this APInt by shiftAmt.
/// @brief Logical right-shift function.
APInt APInt::lshr(uint32_t shiftAmt) const {
- if (isSingleWord())
+ if (isSingleWord()) {
if (shiftAmt == BitWidth)
return APInt(BitWidth, 0);
else
return APInt(BitWidth, this->VAL >> shiftAmt);
+ }
// If all the bits were shifted out, the result is 0. This avoids issues
// with shifting by the size of the integer type, which produces undefined
bool isNeg = str[0] == '-';
if (isNeg)
str++, slen--;
- assert(slen <= numbits || radix != 2 && "Insufficient bit width");
- assert(slen*3 <= numbits || radix != 8 && "Insufficient bit width");
- assert(slen*4 <= numbits || radix != 16 && "Insufficient bit width");
- assert((slen*64)/20 <= numbits || radix != 10 && "Insufficient bit width");
+ assert((slen <= numbits || radix != 2) && "Insufficient bit width");
+ assert((slen*3 <= numbits || radix != 8) && "Insufficient bit width");
+ assert((slen*4 <= numbits || radix != 16) && "Insufficient bit width");
+ assert(((slen*64)/22 <= numbits || radix != 10) && "Insufficient bit width");
// Allocate memory
if (!isSingleWord())