forked from OSchip/llvm-project
[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
This commit is contained in:
parent
39c9105e25
commit
92fc477292
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue