[libc][NFC] Move aligned access implementations to separate header
[llvm-project.git] / libc / src / __support / UInt.h
bloba748d47cd06cc846f831cda24b7efceb924d8ff3
1 //===-- A class to manipulate wide integers. --------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIBC_SRC_SUPPORT_UINT_H
10 #define LLVM_LIBC_SRC_SUPPORT_UINT_H
12 #include "src/__support/CPP/array.h"
13 #include "src/__support/CPP/limits.h"
14 #include "src/__support/CPP/optional.h"
15 #include "src/__support/CPP/type_traits.h"
16 #include "src/__support/builtin_wrappers.h"
17 #include "src/__support/integer_utils.h"
18 #include "src/__support/macros/optimization.h" // LIBC_UNLIKELY
19 #include "src/__support/number_pair.h"
21 #include <stddef.h> // For size_t
22 #include <stdint.h>
24 namespace __llvm_libc::cpp {
26 template <size_t Bits, bool Signed> struct BigInt {
28 static_assert(Bits > 0 && Bits % 64 == 0,
29 "Number of bits in BigInt should be a multiple of 64.");
30 static LIBC_INLINE_VAR constexpr size_t WORDCOUNT = Bits / 64;
31 uint64_t val[WORDCOUNT]{};
33 static LIBC_INLINE_VAR constexpr uint64_t MASK32 = 0xFFFFFFFFu;
35 static LIBC_INLINE constexpr uint64_t low(uint64_t v) { return v & MASK32; }
36 static LIBC_INLINE constexpr uint64_t high(uint64_t v) { return (v >> 32) & MASK32; }
38 LIBC_INLINE constexpr BigInt() = default;
40 LIBC_INLINE constexpr BigInt(const BigInt<Bits, Signed> &other) = default;
42 template <size_t OtherBits, bool OtherSigned>
43 LIBC_INLINE constexpr BigInt(const BigInt<OtherBits, OtherSigned> &other) {
44 if (OtherBits >= Bits) {
45 for (size_t i = 0; i < WORDCOUNT; ++i)
46 val[i] = other[i];
47 } else {
48 size_t i = 0;
49 for (; i < OtherBits / 64; ++i)
50 val[i] = other[i];
51 uint64_t sign = 0;
52 if constexpr (Signed && OtherSigned) {
53 sign = static_cast<uint64_t>(
54 -static_cast<int64_t>(other[OtherBits / 64 - 1] >> 63));
56 for (; i < WORDCOUNT; ++i)
57 val[i] = sign;
61 // Construct a BigInt from a C array.
62 template <size_t N, enable_if_t<N <= WORDCOUNT, int> = 0>
63 LIBC_INLINE constexpr BigInt(const uint64_t (&nums)[N]) {
64 size_t min_wordcount = N < WORDCOUNT ? N : WORDCOUNT;
65 size_t i = 0;
66 for (; i < min_wordcount; ++i)
67 val[i] = nums[i];
69 // If nums doesn't completely fill val, then fill the rest with zeroes.
70 for (; i < WORDCOUNT; ++i)
71 val[i] = 0;
74 // Initialize the first word to |v| and the rest to 0.
75 template <typename T,
76 typename = cpp::enable_if_t<is_integral_v<T> && sizeof(T) <= 16>>
77 LIBC_INLINE constexpr BigInt(T v) {
78 val[0] = static_cast<uint64_t>(v);
80 if constexpr (Bits == 64)
81 return;
83 // Bits is at least 128.
84 size_t i = 1;
85 if constexpr (sizeof(T) == 16) {
86 val[1] = static_cast<uint64_t>(v >> 64);
87 i = 2;
90 uint64_t sign = (Signed && (v < 0)) ? 0xffff'ffff'ffff'ffff : 0;
91 for (; i < WORDCOUNT; ++i) {
92 val[i] = sign;
96 LIBC_INLINE constexpr explicit BigInt(const cpp::array<uint64_t, WORDCOUNT> &words) {
97 for (size_t i = 0; i < WORDCOUNT; ++i)
98 val[i] = words[i];
101 template <typename T, typename = cpp::enable_if_t<cpp::is_integral_v<T> &&
102 sizeof(T) <= 16 &&
103 !cpp::is_same_v<T, bool>>>
104 LIBC_INLINE constexpr explicit operator T() const {
105 if constexpr (sizeof(T) <= 8)
106 return static_cast<T>(val[0]);
108 // T is 128-bit.
109 T lo = static_cast<T>(val[0]);
111 if constexpr (Bits == 64) {
112 if constexpr (Signed) {
113 // Extend sign for negative numbers.
114 return (val[0] >> 63) ? ((T(-1) << 64) + lo) : lo;
115 } else {
116 return lo;
118 } else {
119 return (static_cast<T>(val[1]) << 64) + lo;
123 LIBC_INLINE constexpr explicit operator bool() const { return !is_zero(); }
125 BigInt<Bits, Signed> &operator=(const BigInt<Bits, Signed> &other) = default;
127 LIBC_INLINE constexpr bool is_zero() const {
128 for (size_t i = 0; i < WORDCOUNT; ++i) {
129 if (val[i] != 0)
130 return false;
132 return true;
135 // Add x to this number and store the result in this number.
136 // Returns the carry value produced by the addition operation.
137 LIBC_INLINE constexpr uint64_t add(const BigInt<Bits, Signed> &x) {
138 SumCarry<uint64_t> s{0, 0};
139 for (size_t i = 0; i < WORDCOUNT; ++i) {
140 s = add_with_carry_const(val[i], x.val[i], s.carry);
141 val[i] = s.sum;
143 return s.carry;
146 LIBC_INLINE constexpr BigInt<Bits, Signed> operator+(const BigInt<Bits, Signed> &other) const {
147 BigInt<Bits, Signed> result;
148 SumCarry<uint64_t> s{0, 0};
149 for (size_t i = 0; i < WORDCOUNT; ++i) {
150 s = add_with_carry(val[i], other.val[i], s.carry);
151 result.val[i] = s.sum;
153 return result;
156 // This will only apply when initializing a variable from constant values, so
157 // it will always use the constexpr version of add_with_carry.
158 LIBC_INLINE constexpr BigInt<Bits, Signed> operator+(BigInt<Bits, Signed> &&other) const {
159 BigInt<Bits, Signed> result;
160 SumCarry<uint64_t> s{0, 0};
161 for (size_t i = 0; i < WORDCOUNT; ++i) {
162 s = add_with_carry_const(val[i], other.val[i], s.carry);
163 result.val[i] = s.sum;
165 return result;
168 LIBC_INLINE constexpr BigInt<Bits, Signed> &
169 operator+=(const BigInt<Bits, Signed> &other) {
170 add(other); // Returned carry value is ignored.
171 return *this;
174 // Subtract x to this number and store the result in this number.
175 // Returns the carry value produced by the subtraction operation.
176 LIBC_INLINE constexpr uint64_t sub(const BigInt<Bits, Signed> &x) {
177 DiffBorrow<uint64_t> d{0, 0};
178 for (size_t i = 0; i < WORDCOUNT; ++i) {
179 d = sub_with_borrow_const(val[i], x.val[i], d.borrow);
180 val[i] = d.diff;
182 return d.borrow;
185 LIBC_INLINE BigInt<Bits, Signed> operator-(const BigInt<Bits, Signed> &other) const {
186 BigInt<Bits, Signed> result;
187 DiffBorrow<uint64_t> d{0, 0};
188 for (size_t i = 0; i < WORDCOUNT; ++i) {
189 d = sub_with_borrow(val[i], other.val[i], d.borrow);
190 result.val[i] = d.diff;
192 return result;
195 LIBC_INLINE constexpr BigInt<Bits, Signed> operator-(BigInt<Bits, Signed> &&other) const {
196 BigInt<Bits, Signed> result;
197 DiffBorrow<uint64_t> d{0, 0};
198 for (size_t i = 0; i < WORDCOUNT; ++i) {
199 d = sub_with_borrow_const(val[i], other.val[i], d.borrow);
200 result.val[i] = d.diff;
202 return result;
205 LIBC_INLINE constexpr BigInt<Bits, Signed> &
206 operator-=(const BigInt<Bits, Signed> &other) {
207 // TODO(lntue): Set overflow flag / errno when carry is true.
208 sub(other);
209 return *this;
212 // Multiply this number with x and store the result in this number. It is
213 // implemented using the long multiplication algorithm by splitting the
214 // 64-bit words of this number and |x| in to 32-bit halves but peforming
215 // the operations using 64-bit numbers. This ensures that we don't lose the
216 // carry bits.
217 // Returns the carry value produced by the multiplication operation.
218 LIBC_INLINE constexpr uint64_t mul(uint64_t x) {
219 BigInt<128, Signed> partial_sum(0);
220 uint64_t carry = 0;
221 for (size_t i = 0; i < WORDCOUNT; ++i) {
222 NumberPair<uint64_t> prod = full_mul(val[i], x);
223 BigInt<128, Signed> tmp({prod.lo, prod.hi});
224 carry += partial_sum.add(tmp);
225 val[i] = partial_sum.val[0];
226 partial_sum.val[0] = partial_sum.val[1];
227 partial_sum.val[1] = carry;
228 carry = 0;
230 return partial_sum.val[1];
233 LIBC_INLINE constexpr BigInt<Bits, Signed>
234 operator*(const BigInt<Bits, Signed> &other) const {
235 if constexpr (Signed) {
236 BigInt<Bits, false> a(*this);
237 BigInt<Bits, false> b(other);
238 bool a_neg = (a.val[WORDCOUNT - 1] >> 63);
239 bool b_neg = (b.val[WORDCOUNT - 1] >> 63);
240 if (a_neg)
241 a = -a;
242 if (b_neg)
243 b = -b;
244 BigInt<Bits, false> prod = a * b;
245 if (a_neg != b_neg)
246 prod = -prod;
247 return static_cast<BigInt<Bits, true>>(prod);
248 } else {
250 if constexpr (WORDCOUNT == 1) {
251 return {val[0] * other.val[0]};
252 } else {
253 BigInt<Bits, Signed> result(0);
254 BigInt<128, Signed> partial_sum(0);
255 uint64_t carry = 0;
256 for (size_t i = 0; i < WORDCOUNT; ++i) {
257 for (size_t j = 0; j <= i; j++) {
258 NumberPair<uint64_t> prod = full_mul(val[j], other.val[i - j]);
259 BigInt<128, Signed> tmp({prod.lo, prod.hi});
260 carry += partial_sum.add(tmp);
262 result.val[i] = partial_sum.val[0];
263 partial_sum.val[0] = partial_sum.val[1];
264 partial_sum.val[1] = carry;
265 carry = 0;
267 return result;
272 // Return the full product, only unsigned for now.
273 template <size_t OtherBits>
274 LIBC_INLINE constexpr BigInt<Bits + OtherBits, Signed>
275 ful_mul(const BigInt<OtherBits, Signed> &other) const {
276 BigInt<Bits + OtherBits, Signed> result(0);
277 BigInt<128, Signed> partial_sum(0);
278 uint64_t carry = 0;
279 constexpr size_t OTHER_WORDCOUNT = BigInt<OtherBits, Signed>::WORDCOUNT;
280 for (size_t i = 0; i <= WORDCOUNT + OTHER_WORDCOUNT - 2; ++i) {
281 const size_t lower_idx =
282 i < OTHER_WORDCOUNT ? 0 : i - OTHER_WORDCOUNT + 1;
283 const size_t upper_idx = i < WORDCOUNT ? i : WORDCOUNT - 1;
284 for (size_t j = lower_idx; j <= upper_idx; ++j) {
285 NumberPair<uint64_t> prod = full_mul(val[j], other.val[i - j]);
286 BigInt<128, Signed> tmp({prod.lo, prod.hi});
287 carry += partial_sum.add(tmp);
289 result.val[i] = partial_sum.val[0];
290 partial_sum.val[0] = partial_sum.val[1];
291 partial_sum.val[1] = carry;
292 carry = 0;
294 result.val[WORDCOUNT + OTHER_WORDCOUNT - 1] = partial_sum.val[0];
295 return result;
298 // Fast hi part of the full product. The normal product `operator*` returns
299 // `Bits` least significant bits of the full product, while this function will
300 // approximate `Bits` most significant bits of the full product with errors
301 // bounded by:
302 // 0 <= (a.full_mul(b) >> Bits) - a.quick_mul_hi(b)) <= WORDCOUNT - 1.
304 // An example usage of this is to quickly (but less accurately) compute the
305 // product of (normalized) mantissas of floating point numbers:
306 // (mant_1, mant_2) -> quick_mul_hi -> normalize leading bit
307 // is much more efficient than:
308 // (mant_1, mant_2) -> ful_mul -> normalize leading bit
309 // -> convert back to same Bits width by shifting/rounding,
310 // especially for higher precisions.
312 // Performance summary:
313 // Number of 64-bit x 64-bit -> 128-bit multiplications performed.
314 // Bits WORDCOUNT ful_mul quick_mul_hi Error bound
315 // 128 2 4 3 1
316 // 196 3 9 6 2
317 // 256 4 16 10 3
318 // 512 8 64 36 7
319 constexpr BigInt<Bits, Signed>
320 LIBC_INLINE quick_mul_hi(const BigInt<Bits, Signed> &other) const {
321 BigInt<Bits, Signed> result(0);
322 BigInt<128, Signed> partial_sum(0);
323 uint64_t carry = 0;
324 // First round of accumulation for those at WORDCOUNT - 1 in the full
325 // product.
326 for (size_t i = 0; i < WORDCOUNT; ++i) {
327 NumberPair<uint64_t> prod =
328 full_mul(val[i], other.val[WORDCOUNT - 1 - i]);
329 BigInt<128, Signed> tmp({prod.lo, prod.hi});
330 carry += partial_sum.add(tmp);
332 for (size_t i = WORDCOUNT; i < 2 * WORDCOUNT - 1; ++i) {
333 partial_sum.val[0] = partial_sum.val[1];
334 partial_sum.val[1] = carry;
335 carry = 0;
336 for (size_t j = i - WORDCOUNT + 1; j < WORDCOUNT; ++j) {
337 NumberPair<uint64_t> prod = full_mul(val[j], other.val[i - j]);
338 BigInt<128, Signed> tmp({prod.lo, prod.hi});
339 carry += partial_sum.add(tmp);
341 result.val[i - WORDCOUNT] = partial_sum.val[0];
343 result.val[WORDCOUNT - 1] = partial_sum.val[1];
344 return result;
347 // pow takes a power and sets this to its starting value to that power. Zero
348 // to the zeroth power returns 1.
349 LIBC_INLINE constexpr void pow_n(uint64_t power) {
350 BigInt<Bits, Signed> result = 1;
351 BigInt<Bits, Signed> cur_power = *this;
353 while (power > 0) {
354 if ((power % 2) > 0) {
355 result = result * cur_power;
357 power = power >> 1;
358 cur_power *= cur_power;
360 *this = result;
363 // TODO: Make division work correctly for signed integers.
365 // div takes another BigInt of the same size and divides this by it. The value
366 // of this will be set to the quotient, and the return value is the remainder.
367 LIBC_INLINE constexpr optional<BigInt<Bits, Signed>>
368 div(const BigInt<Bits, Signed> &other) {
369 BigInt<Bits, Signed> remainder(0);
370 if (*this < other) {
371 remainder = *this;
372 *this = BigInt<Bits, Signed>(0);
373 return remainder;
375 if (other == 1) {
376 return remainder;
378 if (other == 0) {
379 return nullopt;
382 BigInt<Bits, Signed> quotient(0);
383 BigInt<Bits, Signed> subtractor = other;
384 int cur_bit = subtractor.clz() - this->clz();
385 subtractor.shift_left(cur_bit);
387 for (; cur_bit >= 0 && *this > 0; --cur_bit, subtractor.shift_right(1)) {
388 if (*this >= subtractor) {
389 this->sub(subtractor);
390 quotient = quotient | (BigInt<Bits, Signed>(1) << cur_bit);
393 remainder = *this;
394 *this = quotient;
395 return remainder;
398 // Efficiently perform BigInt / (x * 2^e), where x is a 32-bit unsigned
399 // integer, and return the remainder. The main idea is as follow:
400 // Let q = y / (x * 2^e) be the quotient, and
401 // r = y % (x * 2^e) be the remainder.
402 // First, notice that:
403 // r % (2^e) = y % (2^e),
404 // so we just need to focus on all the bits of y that is >= 2^e.
405 // To speed up the shift-and-add steps, we only use x as the divisor, and
406 // performing 32-bit shiftings instead of bit-by-bit shiftings.
407 // Since the remainder of each division step < x < 2^32, the computation of
408 // each step is now properly contained within uint64_t.
409 // And finally we perform some extra alignment steps for the remaining bits.
410 LIBC_INLINE constexpr optional<BigInt<Bits, Signed>> div_uint32_times_pow_2(uint32_t x,
411 size_t e) {
412 BigInt<Bits, Signed> remainder(0);
414 if (x == 0) {
415 return nullopt;
417 if (e >= Bits) {
418 remainder = *this;
419 *this = BigInt<Bits, false>(0);
420 return remainder;
423 BigInt<Bits, Signed> quotient(0);
424 uint64_t x64 = static_cast<uint64_t>(x);
425 // lower64 = smallest multiple of 64 that is >= e.
426 size_t lower64 = ((e >> 6) + ((e & 63) != 0)) << 6;
427 // lower_pos is the index of the closest 64-bit chunk >= 2^e.
428 size_t lower_pos = lower64 / 64;
429 // Keep track of current remainder mod x * 2^(32*i)
430 uint64_t rem = 0;
431 // pos is the index of the current 64-bit chunk that we are processing.
432 size_t pos = WORDCOUNT;
434 for (size_t q_pos = WORDCOUNT - lower_pos; q_pos > 0; --q_pos) {
435 // q_pos is 1 + the index of the current 64-bit chunk of the quotient
436 // being processed.
437 // Performing the division / modulus with divisor:
438 // x * 2^(64*q_pos - 32),
439 // i.e. using the upper 32-bit of the current 64-bit chunk.
440 rem <<= 32;
441 rem += val[--pos] >> 32;
442 uint64_t q_tmp = rem / x64;
443 rem %= x64;
445 // Performing the division / modulus with divisor:
446 // x * 2^(64*(q_pos - 1)),
447 // i.e. using the lower 32-bit of the current 64-bit chunk.
448 rem <<= 32;
449 rem += val[pos] & MASK32;
450 quotient.val[q_pos - 1] = (q_tmp << 32) + rem / x64;
451 rem %= x64;
454 // So far, what we have is:
455 // quotient = y / (x * 2^lower64), and
456 // rem = (y % (x * 2^lower64)) / 2^lower64.
457 // If (lower64 > e), we will need to perform an extra adjustment of the
458 // quotient and remainder, namely:
459 // y / (x * 2^e) = [ y / (x * 2^lower64) ] * 2^(lower64 - e) +
460 // + (rem * 2^(lower64 - e)) / x
461 // (y % (x * 2^e)) / 2^e = (rem * 2^(lower64 - e)) % x
462 size_t last_shift = lower64 - e;
464 if (last_shift > 0) {
465 // quotient * 2^(lower64 - e)
466 quotient <<= last_shift;
467 uint64_t q_tmp = 0;
468 uint64_t d = val[--pos];
469 if (last_shift >= 32) {
470 // The shifting (rem * 2^(lower64 - e)) might overflow uint64_t, so we
471 // perform a 32-bit shift first.
472 rem <<= 32;
473 rem += d >> 32;
474 d &= MASK32;
475 q_tmp = rem / x64;
476 rem %= x64;
477 last_shift -= 32;
478 } else {
479 // Only use the upper 32-bit of the current 64-bit chunk.
480 d >>= 32;
483 if (last_shift > 0) {
484 rem <<= 32;
485 rem += d;
486 q_tmp <<= last_shift;
487 x64 <<= 32 - last_shift;
488 q_tmp += rem / x64;
489 rem %= x64;
492 quotient.val[0] += q_tmp;
494 if (lower64 - e <= 32) {
495 // The remainder rem * 2^(lower64 - e) might overflow to the higher
496 // 64-bit chunk.
497 if (pos < WORDCOUNT - 1) {
498 remainder[pos + 1] = rem >> 32;
500 remainder[pos] = (rem << 32) + (val[pos] & MASK32);
501 } else {
502 remainder[pos] = rem;
505 } else {
506 remainder[pos] = rem;
509 // Set the remaining lower bits of the remainder.
510 for (; pos > 0; --pos) {
511 remainder[pos - 1] = val[pos - 1];
514 *this = quotient;
515 return remainder;
518 LIBC_INLINE constexpr BigInt<Bits, Signed>
519 operator/(const BigInt<Bits, Signed> &other) const {
520 BigInt<Bits, Signed> result(*this);
521 result.div(other);
522 return result;
525 LIBC_INLINE constexpr BigInt<Bits, Signed> &
526 operator/=(const BigInt<Bits, Signed> &other) {
527 div(other);
528 return *this;
531 LIBC_INLINE constexpr BigInt<Bits, Signed>
532 operator%(const BigInt<Bits, Signed> &other) const {
533 BigInt<Bits, Signed> result(*this);
534 return *result.div(other);
537 LIBC_INLINE constexpr BigInt<Bits, Signed> &
538 operator*=(const BigInt<Bits, Signed> &other) {
539 *this = *this * other;
540 return *this;
543 LIBC_INLINE constexpr uint64_t clz() {
544 uint64_t leading_zeroes = 0;
545 for (size_t i = WORDCOUNT; i > 0; --i) {
546 if (val[i - 1] == 0) {
547 leading_zeroes += sizeof(uint64_t) * 8;
548 } else {
549 leading_zeroes += unsafe_clz(val[i - 1]);
550 break;
553 return leading_zeroes;
556 LIBC_INLINE constexpr void shift_left(size_t s) {
557 #ifdef __SIZEOF_INT128__
558 if constexpr (Bits == 128) {
559 // Use builtin 128 bits if available;
560 if (s >= 128) {
561 val[0] = 0;
562 val[1] = 0;
563 return;
565 __uint128_t tmp = __uint128_t(val[0]) + (__uint128_t(val[1]) << 64);
566 tmp <<= s;
567 val[0] = uint64_t(tmp);
568 val[1] = uint64_t(tmp >> 64);
569 return;
571 #endif // __SIZEOF_INT128__
572 if (LIBC_UNLIKELY(s == 0))
573 return;
575 const size_t drop = s / 64; // Number of words to drop
576 const size_t shift = s % 64; // Bits to shift in the remaining words.
577 size_t i = WORDCOUNT;
579 if (drop < WORDCOUNT) {
580 i = WORDCOUNT - 1;
581 if (shift > 0) {
582 for (size_t j = WORDCOUNT - 1 - drop; j > 0; --i, --j) {
583 val[i] = (val[j] << shift) | (val[j - 1] >> (64 - shift));
585 val[i] = val[0] << shift;
586 } else {
587 for (size_t j = WORDCOUNT - 1 - drop; j > 0; --i, --j) {
588 val[i] = val[j];
590 val[i] = val[0];
594 for (size_t j = 0; j < i; ++j) {
595 val[j] = 0;
599 LIBC_INLINE constexpr BigInt<Bits, Signed> operator<<(size_t s) const {
600 BigInt<Bits, Signed> result(*this);
601 result.shift_left(s);
602 return result;
605 LIBC_INLINE constexpr BigInt<Bits, Signed> &operator<<=(size_t s) {
606 shift_left(s);
607 return *this;
610 LIBC_INLINE constexpr void shift_right(size_t s) {
611 #ifdef __SIZEOF_INT128__
612 if constexpr (Bits == 128) {
613 // Use builtin 128 bits if available;
614 if (s >= 128) {
615 val[0] = 0;
616 val[1] = 0;
617 return;
619 __uint128_t tmp = __uint128_t(val[0]) + (__uint128_t(val[1]) << 64);
620 if constexpr (Signed) {
621 tmp = static_cast<__uint128_t>(static_cast<__int128_t>(tmp) >> s);
622 } else {
623 tmp >>= s;
625 val[0] = uint64_t(tmp);
626 val[1] = uint64_t(tmp >> 64);
627 return;
629 #endif // __SIZEOF_INT128__
631 if (LIBC_UNLIKELY(s == 0))
632 return;
633 const size_t drop = s / 64; // Number of words to drop
634 const size_t shift = s % 64; // Bit shift in the remaining words.
636 size_t i = 0;
637 uint64_t sign = Signed ? (val[WORDCOUNT - 1] >> 63) : 0;
639 if (drop < WORDCOUNT) {
640 if (shift > 0) {
641 for (size_t j = drop; j < WORDCOUNT - 1; ++i, ++j) {
642 val[i] = (val[j] >> shift) | (val[j + 1] << (64 - shift));
644 if constexpr (Signed) {
645 val[i] = static_cast<uint64_t>(
646 static_cast<int64_t>(val[WORDCOUNT - 1]) >> shift);
647 } else {
648 val[i] = val[WORDCOUNT - 1] >> shift;
650 ++i;
651 } else {
652 for (size_t j = drop; j < WORDCOUNT; ++i, ++j) {
653 val[i] = val[j];
658 for (; i < WORDCOUNT; ++i) {
659 val[i] = sign;
663 LIBC_INLINE constexpr BigInt<Bits, Signed> operator>>(size_t s) const {
664 BigInt<Bits, Signed> result(*this);
665 result.shift_right(s);
666 return result;
669 LIBC_INLINE constexpr BigInt<Bits, Signed> &operator>>=(size_t s) {
670 shift_right(s);
671 return *this;
674 LIBC_INLINE constexpr BigInt<Bits, Signed>
675 operator&(const BigInt<Bits, Signed> &other) const {
676 BigInt<Bits, Signed> result;
677 for (size_t i = 0; i < WORDCOUNT; ++i)
678 result.val[i] = val[i] & other.val[i];
679 return result;
682 LIBC_INLINE constexpr BigInt<Bits, Signed> &
683 operator&=(const BigInt<Bits, Signed> &other) {
684 for (size_t i = 0; i < WORDCOUNT; ++i)
685 val[i] &= other.val[i];
686 return *this;
689 LIBC_INLINE constexpr BigInt<Bits, Signed>
690 operator|(const BigInt<Bits, Signed> &other) const {
691 BigInt<Bits, Signed> result;
692 for (size_t i = 0; i < WORDCOUNT; ++i)
693 result.val[i] = val[i] | other.val[i];
694 return result;
697 LIBC_INLINE constexpr BigInt<Bits, Signed> &
698 operator|=(const BigInt<Bits, Signed> &other) {
699 for (size_t i = 0; i < WORDCOUNT; ++i)
700 val[i] |= other.val[i];
701 return *this;
704 LIBC_INLINE constexpr BigInt<Bits, Signed>
705 operator^(const BigInt<Bits, Signed> &other) const {
706 BigInt<Bits, Signed> result;
707 for (size_t i = 0; i < WORDCOUNT; ++i)
708 result.val[i] = val[i] ^ other.val[i];
709 return result;
712 LIBC_INLINE constexpr BigInt<Bits, Signed> &
713 operator^=(const BigInt<Bits, Signed> &other) {
714 for (size_t i = 0; i < WORDCOUNT; ++i)
715 val[i] ^= other.val[i];
716 return *this;
719 LIBC_INLINE constexpr BigInt<Bits, Signed> operator~() const {
720 BigInt<Bits, Signed> result;
721 for (size_t i = 0; i < WORDCOUNT; ++i)
722 result.val[i] = ~val[i];
723 return result;
726 LIBC_INLINE constexpr BigInt<Bits, Signed> operator-() const {
727 BigInt<Bits, Signed> result = ~(*this);
728 result.add(BigInt<Bits, Signed>(1));
729 return result;
732 LIBC_INLINE constexpr bool operator==(const BigInt<Bits, Signed> &other) const {
733 for (size_t i = 0; i < WORDCOUNT; ++i) {
734 if (val[i] != other.val[i])
735 return false;
737 return true;
740 LIBC_INLINE constexpr bool operator!=(const BigInt<Bits, Signed> &other) const {
741 for (size_t i = 0; i < WORDCOUNT; ++i) {
742 if (val[i] != other.val[i])
743 return true;
745 return false;
748 LIBC_INLINE constexpr bool operator>(const BigInt<Bits, Signed> &other) const {
749 if constexpr (Signed) {
750 // Check for different signs;
751 bool a_sign = val[WORDCOUNT - 1] >> 63;
752 bool b_sign = other.val[WORDCOUNT - 1] >> 63;
753 if (a_sign != b_sign) {
754 return b_sign;
757 for (size_t i = WORDCOUNT; i > 0; --i) {
758 uint64_t word = val[i - 1];
759 uint64_t other_word = other.val[i - 1];
760 if (word > other_word)
761 return true;
762 else if (word < other_word)
763 return false;
765 // Equal
766 return false;
769 LIBC_INLINE constexpr bool operator>=(const BigInt<Bits, Signed> &other) const {
770 if constexpr (Signed) {
771 // Check for different signs;
772 bool a_sign = val[WORDCOUNT - 1] >> 63;
773 bool b_sign = other.val[WORDCOUNT - 1] >> 63;
774 if (a_sign != b_sign) {
775 return b_sign;
778 for (size_t i = WORDCOUNT; i > 0; --i) {
779 uint64_t word = val[i - 1];
780 uint64_t other_word = other.val[i - 1];
781 if (word > other_word)
782 return true;
783 else if (word < other_word)
784 return false;
786 // Equal
787 return true;
790 LIBC_INLINE constexpr bool operator<(const BigInt<Bits, Signed> &other) const {
791 if constexpr (Signed) {
792 // Check for different signs;
793 bool a_sign = val[WORDCOUNT - 1] >> 63;
794 bool b_sign = other.val[WORDCOUNT - 1] >> 63;
795 if (a_sign != b_sign) {
796 return a_sign;
800 for (size_t i = WORDCOUNT; i > 0; --i) {
801 uint64_t word = val[i - 1];
802 uint64_t other_word = other.val[i - 1];
803 if (word > other_word)
804 return false;
805 else if (word < other_word)
806 return true;
808 // Equal
809 return false;
812 LIBC_INLINE constexpr bool operator<=(const BigInt<Bits, Signed> &other) const {
813 if constexpr (Signed) {
814 // Check for different signs;
815 bool a_sign = val[WORDCOUNT - 1] >> 63;
816 bool b_sign = other.val[WORDCOUNT - 1] >> 63;
817 if (a_sign != b_sign) {
818 return a_sign;
821 for (size_t i = WORDCOUNT; i > 0; --i) {
822 uint64_t word = val[i - 1];
823 uint64_t other_word = other.val[i - 1];
824 if (word > other_word)
825 return false;
826 else if (word < other_word)
827 return true;
829 // Equal
830 return true;
833 LIBC_INLINE constexpr BigInt<Bits, Signed> &operator++() {
834 BigInt<Bits, Signed> one(1);
835 add(one);
836 return *this;
839 LIBC_INLINE constexpr BigInt<Bits, Signed> operator++(int) {
840 BigInt<Bits, Signed> oldval(*this);
841 BigInt<Bits, Signed> one(1);
842 add(one);
843 return oldval;
846 LIBC_INLINE constexpr BigInt<Bits, Signed> &operator--() {
847 BigInt<Bits, Signed> one(1);
848 sub(one);
849 return *this;
852 LIBC_INLINE constexpr BigInt<Bits, Signed> operator--(int) {
853 BigInt<Bits, Signed> oldval(*this);
854 BigInt<Bits, Signed> one(1);
855 sub(one);
856 return oldval;
859 // Return the i-th 64-bit word of the number.
860 LIBC_INLINE constexpr const uint64_t &operator[](size_t i) const { return val[i]; }
862 // Return the i-th 64-bit word of the number.
863 LIBC_INLINE constexpr uint64_t &operator[](size_t i) { return val[i]; }
865 LIBC_INLINE uint64_t *data() { return val; }
867 LIBC_INLINE const uint64_t *data() const { return val; }
870 template <size_t Bits> using UInt = BigInt<Bits, false>;
872 template <size_t Bits> using Int = BigInt<Bits, true>;
874 // Provides limits of U/Int<128>.
875 template <> class numeric_limits<UInt<128>> {
876 public:
877 LIBC_INLINE static constexpr UInt<128> max() {
878 return UInt<128>({0xffff'ffff'ffff'ffff, 0xffff'ffff'ffff'ffff});
880 static constexpr UInt<128> min() { return UInt<128>(0); }
883 template <> class numeric_limits<Int<128>> {
884 public:
885 LIBC_INLINE static constexpr Int<128> max() {
886 return Int<128>({0xffff'ffff'ffff'ffff, 0x7fff'ffff'ffff'ffff});
888 LIBC_INLINE static constexpr Int<128> min() {
889 return Int<128>({0, 0x8000'0000'0000'0000});
893 // Provides is_integral of U/Int<128>, U/Int<192>, U/Int<256>.
894 template <size_t Bits, bool Signed>
895 struct is_integral<BigInt<Bits, Signed>> : cpp::true_type {
896 static_assert(Bits > 0 && Bits % 64 == 0,
897 "Number of bits in BigInt should be a multiple of 64.");
900 // Provides is_unsigned of UInt<128>, UInt<192>, UInt<256>.
901 template <size_t Bits> struct is_unsigned<UInt<Bits>> : public cpp::true_type {
902 static_assert(Bits > 0 && Bits % 64 == 0,
903 "Number of bits in UInt should be a multiple of 64.");
906 template <size_t Bits>
907 struct make_unsigned<Int<Bits>> : type_identity<UInt<Bits>> {
908 static_assert(Bits > 0 && Bits % 64 == 0,
909 "Number of bits in Int should be a multiple of 64.");
912 } // namespace __llvm_libc::cpp
914 #endif // LLVM_LIBC_SRC_SUPPORT_UINT_H