[libc-commits] [libc] [libc] Allow BigInt class to use base word types other than uint64_t. (PR #81634)
via libc-commits
libc-commits at lists.llvm.org
Tue Feb 13 10:18:20 PST 2024
================
@@ -254,33 +258,33 @@ template <size_t Bits, bool Signed> struct BigInt {
return partial_sum.val[1];
}
- LIBC_INLINE constexpr BigInt<Bits, Signed>
- operator*(const BigInt<Bits, Signed> &other) const {
+ LIBC_INLINE constexpr BigInt<Bits, Signed, WordType>
+ operator*(const BigInt<Bits, Signed, WordType> &other) const {
if constexpr (Signed) {
- BigInt<Bits, false> a(*this);
- BigInt<Bits, false> b(other);
- bool a_neg = (a.val[WORDCOUNT - 1] >> 63);
- bool b_neg = (b.val[WORDCOUNT - 1] >> 63);
+ BigInt<Bits, false, WordType> a(*this);
+ BigInt<Bits, false, WordType> b(other);
+ bool a_neg = (a.val[WORD_COUNT - 1] >> (WORD_SIZE - 1));
+ bool b_neg = (b.val[WORD_COUNT - 1] >> (WORD_SIZE - 1));
if (a_neg)
a = -a;
if (b_neg)
b = -b;
- BigInt<Bits, false> prod = a * b;
+ BigInt<Bits, false, WordType> prod = a * b;
if (a_neg != b_neg)
prod = -prod;
- return static_cast<BigInt<Bits, true>>(prod);
+ return static_cast<BigInt<Bits, true, WordType>>(prod);
} else {
- if constexpr (WORDCOUNT == 1) {
+ if constexpr (WORD_COUNT == 1) {
return {val[0] * other.val[0]};
} else {
- BigInt<Bits, Signed> result(0);
- BigInt<128, Signed> partial_sum(0);
- uint64_t carry = 0;
- for (size_t i = 0; i < WORDCOUNT; ++i) {
+ BigInt<Bits, Signed, WordType> result(0);
+ BigInt<2 * WORD_SIZE, Signed, WordType> partial_sum(0);
+ WordType carry = 0;
+ for (size_t i = 0; i < WORD_COUNT; ++i) {
for (size_t j = 0; j <= i; j++) {
- NumberPair<uint64_t> prod = full_mul(val[j], other.val[i - j]);
- BigInt<128, Signed> tmp({prod.lo, prod.hi});
+ NumberPair<WordType> prod = full_mul(val[j], other.val[i - j]);
----------------
michaelrj-google wrote:
full_mull can only handle sizes up to uint64. Should we add a check?
https://github.com/llvm/llvm-project/pull/81634
More information about the libc-commits
mailing list