diff options
Diffstat (limited to 'lib/Support/APInt.cpp')
-rw-r--r-- | lib/Support/APInt.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 43173311cd80..758fe8b4f866 100644 --- a/lib/Support/APInt.cpp +++ b/lib/Support/APInt.cpp @@ -401,6 +401,33 @@ void APInt::insertBits(const APInt &subBits, unsigned bitPosition) { } } +void APInt::insertBits(uint64_t subBits, unsigned bitPosition, unsigned numBits) { + uint64_t maskBits = maskTrailingOnes<uint64_t>(numBits); + subBits &= maskBits; + if (isSingleWord()) { + U.VAL &= ~(maskBits << bitPosition); + U.VAL |= subBits << bitPosition; + return; + } + + unsigned loBit = whichBit(bitPosition); + unsigned loWord = whichWord(bitPosition); + unsigned hiWord = whichWord(bitPosition + numBits - 1); + if (loWord == hiWord) { + U.pVal[loWord] &= ~(maskBits << loBit); + U.pVal[loWord] |= subBits << loBit; + return; + } + + static_assert(8 * sizeof(WordType) <= 64, "This code assumes only two words affected"); + unsigned wordBits = 8 * sizeof(WordType); + U.pVal[loWord] &= ~(maskBits << loBit); + U.pVal[loWord] |= subBits << loBit; + + U.pVal[hiWord] &= ~(maskBits >> (wordBits - loBit)); + U.pVal[hiWord] |= subBits >> (wordBits - loBit); +} + APInt APInt::extractBits(unsigned numBits, unsigned bitPosition) const { assert(numBits > 0 && "Can't extract zero bits"); assert(bitPosition < BitWidth && (numBits + bitPosition) <= BitWidth && @@ -438,6 +465,31 @@ APInt APInt::extractBits(unsigned numBits, unsigned bitPosition) const { return Result.clearUnusedBits(); } +uint64_t APInt::extractBitsAsZExtValue(unsigned numBits, + unsigned bitPosition) const { + assert(numBits > 0 && "Can't extract zero bits"); + assert(bitPosition < BitWidth && (numBits + bitPosition) <= BitWidth && + "Illegal bit extraction"); + assert(numBits <= 64 && "Illegal bit extraction"); + + uint64_t maskBits = maskTrailingOnes<uint64_t>(numBits); + if (isSingleWord()) + return (U.VAL >> bitPosition) & maskBits; + + unsigned loBit = whichBit(bitPosition); + unsigned loWord = whichWord(bitPosition); + unsigned hiWord = whichWord(bitPosition + numBits - 1); + if (loWord == hiWord) + return (U.pVal[loWord] >> loBit) & maskBits; + + static_assert(8 * sizeof(WordType) <= 64, "This code assumes only two words affected"); + unsigned wordBits = 8 * sizeof(WordType); + uint64_t retBits = U.pVal[loWord] >> loBit; + retBits |= U.pVal[hiWord] << (wordBits - loBit); + retBits &= maskBits; + return retBits; +} + unsigned APInt::getBitsNeeded(StringRef str, uint8_t radix) { assert(!str.empty() && "Invalid string length"); assert((radix == 10 || radix == 8 || radix == 16 || radix == 2 || |