mirror of
https://github.com/RPCSX/llvm.git
synced 2024-11-25 20:59:51 +00:00
Implement a getBitsNeeded method to determine how many bits are needed to
represent a string in binary form by an APInt. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@35968 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
4beccb897d
commit
57ae4f5f01
@ -840,6 +840,12 @@ public:
|
||||
assert(getActiveBits() <= 64 && "Too many bits for int64_t");
|
||||
return int64_t(pVal[0]);
|
||||
}
|
||||
|
||||
/// This method determines how many bits are required to hold the APInt
|
||||
/// equivalent of the string given by \p str of length \p slen.
|
||||
/// @brief Get bits required for string value.
|
||||
static uint32_t getBitsNeeded(const char* str, uint32_t slen, uint8_t radix);
|
||||
|
||||
/// countLeadingZeros - This function is an APInt version of the
|
||||
/// countLeadingZeros_{32,64} functions in MathExtras.h. It counts the number
|
||||
/// of zeros from the most significant bit to the first one bit.
|
||||
|
@ -659,6 +659,43 @@ APInt& APInt::flip(uint32_t bitPosition) {
|
||||
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();
|
||||
}
|
||||
|
||||
uint64_t APInt::getHashValue() const {
|
||||
// Put the bit width into the low order bits.
|
||||
uint64_t hash = BitWidth;
|
||||
|
Loading…
Reference in New Issue
Block a user