diff options
author | Reid Spencer <rspencer@reidspencer.com> | 2007-02-27 21:59:26 +0000 |
---|---|---|
committer | Reid Spencer <rspencer@reidspencer.com> | 2007-02-27 21:59:26 +0000 |
commit | 681dcd14e9d59c2070e3a298328db9aea6069480 (patch) | |
tree | 4aafeb60a49d78d286effd129e14dbf66ab0457b /lib/Support/APInt.cpp | |
parent | 3fae29acef408d999914406a77c140b28f8ed91e (diff) |
Implement countLeadingOnes() and getMinSignedBits(). This helps to minimize
the bit width of negative numbers by computing the minimum bit width for a
negative value. E.g. 0x1800000000000000 could be just 0x8000000000000000
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34695 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Support/APInt.cpp')
-rw-r--r-- | lib/Support/APInt.cpp | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index acc9de295b..c13c59e3db 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -702,6 +702,38 @@ uint32_t APInt::countLeadingZeros() const { return Count; } +static uint32_t countLeadingOnes_64(uint64_t V, uint32_t skip) { + uint32_t Count = 0; + if (skip) + V <<= skip; + while (V && (V & (1ULL << 63))) { + Count++; + V <<= 1; + } + return Count; +} + +uint32_t APInt::countLeadingOnes() const { + if (isSingleWord()) + return countLeadingOnes_64(VAL, APINT_BITS_PER_WORD - BitWidth); + + uint32_t highWordBits = BitWidth % APINT_BITS_PER_WORD; + uint32_t shift = (highWordBits == 0 ? 0 : APINT_BITS_PER_WORD - highWordBits); + int i = getNumWords() - 1; + uint32_t Count = countLeadingOnes_64(pVal[i], shift); + if (Count == highWordBits) { + for (i--; i >= 0; --i) { + if (pVal[i] == -1ULL) + Count += APINT_BITS_PER_WORD; + else { + Count += countLeadingOnes_64(pVal[i], 0); + break; + } + } + } + return Count; +} + uint32_t APInt::countTrailingZeros() const { if (isSingleWord()) return CountTrailingZeros_64(VAL); @@ -1701,6 +1733,7 @@ void APInt::dump() const else for (unsigned i = getNumWords(); i > 0; i--) { cerr << pVal[i-1] << " "; } - cerr << " (" << this->toString(10) << ")\n" << std::setbase(10); + cerr << " U(" << this->toString(10) << ") S(" << this->toStringSigned(10) + << ")\n" << std::setbase(10); } #endif |