diff options
Diffstat (limited to '')
| -rw-r--r-- | common.h | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/common.h b/common.h new file mode 100644 index 0000000..b299fd1 --- /dev/null +++ b/common.h @@ -0,0 +1,91 @@ +/* See LICENSE file for copyright and license details. */ +#include "libquanta.h" +#include <errno.h> +#include <limits.h> +#include <math.h> +#include <stdlib.h> + + +#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); +} |
