/* See LICENSE file for copyright and license details. */ #include "libquanta.h" #include #include #include #include #include #define PALETTE_BASE_SIZE offsetof(struct libquanta_palette, palette) #define PALETTE_VALUE_TYPE uint64_t #define PALETTE_VALUE_SIZE sizeof(PALETTE_VALUE_TYPE) #define PALETTE_VALUE_MAX_BITS 64U struct bigint { uintmax_t high, low; }; #if defined(__GNUC__) __attribute__((__visibility__("hidden"))) #endif uintmax_t libquanta_bigint_divmod_small__(struct bigint *big, uintmax_t small); #define bigint_divmod_small libquanta_bigint_divmod_small__ static inline void bigint_add_small(struct bigint *big, uintmax_t small) { #if defined(__GNUC__) if (__builtin_add_overflow(big->low, small, &big->low)) big->high += 1U; #else if (big->low > UINTMAX_MAX - small) big->high += 1U; big->low += small; #endif } static inline void bigint_sub_small(struct bigint *big, uintmax_t small) { #if defined(__GNUC__) if (__builtin_sub_overflow(big->low, small, &big->low)) big->high -= 1U; #else if (big->low < small) big->high -= 1U; big->low -= small; #endif } static inline void bigint_add_big(struct bigint *res, const struct bigint *restrict other) { bigint_add_small(res, other->low); res->high += other->high; } static inline void bigint_sub_big(struct bigint *res, const struct bigint *restrict other) { bigint_sub_small(res, other->low); res->high -= other->high; } static inline void bigint_rsub_big(struct bigint *res, const struct bigint *restrict other) { res->high = other->high - res->high; #if defined(__GNUC__) if (__builtin_sub_overflow(other->low, res->low, &res->low)) res->high -= 1U; #else if (res->low > other->low) res->high -= 1U; res->low = other->low - res->low; #endif } static inline uintmax_t bigint_div_small(const struct bigint *big, uintmax_t small) { struct bigint big_copy = *big; return bigint_divmod_small(&big_copy, small); }