diff options
author | Craig Topper <craig.topper@gmail.com> | 2017-04-13 04:36:06 +0000 |
---|---|---|
committer | Craig Topper <craig.topper@gmail.com> | 2017-04-13 04:36:06 +0000 |
commit | 92fc4772922d10071fe70bd5fc889c1aa28cbe7b (patch) | |
tree | ff4d6ffdb4a78e970c161bfe22b3488f69c3f82f /llvm/lib/Support/APInt.cpp | |
parent | 39c9105e25e6a36cd67f5443108da0c056e2df68 (diff) | |
download | bcm5719-llvm-92fc4772922d10071fe70bd5fc889c1aa28cbe7b.tar.gz bcm5719-llvm-92fc4772922d10071fe70bd5fc889c1aa28cbe7b.zip |
[APInt] Generalize the implementation of tcIncrement to support adding a full 'word' by introducing tcAddPart. Use this to support tcIncrement, operator++ and operator+=(uint64_t). Do the same for subtract. NFCI.
llvm-svn: 300169
Diffstat (limited to 'llvm/lib/Support/APInt.cpp')
-rw-r--r-- | llvm/lib/Support/APInt.cpp | 104 |
1 files changed, 40 insertions, 64 deletions
diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index 00b340e3ee4..8733028a9b6 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -171,58 +171,21 @@ void APInt::Profile(FoldingSetNodeID& ID) const { ID.AddInteger(pVal[i]); } -/// This function adds a single "digit" integer, y, to the multiple -/// "digit" integer array, x[]. x[] is modified to reflect the addition and -/// 1 is returned if there is a carry out, otherwise 0 is returned. -/// @returns the carry of the addition. -static bool add_1(uint64_t dest[], uint64_t x[], unsigned len, uint64_t y) { - for (unsigned i = 0; i < len; ++i) { - dest[i] = y + x[i]; - if (dest[i] < y) - y = 1; // Carry one to next digit. - else { - y = 0; // No need to carry so exit early - break; - } - } - return y; -} - /// @brief Prefix increment operator. Increments the APInt by one. APInt& APInt::operator++() { if (isSingleWord()) ++VAL; else - add_1(pVal, pVal, getNumWords(), 1); + tcIncrement(pVal, getNumWords()); return clearUnusedBits(); } -/// This function subtracts a single "digit" (64-bit word), y, from -/// the multi-digit integer array, x[], propagating the borrowed 1 value until -/// no further borrowing is needed or it runs out of "digits" in x. The result -/// is 1 if "borrowing" exhausted the digits in x, or 0 if x was not exhausted. -/// In other words, if y > x then this function returns 1, otherwise 0. -/// @returns the borrow out of the subtraction -static bool sub_1(uint64_t x[], unsigned len, uint64_t y) { - for (unsigned i = 0; i < len; ++i) { - uint64_t X = x[i]; - x[i] -= y; - if (y > X) - y = 1; // We have to "borrow 1" from next "digit" - else { - y = 0; // No need to borrow - break; // Remaining digits are unchanged so exit early - } - } - return bool(y); -} - /// @brief Prefix decrement operator. Decrements the APInt by one. APInt& APInt::operator--() { if (isSingleWord()) --VAL; else - sub_1(pVal, getNumWords(), 1); + tcDecrement(pVal, getNumWords()); return clearUnusedBits(); } @@ -242,7 +205,7 @@ APInt& APInt::operator+=(uint64_t RHS) { if (isSingleWord()) VAL += RHS; else - add_1(pVal, pVal, getNumWords(), RHS); + tcAddPart(pVal, RHS, getNumWords()); return clearUnusedBits(); } @@ -262,7 +225,7 @@ APInt& APInt::operator-=(uint64_t RHS) { if (isSingleWord()) VAL -= RHS; else - sub_1(pVal, getNumWords(), RHS); + tcSubtractPart(pVal, RHS, getNumWords()); return clearUnusedBits(); } @@ -2471,6 +2434,22 @@ APInt::WordType APInt::tcAdd(WordType *dst, const WordType *rhs, return c; } +/// This function adds a single "word" integer, src, to the multiple +/// "word" integer array, dst[]. dst[] is modified to reflect the addition and +/// 1 is returned if there is a carry out, otherwise 0 is returned. +/// @returns the carry of the addition. +APInt::WordType APInt::tcAddPart(WordType *dst, WordType src, + unsigned parts) { + for (unsigned i = 0; i < parts; ++i) { + dst[i] += src; + if (dst[i] >= src) + return 0; // No need to carry so exit early. + src = 1; // Carry one to next digit. + } + + return 1; +} + /* DST -= RHS + C where C is zero or one. Returns the carry flag. */ APInt::WordType APInt::tcSubtract(WordType *dst, const WordType *rhs, WordType c, unsigned parts) { @@ -2490,6 +2469,26 @@ APInt::WordType APInt::tcSubtract(WordType *dst, const WordType *rhs, return c; } +/// This function subtracts a single "word" (64-bit word), src, from +/// the multi-word integer array, dst[], propagating the borrowed 1 value until +/// no further borrowing is needed or it runs out of "words" in dst. The result +/// is 1 if "borrowing" exhausted the digits in dst, or 0 if dst was not +/// exhausted. In other words, if src > dst then this function returns 1, +/// otherwise 0. +/// @returns the borrow out of the subtraction +APInt::WordType APInt::tcSubtractPart(WordType *dst, WordType src, + unsigned parts) { + for (unsigned i = 0; i < parts; ++i) { + WordType Dst = dst[i]; + dst[i] -= src; + if (src <= Dst) + return 0; // No need to borrow so exit early. + src = 1; // We have to "borrow 1" from next "word" + } + + return 1; +} + /* Negate a bignum in-place. */ void APInt::tcNegate(WordType *dst, unsigned parts) { tcComplement(dst, parts); @@ -2784,29 +2783,6 @@ int APInt::tcCompare(const WordType *lhs, const WordType *rhs, return 0; } -/* Increment a bignum in-place, return the carry flag. */ -APInt::WordType APInt::tcIncrement(WordType *dst, unsigned parts) { - unsigned i; - for (i = 0; i < parts; i++) - if (++dst[i] != 0) - break; - - return i == parts; -} - -/* Decrement a bignum in-place, return the borrow flag. */ -APInt::WordType APInt::tcDecrement(WordType *dst, unsigned parts) { - for (unsigned i = 0; i < parts; i++) { - // If the current word is non-zero, then the decrement has no effect on the - // higher-order words of the integer and no borrow can occur. Exit early. - if (dst[i]--) - return 0; - } - // If every word was zero, then there is a borrow. - return 1; -} - - /* Set the least significant BITS bits of a bignum, clear the rest. */ void APInt::tcSetLeastSignificantBits(WordType *dst, unsigned parts, |