summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Support/APInt.cpp
diff options
context:
space:
mode:
authorCraig Topper <craig.topper@gmail.com>2017-04-13 04:36:06 +0000
committerCraig Topper <craig.topper@gmail.com>2017-04-13 04:36:06 +0000
commit92fc4772922d10071fe70bd5fc889c1aa28cbe7b (patch)
treeff4d6ffdb4a78e970c161bfe22b3488f69c3f82f /llvm/lib/Support/APInt.cpp
parent39c9105e25e6a36cd67f5443108da0c056e2df68 (diff)
downloadbcm5719-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.cpp104
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,
OpenPOWER on IntegriCloud