From: Craig Topper Date: Thu, 13 Apr 2017 04:36:06 +0000 (+0000) Subject: [APInt] Generalize the implementation of tcIncrement to support adding a full 'word... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cd686df68a2f1a014c32e98a76128766db373cfc;p=llvm [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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300169 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/ADT/APInt.h b/include/llvm/ADT/APInt.h index 045df3c9087..fb883aa061e 100644 --- a/include/llvm/ADT/APInt.h +++ b/include/llvm/ADT/APInt.h @@ -1698,10 +1698,14 @@ public: /// DST += RHS + CARRY where CARRY is zero or one. Returns the carry flag. static WordType tcAdd(WordType *, const WordType *, WordType carry, unsigned); + /// DST += RHS. Returns the carry flag. + static WordType tcAddPart(WordType *, WordType, unsigned); /// DST -= RHS + CARRY where CARRY is zero or one. Returns the carry flag. static WordType tcSubtract(WordType *, const WordType *, WordType carry, unsigned); + /// DST -= RHS. Returns the carry flag. + static WordType tcSubtractPart(WordType *, WordType, unsigned); /// DST += SRC * MULTIPLIER + PART if add is true /// DST = SRC * MULTIPLIER + PART if add is false @@ -1762,10 +1766,14 @@ public: static int tcCompare(const WordType *, const WordType *, unsigned); /// Increment a bignum in-place. Return the carry flag. - static WordType tcIncrement(WordType *, unsigned); + static WordType tcIncrement(WordType *dst, unsigned parts) { + return tcAddPart(dst, 1, parts); + } /// Decrement a bignum in-place. Return the borrow flag. - static WordType tcDecrement(WordType *, unsigned); + static WordType tcDecrement(WordType *dst, unsigned parts) { + return tcSubtractPart(dst, 1, parts); + } /// Set the least significant BITS and clear the rest. static void tcSetLeastSignificantBits(WordType *, unsigned, unsigned bits); diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp index 00b340e3ee4..8733028a9b6 100644 --- a/lib/Support/APInt.cpp +++ b/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,