aboutsummaryrefslogtreecommitdiff
path: root/lib/Support/APInt.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-10-23 17:51:42 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-10-23 17:51:42 +0000
commit1d5ae1026e831016fc29fd927877c86af904481f (patch)
tree2cdfd12620fcfa5d9e4a0389f85368e8e36f63f9 /lib/Support/APInt.cpp
parente6d1592492a3a379186bfb02bd0f4eda0669c0d5 (diff)
Notes
Diffstat (limited to 'lib/Support/APInt.cpp')
-rw-r--r--lib/Support/APInt.cpp52
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 ||