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" |