| internals.h - libzahl - big integer library | |
| git clone git://git.suckless.org/libzahl | |
| Log | |
| Files | |
| Refs | |
| README | |
| LICENSE | |
| --- | |
| internals.h (4450B) | |
| --- | |
| 1 /* See LICENSE file for copyright and license details. */ | |
| 2 | |
| 3 #ifndef ZAHL_INLINE | |
| 4 # if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L | |
| 5 # define ZAHL_INLINE static inline | |
| 6 # else | |
| 7 # define ZAHL_INLINE static | |
| 8 # endif | |
| 9 #endif | |
| 10 | |
| 11 | |
| 12 #if defined(__GNUC__) || defined(__clang__) | |
| 13 # define ZAHL_LIKELY(expr) __builtin_expect(!!(expr), 1) | |
| 14 # define ZAHL_UNLIKELY(expr) __builtin_expect(!!(expr), 0) | |
| 15 # define ZAHL_CONST_P(value) __builtin_constant_p(value) | |
| 16 #else | |
| 17 # define ZAHL_LIKELY(expr) (expr) | |
| 18 # define ZAHL_UNLIKELY(expr) (expr) | |
| 19 #endif | |
| 20 | |
| 21 | |
| 22 #if defined(__GNUC__) && !defined(__clang__) | |
| 23 # define ZAHL_O0 __attribute__((__optimize__("O0"))) | |
| 24 # define ZAHL_O1 __attribute__((__optimize__("O1"))) | |
| 25 # define ZAHL_O2 __attribute__((__optimize__("O2"))) | |
| 26 # define ZAHL_O3 __attribute__((__optimize__("O3"))) | |
| 27 # define ZAHL_Ofast __attribute__((__optimize__("Ofast"))) | |
| 28 # define ZAHL_Os __attribute__((__optimize__("Os"))) | |
| 29 # define ZAHL_Oz __attribute__((__optimize__("Os"))) | |
| 30 #elif defined(__clang__) | |
| 31 # define ZAHL_O0 __attribute__((__optnone__)) | |
| 32 # define ZAHL_O1 /* Don't know how. */ | |
| 33 # define ZAHL_O2 /* Don't know how. */ | |
| 34 # define ZAHL_O3 /* Don't know how. */ | |
| 35 # define ZAHL_Ofast /* Don't know how. */ | |
| 36 # define ZAHL_Os /* Don't know how. */ | |
| 37 # define ZAHL_Oz /* Don't know how. */ | |
| 38 #else | |
| 39 # define ZAHL_O0 /* Don't know how. */ | |
| 40 # define ZAHL_O1 /* Don't know how. */ | |
| 41 # define ZAHL_O2 /* Don't know how. */ | |
| 42 # define ZAHL_O3 /* Don't know how. */ | |
| 43 # define ZAHL_Ofast /* Don't know how. */ | |
| 44 # define ZAHL_Os /* Don't know how. */ | |
| 45 # define ZAHL_Oz /* Don't know how. */ | |
| 46 #endif | |
| 47 /* Mostly ZAHL_O2, but sometimes ZAHL_O3, are useful. | |
| 48 * But note, often it optimal to not use any of them. */ | |
| 49 | |
| 50 | |
| 51 #define ZAHL_BITS_PER_CHAR 64 | |
| 52 #define ZAHL_LB_BITS_PER_CHAR 6 | |
| 53 #define ZAHL_CHAR_MAX UINT64_MAX | |
| 54 #define ZAHL_FLUFF 4 | |
| 55 /* Note: These cannot be changed willy-nilly, some code depends | |
| 56 * on them, be cause being flexible would just be too painful. */ | |
| 57 | |
| 58 | |
| 59 #define ZAHL_FLOOR_BITS_TO_CHARS(bits) ((bits) >> ZAHL_LB_BITS_PER_CH… | |
| 60 #define ZAHL_CEILING_BITS_TO_CHARS(bits) (((bits) + (ZAHL_BITS_PER_CHAR… | |
| 61 #define ZAHL_BITS_IN_LAST_CHAR(bits) ((bits) & (ZAHL_BITS_PER_CHAR … | |
| 62 #define ZAHL_TRUNCATE_TO_CHAR(bits) ((bits) & ~(size_t)(ZAHL_BITS_… | |
| 63 | |
| 64 | |
| 65 #define ZAHL_SET_SIGNUM(a, signum) ((a)->sign = (signum)) | |
| 66 #define ZAHL_SET(a, b) do { if ((a) != (b)) zset(a, b… | |
| 67 #define ZAHL_ENSURE_SIZE(a, n) do { if ((a)->alloced < (n)) l… | |
| 68 #define ZAHL_TRIM(a) for (; (a)->used && !(a)->char… | |
| 69 #define ZAHL_TRIM_NONZERO(a) for (; !(a)->chars[(a)->used -… | |
| 70 #define ZAHL_TRIM_AND_ZERO(a) do { ZAHL_TRIM(a); if (!(a)->u… | |
| 71 #define ZAHL_TRIM_AND_SIGN(a, s) do { ZAHL_TRIM(a); ZAHL_SET_SI… | |
| 72 #define ZAHL_SWAP(a, b, t, m) ((t)->m = (a)->m, (a)->m = (b)… | |
| 73 | |
| 74 | |
| 75 #if defined(__GNUC__) || defined(__clang__) | |
| 76 # if ZAHL_CHAR_MAX == LONG_MAX | |
| 77 # define ZAHL_ADD_CTZ(r, x) ((r) += (size_t)__builtin_ctzl(x)) | |
| 78 # define ZAHL_SUB_CLZ(r, x) ((r) -= (size_t)__builtin_clzl(x)) | |
| 79 # else | |
| 80 # define ZAHL_ADD_CTZ(r, x) ((r) += (size_t)__builtin_ctzll(x)) | |
| 81 # define ZAHL_SUB_CLZ(r, x) ((r) -= (size_t)__builtin_clzll(x)) | |
| 82 # endif | |
| 83 #else | |
| 84 # define ZAHL_ADD_CTZ(r, x) \ | |
| 85 do { \ | |
| 86 zahl_char_t zahl_x__ = (x); \ | |
| 87 for (; zahl_x__ & 1; zahl_x__ >>= 1, (r)++); \ | |
| 88 } while (0) | |
| 89 # define ZAHL_SUB_CLZ(r, x) \ | |
| 90 do { \ | |
| 91 zahl_char_t zahl_x__ = (x); \ | |
| 92 (r) -= 8 * sizeof(zahl_char_t); \ | |
| 93 for (; zahl_x__; zahl_x__ >>= 1, (r)++); \ | |
| 94 } while (0) | |
| 95 #endif | |
| 96 | |
| 97 | |
| 98 typedef uint64_t zahl_char_t; | |
| 99 | |
| 100 struct zahl { | |
| 101 int sign; | |
| 102 #if INT_MAX != LONG_MAX | |
| 103 int padding__; | |
| 104 #endif | |
| 105 size_t used; | |
| 106 size_t alloced; | |
| 107 zahl_char_t *chars; | |
| 108 }; | |
| 109 | |
| 110 | |
| 111 extern struct zahl libzahl_tmp_div[1]; | |
| 112 extern struct zahl libzahl_tmp_mod[1]; | |
| 113 | |
| 114 | |
| 115 void libzahl_realloc(struct zahl *, size_t); | |
| 116 | |
| 117 #include "memory.h" |