aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/APInt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Support/APInt.cpp')
-rw-r--r--llvm/lib/Support/APInt.cpp27
1 files changed, 27 insertions, 0 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp
index 4e45416..0119cb2 100644
--- a/llvm/lib/Support/APInt.cpp
+++ b/llvm/lib/Support/APInt.cpp
@@ -336,6 +336,33 @@ void APInt::setBitsSlowCase(unsigned loBit, unsigned hiBit) {
U.pVal[word] = WORDTYPE_MAX;
}
+void APInt::clearBitsSlowCase(unsigned LoBit, unsigned HiBit) {
+ unsigned LoWord = whichWord(LoBit);
+ unsigned HiWord = whichWord(HiBit);
+
+ // Create an initial mask for the low word with ones below loBit.
+ uint64_t LoMask = ~(WORDTYPE_MAX << whichBit(LoBit));
+
+ // If HiBit is not aligned, we need a high mask.
+ unsigned HiShiftAmt = whichBit(HiBit);
+ if (HiShiftAmt != 0) {
+ // Create a high mask with ones above HiBit.
+ uint64_t HiMask = ~(WORDTYPE_MAX >> (APINT_BITS_PER_WORD - HiShiftAmt));
+ // If LoWord and HiWord are equal, then we combine the masks. Otherwise,
+ // set the bits in HiWord.
+ if (HiWord == LoWord)
+ LoMask &= HiMask;
+ else
+ U.pVal[HiWord] &= HiMask;
+ }
+ // Apply the mask to the low word.
+ U.pVal[LoWord] &= LoMask;
+
+ // Fill any words between LoWord and HiWord with all zeros.
+ for (unsigned Word = LoWord + 1; Word < HiWord; ++Word)
+ U.pVal[Word] = 0;
+}
+
// Complement a bignum in-place.
static void tcComplement(APInt::WordType *dst, unsigned parts) {
for (unsigned i = 0; i < parts; i++)