authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-26 21:55:45-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-27 10:26:45-07:00
log0527b441ae0e90e0b97052594cabb78129a02782
tree2660367cc8b5cd3b0fdff686f9aaccaf31a44296
parentc6f5832bb61841d5be4f77adc38fbc4561bb5057

move zig.h to become an installation file

Now instead of zig.h being baked into the compiler binary, it is a header file distributed along with all the other header files distributed with Zig. Closes #11643

4 files changed, 1600 insertions(+), 1601 deletions(-)

CMakeLists.txt-1
......@@ -749,7 +749,6 @@ set(ZIG_STAGE2_SOURCES
749749 "${CMAKE_SOURCE_DIR}/src/libunwind.zig"
750750 "${CMAKE_SOURCE_DIR}/src/link.zig"
751751 "${CMAKE_SOURCE_DIR}/src/link/C.zig"
752 "${CMAKE_SOURCE_DIR}/src/link/C/zig.h"
753752 "${CMAKE_SOURCE_DIR}/src/link/Coff.zig"
754753 "${CMAKE_SOURCE_DIR}/src/link/Elf.zig"
755754 "${CMAKE_SOURCE_DIR}/src/link/MachO.zig"
lib/include/zig.h created+1599
......@@ -0,0 +1,1599 @@
1#undef linux
2
3#if __STDC_VERSION__ >= 201112L
4#define zig_noreturn _Noreturn
5#define zig_threadlocal thread_local
6#elif __GNUC__
7#define zig_noreturn __attribute__ ((noreturn))
8#define zig_threadlocal __thread
9#elif _MSC_VER
10#define zig_noreturn __declspec(noreturn)
11#define zig_threadlocal __declspec(thread)
12#else
13#define zig_noreturn
14#define zig_threadlocal zig_threadlocal_unavailable
15#endif
16
17#if __GNUC__
18#define ZIG_COLD __attribute__ ((cold))
19#else
20#define ZIG_COLD
21#endif
22
23#if __STDC_VERSION__ >= 199901L
24#define ZIG_RESTRICT restrict
25#elif defined(__GNUC__)
26#define ZIG_RESTRICT __restrict
27#else
28#define ZIG_RESTRICT
29#endif
30
31#if __STDC_VERSION__ >= 201112L
32#include <stdalign.h>
33#define ZIG_ALIGN(alignment) alignas(alignment)
34#elif defined(__GNUC__)
35#define ZIG_ALIGN(alignment) __attribute__((aligned(alignment)))
36#else
37#define ZIG_ALIGN(alignment) zig_compile_error("the C compiler being used does not support aligning variables")
38#endif
39
40#if __STDC_VERSION__ >= 199901L
41#include <stdbool.h>
42#else
43#define bool unsigned char
44#define true 1
45#define false 0
46#endif
47
48#if defined(__GNUC__)
49#define zig_unreachable() __builtin_unreachable()
50#else
51#define zig_unreachable()
52#endif
53
54#ifdef __cplusplus
55#define ZIG_EXTERN_C extern "C"
56#else
57#define ZIG_EXTERN_C
58#endif
59
60#if defined(_MSC_VER)
61#define zig_breakpoint() __debugbreak()
62#elif defined(__MINGW32__) || defined(__MINGW64__)
63#define zig_breakpoint() __debugbreak()
64#elif defined(__clang__)
65#define zig_breakpoint() __builtin_debugtrap()
66#elif defined(__GNUC__)
67#define zig_breakpoint() __builtin_trap()
68#elif defined(__i386__) || defined(__x86_64__)
69#define zig_breakpoint() __asm__ volatile("int $0x03");
70#else
71#define zig_breakpoint() raise(SIGTRAP)
72#endif
73
74#if defined(_MSC_VER)
75#define zig_return_address() _ReturnAddress()
76#elif defined(__GNUC__)
77#define zig_return_address() __builtin_extract_return_addr(__builtin_return_address(0))
78#else
79#define zig_return_address() 0
80#endif
81
82#if defined(__GNUC__)
83#define zig_frame_address() __builtin_frame_address(0)
84#else
85#define zig_frame_address() 0
86#endif
87
88#if defined(__GNUC__)
89#define zig_prefetch(addr, rw, locality) __builtin_prefetch(addr, rw, locality)
90#else
91#define zig_prefetch(addr, rw, locality)
92#endif
93
94#if defined(__clang__)
95#define zig_wasm_memory_size(index) __builtin_wasm_memory_size(index)
96#define zig_wasm_memory_grow(index, delta) __builtin_wasm_memory_grow(index, delta)
97#else
98#define zig_wasm_memory_size(index) zig_unimplemented()
99#define zig_wasm_memory_grow(index, delta) zig_unimplemented()
100#endif
101
102#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
103#include <stdatomic.h>
104#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)
105#define zig_cmpxchg_weak (obj, expected, desired, succ, fail) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)
106#define zig_atomicrmw_xchg(obj, arg, order) atomic_exchange_explicit (obj, arg, order)
107#define zig_atomicrmw_add (obj, arg, order) atomic_fetch_add_explicit (obj, arg, order)
108#define zig_atomicrmw_sub (obj, arg, order) atomic_fetch_sub_explicit (obj, arg, order)
109#define zig_atomicrmw_or (obj, arg, order) atomic_fetch_or_explicit (obj, arg, order)
110#define zig_atomicrmw_xor (obj, arg, order) atomic_fetch_xor_explicit (obj, arg, order)
111#define zig_atomicrmw_and (obj, arg, order) atomic_fetch_and_explicit (obj, arg, order)
112#define zig_atomicrmw_nand(obj, arg, order) atomic_fetch_nand_explicit(obj, arg, order)
113#define zig_atomicrmw_min (obj, arg, order) atomic_fetch_min_explicit (obj, arg, order)
114#define zig_atomicrmw_max (obj, arg, order) atomic_fetch_max_explicit (obj, arg, order)
115#define zig_atomic_store (obj, arg, order) atomic_store_explicit (obj, arg, order)
116#define zig_atomic_load (obj, order) atomic_load_explicit (obj, order)
117#define zig_fence(order) atomic_thread_fence(order)
118#elif __GNUC__
119#define memory_order_relaxed __ATOMIC_RELAXED
120#define memory_order_consume __ATOMIC_CONSUME
121#define memory_order_acquire __ATOMIC_ACQUIRE
122#define memory_order_release __ATOMIC_RELEASE
123#define memory_order_acq_rel __ATOMIC_ACQ_REL
124#define memory_order_seq_cst __ATOMIC_SEQ_CST
125#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) __atomic_compare_exchange_n(obj, &(expected), desired, false, succ, fail)
126#define zig_cmpxchg_weak (obj, expected, desired, succ, fail) __atomic_compare_exchange_n(obj, &(expected), desired, true , succ, fail)
127#define zig_atomicrmw_xchg(obj, arg, order) __atomic_exchange_n(obj, arg, order)
128#define zig_atomicrmw_add (obj, arg, order) __atomic_fetch_add (obj, arg, order)
129#define zig_atomicrmw_sub (obj, arg, order) __atomic_fetch_sub (obj, arg, order)
130#define zig_atomicrmw_or (obj, arg, order) __atomic_fetch_or (obj, arg, order)
131#define zig_atomicrmw_xor (obj, arg, order) __atomic_fetch_xor (obj, arg, order)
132#define zig_atomicrmw_and (obj, arg, order) __atomic_fetch_and (obj, arg, order)
133#define zig_atomicrmw_nand(obj, arg, order) __atomic_fetch_nand(obj, arg, order)
134#define zig_atomicrmw_min (obj, arg, order) __atomic_fetch_min (obj, arg, order)
135#define zig_atomicrmw_max (obj, arg, order) __atomic_fetch_max (obj, arg, order)
136#define zig_atomic_store (obj, arg, order) __atomic_store (obj, arg, order)
137#define zig_atomic_load (obj, order) __atomic_load (obj, order)
138#define zig_fence(order) __atomic_thread_fence(order)
139#else
140#define memory_order_relaxed 0
141#define memory_order_consume 1
142#define memory_order_acquire 2
143#define memory_order_release 3
144#define memory_order_acq_rel 4
145#define memory_order_seq_cst 5
146#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) zig_unimplemented()
147#define zig_cmpxchg_weak (obj, expected, desired, succ, fail) zig_unimplemented()
148#define zig_atomicrmw_xchg(obj, arg, order) zig_unimplemented()
149#define zig_atomicrmw_add (obj, arg, order) zig_unimplemented()
150#define zig_atomicrmw_sub (obj, arg, order) zig_unimplemented()
151#define zig_atomicrmw_or (obj, arg, order) zig_unimplemented()
152#define zig_atomicrmw_xor (obj, arg, order) zig_unimplemented()
153#define zig_atomicrmw_and (obj, arg, order) zig_unimplemented()
154#define zig_atomicrmw_nand(obj, arg, order) zig_unimplemented()
155#define zig_atomicrmw_min (obj, arg, order) zig_unimplemented()
156#define zig_atomicrmw_max (obj, arg, order) zig_unimplemented()
157#define zig_atomic_store (obj, arg, order) zig_unimplemented()
158#define zig_atomic_load (obj, order) zig_unimplemented()
159#define zig_fence(order) zig_unimplemented()
160#endif
161
162#include <stdint.h>
163#include <stddef.h>
164#include <limits.h>
165
166#define int128_t __int128
167#define uint128_t unsigned __int128
168#define UINT128_MAX ((uint128_t)(0xffffffffffffffffull) | 0xffffffffffffffffull)
169ZIG_EXTERN_C void *memcpy (void *ZIG_RESTRICT, const void *ZIG_RESTRICT, size_t);
170ZIG_EXTERN_C void *memset (void *, int, size_t);
171ZIG_EXTERN_C int64_t __addodi4(int64_t lhs, int64_t rhs, int *overflow);
172ZIG_EXTERN_C int128_t __addoti4(int128_t lhs, int128_t rhs, int *overflow);
173ZIG_EXTERN_C uint64_t __uaddodi4(uint64_t lhs, uint64_t rhs, int *overflow);
174ZIG_EXTERN_C uint128_t __uaddoti4(uint128_t lhs, uint128_t rhs, int *overflow);
175ZIG_EXTERN_C int32_t __subosi4(int32_t lhs, int32_t rhs, int *overflow);
176ZIG_EXTERN_C int64_t __subodi4(int64_t lhs, int64_t rhs, int *overflow);
177ZIG_EXTERN_C int128_t __suboti4(int128_t lhs, int128_t rhs, int *overflow);
178ZIG_EXTERN_C uint32_t __usubosi4(uint32_t lhs, uint32_t rhs, int *overflow);
179ZIG_EXTERN_C uint64_t __usubodi4(uint64_t lhs, uint64_t rhs, int *overflow);
180ZIG_EXTERN_C uint128_t __usuboti4(uint128_t lhs, uint128_t rhs, int *overflow);
181ZIG_EXTERN_C int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow);
182ZIG_EXTERN_C int128_t __muloti4(int128_t lhs, int128_t rhs, int *overflow);
183ZIG_EXTERN_C uint64_t __umulodi4(uint64_t lhs, uint64_t rhs, int *overflow);
184ZIG_EXTERN_C uint128_t __umuloti4(uint128_t lhs, uint128_t rhs, int *overflow);
185
186
187static inline uint8_t zig_addw_u8(uint8_t lhs, uint8_t rhs, uint8_t max) {
188 uint8_t thresh = max - rhs;
189 if (lhs > thresh) {
190 return lhs - thresh - 1;
191 } else {
192 return lhs + rhs;
193 }
194}
195
196static inline int8_t zig_addw_i8(int8_t lhs, int8_t rhs, int8_t min, int8_t max) {
197 if ((lhs > 0) && (rhs > 0)) {
198 int8_t thresh = max - rhs;
199 if (lhs > thresh) {
200 return min + lhs - thresh - 1;
201 }
202 } else if ((lhs < 0) && (rhs < 0)) {
203 int8_t thresh = min - rhs;
204 if (lhs < thresh) {
205 return max + lhs - thresh + 1;
206 }
207 }
208 return lhs + rhs;
209}
210
211static inline uint16_t zig_addw_u16(uint16_t lhs, uint16_t rhs, uint16_t max) {
212 uint16_t thresh = max - rhs;
213 if (lhs > thresh) {
214 return lhs - thresh - 1;
215 } else {
216 return lhs + rhs;
217 }
218}
219
220static inline int16_t zig_addw_i16(int16_t lhs, int16_t rhs, int16_t min, int16_t max) {
221 if ((lhs > 0) && (rhs > 0)) {
222 int16_t thresh = max - rhs;
223 if (lhs > thresh) {
224 return min + lhs - thresh - 1;
225 }
226 } else if ((lhs < 0) && (rhs < 0)) {
227 int16_t thresh = min - rhs;
228 if (lhs < thresh) {
229 return max + lhs - thresh + 1;
230 }
231 }
232 return lhs + rhs;
233}
234
235static inline uint32_t zig_addw_u32(uint32_t lhs, uint32_t rhs, uint32_t max) {
236 uint32_t thresh = max - rhs;
237 if (lhs > thresh) {
238 return lhs - thresh - 1;
239 } else {
240 return lhs + rhs;
241 }
242}
243
244static inline int32_t zig_addw_i32(int32_t lhs, int32_t rhs, int32_t min, int32_t max) {
245 if ((lhs > 0) && (rhs > 0)) {
246 int32_t thresh = max - rhs;
247 if (lhs > thresh) {
248 return min + lhs - thresh - 1;
249 }
250 } else if ((lhs < 0) && (rhs < 0)) {
251 int32_t thresh = min - rhs;
252 if (lhs < thresh) {
253 return max + lhs - thresh + 1;
254 }
255 }
256 return lhs + rhs;
257}
258
259static inline uint64_t zig_addw_u64(uint64_t lhs, uint64_t rhs, uint64_t max) {
260 uint64_t thresh = max - rhs;
261 if (lhs > thresh) {
262 return lhs - thresh - 1;
263 } else {
264 return lhs + rhs;
265 }
266}
267
268static inline int64_t zig_addw_i64(int64_t lhs, int64_t rhs, int64_t min, int64_t max) {
269 if ((lhs > 0) && (rhs > 0)) {
270 int64_t thresh = max - rhs;
271 if (lhs > thresh) {
272 return min + lhs - thresh - 1;
273 }
274 } else if ((lhs < 0) && (rhs < 0)) {
275 int64_t thresh = min - rhs;
276 if (lhs < thresh) {
277 return max + lhs - thresh + 1;
278 }
279 }
280 return lhs + rhs;
281}
282
283static inline intptr_t zig_addw_isize(intptr_t lhs, intptr_t rhs, intptr_t min, intptr_t max) {
284 return (intptr_t)(((uintptr_t)lhs) + ((uintptr_t)rhs));
285}
286
287static inline short zig_addw_short(short lhs, short rhs, short min, short max) {
288 return (short)(((unsigned short)lhs) + ((unsigned short)rhs));
289}
290
291static inline int zig_addw_int(int lhs, int rhs, int min, int max) {
292 return (int)(((unsigned)lhs) + ((unsigned)rhs));
293}
294
295static inline long zig_addw_long(long lhs, long rhs, long min, long max) {
296 return (long)(((unsigned long)lhs) + ((unsigned long)rhs));
297}
298
299static inline long long zig_addw_longlong(long long lhs, long long rhs, long long min, long long max) {
300 return (long long)(((unsigned long long)lhs) + ((unsigned long long)rhs));
301}
302
303static inline uint8_t zig_subw_u8(uint8_t lhs, uint8_t rhs, uint8_t max) {
304 if (lhs < rhs) {
305 return max - rhs - lhs + 1;
306 } else {
307 return lhs - rhs;
308 }
309}
310
311static inline int8_t zig_subw_i8(int8_t lhs, int8_t rhs, int8_t min, int8_t max) {
312 if ((lhs > 0) && (rhs < 0)) {
313 int8_t thresh = lhs - max;
314 if (rhs < thresh) {
315 return min + (thresh - rhs - 1);
316 }
317 } else if ((lhs < 0) && (rhs > 0)) {
318 int8_t thresh = lhs - min;
319 if (rhs > thresh) {
320 return max - (rhs - thresh - 1);
321 }
322 }
323 return lhs - rhs;
324}
325
326static inline uint16_t zig_subw_u16(uint16_t lhs, uint16_t rhs, uint16_t max) {
327 if (lhs < rhs) {
328 return max - rhs - lhs + 1;
329 } else {
330 return lhs - rhs;
331 }
332}
333
334static inline int16_t zig_subw_i16(int16_t lhs, int16_t rhs, int16_t min, int16_t max) {
335 if ((lhs > 0) && (rhs < 0)) {
336 int16_t thresh = lhs - max;
337 if (rhs < thresh) {
338 return min + (thresh - rhs - 1);
339 }
340 } else if ((lhs < 0) && (rhs > 0)) {
341 int16_t thresh = lhs - min;
342 if (rhs > thresh) {
343 return max - (rhs - thresh - 1);
344 }
345 }
346 return lhs - rhs;
347}
348
349static inline uint32_t zig_subw_u32(uint32_t lhs, uint32_t rhs, uint32_t max) {
350 if (lhs < rhs) {
351 return max - rhs - lhs + 1;
352 } else {
353 return lhs - rhs;
354 }
355}
356
357static inline int32_t zig_subw_i32(int32_t lhs, int32_t rhs, int32_t min, int32_t max) {
358 if ((lhs > 0) && (rhs < 0)) {
359 int32_t thresh = lhs - max;
360 if (rhs < thresh) {
361 return min + (thresh - rhs - 1);
362 }
363 } else if ((lhs < 0) && (rhs > 0)) {
364 int32_t thresh = lhs - min;
365 if (rhs > thresh) {
366 return max - (rhs - thresh - 1);
367 }
368 }
369 return lhs - rhs;
370}
371
372static inline uint64_t zig_subw_u64(uint64_t lhs, uint64_t rhs, uint64_t max) {
373 if (lhs < rhs) {
374 return max - rhs - lhs + 1;
375 } else {
376 return lhs - rhs;
377 }
378}
379
380static inline int64_t zig_subw_i64(int64_t lhs, int64_t rhs, int64_t min, int64_t max) {
381 if ((lhs > 0) && (rhs < 0)) {
382 int64_t thresh = lhs - max;
383 if (rhs < thresh) {
384 return min + (thresh - rhs - 1);
385 }
386 } else if ((lhs < 0) && (rhs > 0)) {
387 int64_t thresh = lhs - min;
388 if (rhs > thresh) {
389 return max - (rhs - thresh - 1);
390 }
391 }
392 return lhs - rhs;
393}
394
395static inline intptr_t zig_subw_isize(intptr_t lhs, intptr_t rhs, intptr_t min, intptr_t max) {
396 return (intptr_t)(((uintptr_t)lhs) - ((uintptr_t)rhs));
397}
398
399static inline short zig_subw_short(short lhs, short rhs, short min, short max) {
400 return (short)(((unsigned short)lhs) - ((unsigned short)rhs));
401}
402
403static inline int zig_subw_int(int lhs, int rhs, int min, int max) {
404 return (int)(((unsigned)lhs) - ((unsigned)rhs));
405}
406
407static inline long zig_subw_long(long lhs, long rhs, long min, long max) {
408 return (long)(((unsigned long)lhs) - ((unsigned long)rhs));
409}
410
411static inline long long zig_subw_longlong(long long lhs, long long rhs, long long min, long long max) {
412 return (long long)(((unsigned long long)lhs) - ((unsigned long long)rhs));
413}
414
415static inline bool zig_addo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) {
416#if defined(__GNUC__) && INT8_MAX == INT_MAX
417 if (min == INT8_MIN && max == INT8_MAX) {
418 return __builtin_sadd_overflow(lhs, rhs, (int*)res);
419 }
420#elif defined(__GNUC__) && INT8_MAX == LONG_MAX
421 if (min == INT8_MIN && max == INT8_MAX) {
422 return __builtin_saddl_overflow(lhs, rhs, (long*)res);
423 }
424#elif defined(__GNUC__) && INT8_MAX == LLONG_MAX
425 if (min == INT8_MIN && max == INT8_MAX) {
426 return __builtin_saddll_overflow(lhs, rhs, (long long*)res);
427 }
428#endif
429 int16_t big_result = (int16_t)lhs + (int16_t)rhs;
430 if (big_result > max) {
431 *res = big_result - ((int16_t)max - (int16_t)min);
432 return true;
433 }
434 if (big_result < min) {
435 *res = big_result + ((int16_t)max - (int16_t)min);
436 return true;
437 }
438 *res = big_result;
439 return false;
440}
441
442static inline bool zig_addo_i16(int16_t lhs, int16_t rhs, int16_t *res, int16_t min, int16_t max) {
443#if defined(__GNUC__) && INT16_MAX == INT_MAX
444 if (min == INT16_MIN && max == INT16_MAX) {
445 return __builtin_sadd_overflow(lhs, rhs, (int*)res);
446 }
447#elif defined(__GNUC__) && INT16_MAX == LONG_MAX
448 if (min == INT16_MIN && max == INT16_MAX) {
449 return __builtin_saddl_overflow(lhs, rhs, (long*)res);
450 }
451#elif defined(__GNUC__) && INT16_MAX == LLONG_MAX
452 if (min == INT16_MIN && max == INT16_MAX) {
453 return __builtin_saddll_overflow(lhs, rhs, (long long*)res);
454 }
455#endif
456 int32_t big_result = (int32_t)lhs + (int32_t)rhs;
457 if (big_result > max) {
458 *res = big_result - ((int32_t)max - (int32_t)min);
459 return true;
460 }
461 if (big_result < min) {
462 *res = big_result + ((int32_t)max - (int32_t)min);
463 return true;
464 }
465 *res = big_result;
466 return false;
467}
468
469static inline bool zig_addo_i32(int32_t lhs, int32_t rhs, int32_t *res, int32_t min, int32_t max) {
470#if defined(__GNUC__) && INT32_MAX == INT_MAX
471 if (min == INT32_MIN && max == INT32_MAX) {
472 return __builtin_sadd_overflow(lhs, rhs, (int*)res);
473 }
474#elif defined(__GNUC__) && INT32_MAX == LONG_MAX
475 if (min == INT32_MIN && max == INT32_MAX) {
476 return __builtin_saddl_overflow(lhs, rhs, (long*)res);
477 }
478#elif defined(__GNUC__) && INT32_MAX == LLONG_MAX
479 if (min == INT32_MIN && max == INT32_MAX) {
480 return __builtin_saddll_overflow(lhs, rhs, (long long*)res);
481 }
482#endif
483 int64_t big_result = (int64_t)lhs + (int64_t)rhs;
484 if (big_result > max) {
485 *res = big_result - ((int64_t)max - (int64_t)min);
486 return true;
487 }
488 if (big_result < min) {
489 *res = big_result + ((int64_t)max - (int64_t)min);
490 return true;
491 }
492 *res = big_result;
493 return false;
494}
495
496static inline bool zig_addo_i64(int64_t lhs, int64_t rhs, int64_t *res, int64_t min, int64_t max) {
497 bool overflow;
498#if defined(__GNUC__) && INT64_MAX == INT_MAX
499 overflow = __builtin_sadd_overflow(lhs, rhs, (int*)res);
500#elif defined(__GNUC__) && INT64_MAX == LONG_MAX
501 overflow = __builtin_saddl_overflow(lhs, rhs, (long*)res);
502#elif defined(__GNUC__) && INT64_MAX == LLONG_MAX
503 overflow = __builtin_saddll_overflow(lhs, rhs, (long long*)res);
504#else
505 int int_overflow;
506 *res = __addodi4(lhs, rhs, &int_overflow);
507 overflow = int_overflow != 0;
508#endif
509 if (!overflow) {
510 if (*res > max) {
511 // TODO adjust the result to be the truncated bits
512 return true;
513 } else if (*res < min) {
514 // TODO adjust the result to be the truncated bits
515 return true;
516 }
517 }
518 return overflow;
519}
520
521static inline bool zig_addo_i128(int128_t lhs, int128_t rhs, int128_t *res, int128_t min, int128_t max) {
522 bool overflow;
523#if defined(__GNUC__) && INT128_MAX == INT_MAX
524 overflow = __builtin_sadd_overflow(lhs, rhs, (int*)res);
525#elif defined(__GNUC__) && INT128_MAX == LONG_MAX
526 overflow = __builtin_saddl_overflow(lhs, rhs, (long*)res);
527#elif defined(__GNUC__) && INT128_MAX == LLONG_MAX
528 overflow = __builtin_saddll_overflow(lhs, rhs, (long long*)res);
529#else
530 int int_overflow;
531 *res = __addoti4(lhs, rhs, &int_overflow);
532 overflow = int_overflow != 0;
533#endif
534 if (!overflow) {
535 if (*res > max) {
536 // TODO adjust the result to be the truncated bits
537 return true;
538 } else if (*res < min) {
539 // TODO adjust the result to be the truncated bits
540 return true;
541 }
542 }
543 return overflow;
544}
545
546static inline bool zig_addo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t max) {
547#if defined(__GNUC__) && UINT8_MAX == UINT_MAX
548 if (max == UINT8_MAX) {
549 return __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res);
550 }
551#elif defined(__GNUC__) && UINT8_MAX == ULONG_MAX
552 if (max == UINT8_MAX) {
553 return __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res);
554 }
555#elif defined(__GNUC__) && UINT8_MAX == ULLONG_MAX
556 if (max == UINT8_MAX) {
557 return __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res);
558 }
559#endif
560 uint16_t big_result = (uint16_t)lhs + (uint16_t)rhs;
561 if (big_result > max) {
562 *res = big_result - max - 1;
563 return true;
564 }
565 *res = big_result;
566 return false;
567}
568
569static inline uint16_t zig_addo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint16_t max) {
570#if defined(__GNUC__) && UINT16_MAX == UINT_MAX
571 if (max == UINT16_MAX) {
572 return __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res);
573 }
574#elif defined(__GNUC__) && UINT16_MAX == ULONG_MAX
575 if (max == UINT16_MAX) {
576 return __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res);
577 }
578#elif defined(__GNUC__) && UINT16_MAX == ULLONG_MAX
579 if (max == UINT16_MAX) {
580 return __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res);
581 }
582#endif
583 uint32_t big_result = (uint32_t)lhs + (uint32_t)rhs;
584 if (big_result > max) {
585 *res = big_result - max - 1;
586 return true;
587 }
588 *res = big_result;
589 return false;
590}
591
592static inline uint32_t zig_addo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint32_t max) {
593#if defined(__GNUC__) && UINT32_MAX == UINT_MAX
594 if (max == UINT32_MAX) {
595 return __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res);
596 }
597#elif defined(__GNUC__) && UINT32_MAX == ULONG_MAX
598 if (max == UINT32_MAX) {
599 return __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res);
600 }
601#elif defined(__GNUC__) && UINT32_MAX == ULLONG_MAX
602 if (max == UINT32_MAX) {
603 return __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res);
604 }
605#endif
606 uint64_t big_result = (uint64_t)lhs + (uint64_t)rhs;
607 if (big_result > max) {
608 *res = big_result - max - 1;
609 return true;
610 }
611 *res = big_result;
612 return false;
613}
614
615static inline uint64_t zig_addo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint64_t max) {
616 bool overflow;
617#if defined(__GNUC__) && UINT64_MAX == UINT_MAX
618 overflow = __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res);
619#elif defined(__GNUC__) && UINT64_MAX == ULONG_MAX
620 overflow = __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res);
621#elif defined(__GNUC__) && UINT64_MAX == ULLONG_MAX
622 overflow = __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res);
623#else
624 int int_overflow;
625 *res = __uaddodi4(lhs, rhs, &int_overflow);
626 overflow = int_overflow != 0;
627#endif
628 if (*res > max && !overflow) {
629 *res -= max - 1;
630 return true;
631 }
632 return overflow;
633}
634
635static inline uint128_t zig_addo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) {
636 int overflow;
637 *res = __uaddoti4(lhs, rhs, &overflow);
638 if (*res > max && overflow == 0) {
639 *res -= max - 1;
640 return true;
641 }
642 return overflow != 0;
643}
644
645static inline bool zig_subo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) {
646#if defined(__GNUC__) && INT8_MAX == INT_MAX
647 if (min == INT8_MIN && max == INT8_MAX) {
648 return __builtin_ssub_overflow(lhs, rhs, (int*)res);
649 }
650#elif defined(__GNUC__) && INT8_MAX == LONG_MAX
651 if (min == INT8_MIN && max == INT8_MAX) {
652 return __builtin_ssubl_overflow(lhs, rhs, (long*)res);
653 }
654#elif defined(__GNUC__) && INT8_MAX == LLONG_MAX
655 if (min == INT8_MIN && max == INT8_MAX) {
656 return __builtin_ssubll_overflow(lhs, rhs, (long long*)res);
657 }
658#endif
659 int16_t big_result = (int16_t)lhs - (int16_t)rhs;
660 if (big_result > max) {
661 *res = big_result - ((int16_t)max - (int16_t)min);
662 return true;
663 }
664 if (big_result < min) {
665 *res = big_result + ((int16_t)max - (int16_t)min);
666 return true;
667 }
668 *res = big_result;
669 return false;
670}
671
672static inline bool zig_subo_i16(int16_t lhs, int16_t rhs, int16_t *res, int16_t min, int16_t max) {
673#if defined(__GNUC__) && INT16_MAX == INT_MAX
674 if (min == INT16_MIN && max == INT16_MAX) {
675 return __builtin_ssub_overflow(lhs, rhs, (int*)res);
676 }
677#elif defined(__GNUC__) && INT16_MAX == LONG_MAX
678 if (min == INT16_MIN && max == INT16_MAX) {
679 return __builtin_ssubl_overflow(lhs, rhs, (long*)res);
680 }
681#elif defined(__GNUC__) && INT16_MAX == LLONG_MAX
682 if (min == INT16_MIN && max == INT16_MAX) {
683 return __builtin_ssubll_overflow(lhs, rhs, (long long*)res);
684 }
685#endif
686 int32_t big_result = (int32_t)lhs - (int32_t)rhs;
687 if (big_result > max) {
688 *res = big_result - ((int32_t)max - (int32_t)min);
689 return true;
690 }
691 if (big_result < min) {
692 *res = big_result + ((int32_t)max - (int32_t)min);
693 return true;
694 }
695 *res = big_result;
696 return false;
697}
698
699static inline bool zig_subo_i32(int32_t lhs, int32_t rhs, int32_t *res, int32_t min, int32_t max) {
700#if defined(__GNUC__) && INT32_MAX == INT_MAX
701 if (min == INT32_MIN && max == INT32_MAX) {
702 return __builtin_ssub_overflow(lhs, rhs, (int*)res);
703 }
704#elif defined(__GNUC__) && INT32_MAX == LONG_MAX
705 if (min == INT32_MIN && max == INT32_MAX) {
706 return __builtin_ssubl_overflow(lhs, rhs, (long*)res);
707 }
708#elif defined(__GNUC__) && INT32_MAX == LLONG_MAX
709 if (min == INT32_MIN && max == INT32_MAX) {
710 return __builtin_ssubll_overflow(lhs, rhs, (long long*)res);
711 }
712#endif
713 int64_t big_result = (int64_t)lhs - (int64_t)rhs;
714 if (big_result > max) {
715 *res = big_result - ((int64_t)max - (int64_t)min);
716 return true;
717 }
718 if (big_result < min) {
719 *res = big_result + ((int64_t)max - (int64_t)min);
720 return true;
721 }
722 *res = big_result;
723 return false;
724}
725
726static inline bool zig_subo_i64(int64_t lhs, int64_t rhs, int64_t *res, int64_t min, int64_t max) {
727 bool overflow;
728#if defined(__GNUC__) && INT64_MAX == INT_MAX
729 overflow = __builtin_ssub_overflow(lhs, rhs, (int*)res);
730#elif defined(__GNUC__) && INT64_MAX == LONG_MAX
731 overflow = __builtin_ssubl_overflow(lhs, rhs, (long*)res);
732#elif defined(__GNUC__) && INT64_MAX == LLONG_MAX
733 overflow = __builtin_ssubll_overflow(lhs, rhs, (long long*)res);
734#else
735 int int_overflow;
736 *res = __subodi4(lhs, rhs, &int_overflow);
737 overflow = int_overflow != 0;
738#endif
739 if (!overflow) {
740 if (*res > max) {
741 // TODO adjust the result to be the truncated bits
742 return true;
743 } else if (*res < min) {
744 // TODO adjust the result to be the truncated bits
745 return true;
746 }
747 }
748 return overflow;
749}
750
751static inline bool zig_subo_i128(int128_t lhs, int128_t rhs, int128_t *res, int128_t min, int128_t max) {
752 bool overflow;
753#if defined(__GNUC__) && INT128_MAX == INT_MAX
754 overflow = __builtin_ssub_overflow(lhs, rhs, (int*)res);
755#elif defined(__GNUC__) && INT128_MAX == LONG_MAX
756 overflow = __builtin_ssubl_overflow(lhs, rhs, (long*)res);
757#elif defined(__GNUC__) && INT128_MAX == LLONG_MAX
758 overflow = __builtin_ssubll_overflow(lhs, rhs, (long long*)res);
759#else
760 int int_overflow;
761 *res = __suboti4(lhs, rhs, &int_overflow);
762 overflow = int_overflow != 0;
763#endif
764 if (!overflow) {
765 if (*res > max) {
766 // TODO adjust the result to be the truncated bits
767 return true;
768 } else if (*res < min) {
769 // TODO adjust the result to be the truncated bits
770 return true;
771 }
772 }
773 return overflow;
774}
775
776static inline bool zig_subo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t max) {
777#if defined(__GNUC__) && UINT8_MAX == UINT_MAX
778 return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res);
779#elif defined(__GNUC__) && UINT8_MAX == ULONG_MAX
780 return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res);
781#elif defined(__GNUC__) && UINT8_MAX == ULLONG_MAX
782 return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res);
783#endif
784 if (rhs > lhs) {
785 *res = max - (rhs - lhs - 1);
786 return true;
787 }
788 *res = lhs - rhs;
789 return false;
790}
791
792static inline uint16_t zig_subo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint16_t max) {
793#if defined(__GNUC__) && UINT16_MAX == UINT_MAX
794 return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res);
795#elif defined(__GNUC__) && UINT16_MAX == ULONG_MAX
796 return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res);
797#elif defined(__GNUC__) && UINT16_MAX == ULLONG_MAX
798 return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res);
799#endif
800 if (rhs > lhs) {
801 *res = max - (rhs - lhs - 1);
802 return true;
803 }
804 *res = lhs - rhs;
805 return false;
806}
807
808static inline uint32_t zig_subo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint32_t max) {
809 if (max == UINT32_MAX) {
810#if defined(__GNUC__) && UINT32_MAX == UINT_MAX
811 return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res);
812#elif defined(__GNUC__) && UINT32_MAX == ULONG_MAX
813 return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res);
814#elif defined(__GNUC__) && UINT32_MAX == ULLONG_MAX
815 return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res);
816#endif
817 int int_overflow;
818 *res = __usubosi4(lhs, rhs, &int_overflow);
819 return int_overflow != 0;
820 } else {
821 if (rhs > lhs) {
822 *res = max - (rhs - lhs - 1);
823 return true;
824 }
825 *res = lhs - rhs;
826 return false;
827 }
828}
829
830static inline uint64_t zig_subo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint64_t max) {
831 if (max == UINT64_MAX) {
832#if defined(__GNUC__) && UINT64_MAX == UINT_MAX
833 return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res);
834#elif defined(__GNUC__) && UINT64_MAX == ULONG_MAX
835 return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res);
836#elif defined(__GNUC__) && UINT64_MAX == ULLONG_MAX
837 return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res);
838#else
839 int int_overflow;
840 *res = __usubodi4(lhs, rhs, &int_overflow);
841 return int_overflow != 0;
842#endif
843 } else {
844 if (rhs > lhs) {
845 *res = max - (rhs - lhs - 1);
846 return true;
847 }
848 *res = lhs - rhs;
849 return false;
850 }
851}
852
853static inline uint128_t zig_subo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) {
854 if (max == UINT128_MAX) {
855 int int_overflow;
856 *res = __usuboti4(lhs, rhs, &int_overflow);
857 return int_overflow != 0;
858 } else {
859 if (rhs > lhs) {
860 *res = max - (rhs - lhs - 1);
861 return true;
862 }
863 *res = lhs - rhs;
864 return false;
865 }
866}
867
868static inline bool zig_mulo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) {
869#if defined(__GNUC__) && INT8_MAX == INT_MAX
870 if (min == INT8_MIN && max == INT8_MAX) {
871 return __builtin_smul_overflow(lhs, rhs, (int*)res);
872 }
873#elif defined(__GNUC__) && INT8_MAX == LONG_MAX
874 if (min == INT8_MIN && max == INT8_MAX) {
875 return __builtin_smull_overflow(lhs, rhs, (long*)res);
876 }
877#elif defined(__GNUC__) && INT8_MAX == LLONG_MAX
878 if (min == INT8_MIN && max == INT8_MAX) {
879 return __builtin_smulll_overflow(lhs, rhs, (long long*)res);
880 }
881#endif
882 int16_t big_result = (int16_t)lhs * (int16_t)rhs;
883 if (big_result > max) {
884 *res = big_result - ((int16_t)max - (int16_t)min);
885 return true;
886 }
887 if (big_result < min) {
888 *res = big_result + ((int16_t)max - (int16_t)min);
889 return true;
890 }
891 *res = big_result;
892 return false;
893}
894
895static inline bool zig_mulo_i16(int16_t lhs, int16_t rhs, int16_t *res, int16_t min, int16_t max) {
896#if defined(__GNUC__) && INT16_MAX == INT_MAX
897 if (min == INT16_MIN && max == INT16_MAX) {
898 return __builtin_smul_overflow(lhs, rhs, (int*)res);
899 }
900#elif defined(__GNUC__) && INT16_MAX == LONG_MAX
901 if (min == INT16_MIN && max == INT16_MAX) {
902 return __builtin_smull_overflow(lhs, rhs, (long*)res);
903 }
904#elif defined(__GNUC__) && INT16_MAX == LLONG_MAX
905 if (min == INT16_MIN && max == INT16_MAX) {
906 return __builtin_smulll_overflow(lhs, rhs, (long long*)res);
907 }
908#endif
909 int32_t big_result = (int32_t)lhs * (int32_t)rhs;
910 if (big_result > max) {
911 *res = big_result - ((int32_t)max - (int32_t)min);
912 return true;
913 }
914 if (big_result < min) {
915 *res = big_result + ((int32_t)max - (int32_t)min);
916 return true;
917 }
918 *res = big_result;
919 return false;
920}
921
922static inline bool zig_mulo_i32(int32_t lhs, int32_t rhs, int32_t *res, int32_t min, int32_t max) {
923#if defined(__GNUC__) && INT32_MAX == INT_MAX
924 if (min == INT32_MIN && max == INT32_MAX) {
925 return __builtin_smul_overflow(lhs, rhs, (int*)res);
926 }
927#elif defined(__GNUC__) && INT32_MAX == LONG_MAX
928 if (min == INT32_MIN && max == INT32_MAX) {
929 return __builtin_smull_overflow(lhs, rhs, (long*)res);
930 }
931#elif defined(__GNUC__) && INT32_MAX == LLONG_MAX
932 if (min == INT32_MIN && max == INT32_MAX) {
933 return __builtin_smulll_overflow(lhs, rhs, (long long*)res);
934 }
935#endif
936 int64_t big_result = (int64_t)lhs * (int64_t)rhs;
937 if (big_result > max) {
938 *res = big_result - ((int64_t)max - (int64_t)min);
939 return true;
940 }
941 if (big_result < min) {
942 *res = big_result + ((int64_t)max - (int64_t)min);
943 return true;
944 }
945 *res = big_result;
946 return false;
947}
948
949static inline bool zig_mulo_i64(int64_t lhs, int64_t rhs, int64_t *res, int64_t min, int64_t max) {
950 bool overflow;
951#if defined(__GNUC__) && INT64_MAX == INT_MAX
952 overflow = __builtin_smul_overflow(lhs, rhs, (int*)res);
953#elif defined(__GNUC__) && INT64_MAX == LONG_MAX
954 overflow = __builtin_smull_overflow(lhs, rhs, (long*)res);
955#elif defined(__GNUC__) && INT64_MAX == LLONG_MAX
956 overflow = __builtin_smulll_overflow(lhs, rhs, (long long*)res);
957#else
958 int int_overflow;
959 *res = __mulodi4(lhs, rhs, &int_overflow);
960 overflow = int_overflow != 0;
961#endif
962 if (!overflow) {
963 if (*res > max) {
964 // TODO adjust the result to be the truncated bits
965 return true;
966 } else if (*res < min) {
967 // TODO adjust the result to be the truncated bits
968 return true;
969 }
970 }
971 return overflow;
972}
973
974static inline bool zig_mulo_i128(int128_t lhs, int128_t rhs, int128_t *res, int128_t min, int128_t max) {
975 bool overflow;
976#if defined(__GNUC__) && INT128_MAX == INT_MAX
977 overflow = __builtin_smul_overflow(lhs, rhs, (int*)res);
978#elif defined(__GNUC__) && INT128_MAX == LONG_MAX
979 overflow = __builtin_smull_overflow(lhs, rhs, (long*)res);
980#elif defined(__GNUC__) && INT128_MAX == LLONG_MAX
981 overflow = __builtin_smulll_overflow(lhs, rhs, (long long*)res);
982#else
983 int int_overflow;
984 *res = __muloti4(lhs, rhs, &int_overflow);
985 overflow = int_overflow != 0;
986#endif
987 if (!overflow) {
988 if (*res > max) {
989 // TODO adjust the result to be the truncated bits
990 return true;
991 } else if (*res < min) {
992 // TODO adjust the result to be the truncated bits
993 return true;
994 }
995 }
996 return overflow;
997}
998
999static inline bool zig_mulo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t max) {
1000#if defined(__GNUC__) && UINT8_MAX == UINT_MAX
1001 if (max == UINT8_MAX) {
1002 return __builtin_umul_overflow(lhs, rhs, (unsigned int*)res);
1003 }
1004#elif defined(__GNUC__) && UINT8_MAX == ULONG_MAX
1005 if (max == UINT8_MAX) {
1006 return __builtin_umull_overflow(lhs, rhs, (unsigned long*)res);
1007 }
1008#elif defined(__GNUC__) && UINT8_MAX == ULLONG_MAX
1009 if (max == UINT8_MAX) {
1010 return __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res);
1011 }
1012#endif
1013 uint16_t big_result = (uint16_t)lhs * (uint16_t)rhs;
1014 if (big_result > max) {
1015 *res = big_result - max - 1;
1016 return true;
1017 }
1018 *res = big_result;
1019 return false;
1020}
1021
1022static inline uint16_t zig_mulo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint16_t max) {
1023#if defined(__GNUC__) && UINT16_MAX == UINT_MAX
1024 if (max == UINT16_MAX) {
1025 return __builtin_umul_overflow(lhs, rhs, (unsigned int*)res);
1026 }
1027#elif defined(__GNUC__) && UINT16_MAX == ULONG_MAX
1028 if (max == UINT16_MAX) {
1029 return __builtin_umull_overflow(lhs, rhs, (unsigned long*)res);
1030 }
1031#elif defined(__GNUC__) && UINT16_MAX == ULLONG_MAX
1032 if (max == UINT16_MAX) {
1033 return __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res);
1034 }
1035#endif
1036 uint32_t big_result = (uint32_t)lhs * (uint32_t)rhs;
1037 if (big_result > max) {
1038 *res = big_result - max - 1;
1039 return true;
1040 }
1041 *res = big_result;
1042 return false;
1043}
1044
1045static inline uint32_t zig_mulo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint32_t max) {
1046#if defined(__GNUC__) && UINT32_MAX == UINT_MAX
1047 if (max == UINT32_MAX) {
1048 return __builtin_umul_overflow(lhs, rhs, (unsigned int*)res);
1049 }
1050#elif defined(__GNUC__) && UINT32_MAX == ULONG_MAX
1051 if (max == UINT32_MAX) {
1052 return __builtin_umull_overflow(lhs, rhs, (unsigned long*)res);
1053 }
1054#elif defined(__GNUC__) && UINT32_MAX == ULLONG_MAX
1055 if (max == UINT32_MAX) {
1056 return __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res);
1057 }
1058#endif
1059 uint64_t big_result = (uint64_t)lhs * (uint64_t)rhs;
1060 if (big_result > max) {
1061 *res = big_result - max - 1;
1062 return true;
1063 }
1064 *res = big_result;
1065 return false;
1066}
1067
1068static inline uint64_t zig_mulo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint64_t max) {
1069 bool overflow;
1070#if defined(__GNUC__) && UINT64_MAX == UINT_MAX
1071 overflow = __builtin_umul_overflow(lhs, rhs, (unsigned int*)res);
1072#elif defined(__GNUC__) && UINT64_MAX == ULONG_MAX
1073 overflow = __builtin_umull_overflow(lhs, rhs, (unsigned long*)res);
1074#elif defined(__GNUC__) && UINT64_MAX == ULLONG_MAX
1075 overflow = __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res);
1076#else
1077 int int_overflow;
1078 *res = __umulodi4(lhs, rhs, &int_overflow);
1079 overflow = int_overflow != 0;
1080#endif
1081 if (*res > max && !overflow) {
1082 *res -= max - 1;
1083 return true;
1084 }
1085 return overflow;
1086}
1087
1088static inline uint128_t zig_mulo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) {
1089 int overflow;
1090 *res = __umuloti4(lhs, rhs, &overflow);
1091 if (*res > max && overflow == 0) {
1092 *res -= max - 1;
1093 return true;
1094 }
1095 return overflow != 0;
1096}
1097
1098static inline float zig_bitcast_f32_u32(uint32_t arg) {
1099 float dest;
1100 memcpy(&dest, &arg, sizeof dest);
1101 return dest;
1102}
1103
1104static inline float zig_bitcast_f64_u64(uint64_t arg) {
1105 double dest;
1106 memcpy(&dest, &arg, sizeof dest);
1107 return dest;
1108}
1109
1110#define zig_add_sat_u(ZT, T) static inline T zig_adds_##ZT(T x, T y, T max) { \
1111 return (x > max - y) ? max : x + y; \
1112}
1113
1114#define zig_add_sat_s(ZT, T, T2) static inline T zig_adds_##ZT(T2 x, T2 y, T2 min, T2 max) { \
1115 T2 res = x + y; \
1116 return (res < min) ? min : (res > max) ? max : res; \
1117}
1118
1119zig_add_sat_u( u8, uint8_t)
1120zig_add_sat_s( i8, int8_t, int16_t)
1121zig_add_sat_u(u16, uint16_t)
1122zig_add_sat_s(i16, int16_t, int32_t)
1123zig_add_sat_u(u32, uint32_t)
1124zig_add_sat_s(i32, int32_t, int64_t)
1125zig_add_sat_u(u64, uint64_t)
1126zig_add_sat_s(i64, int64_t, int128_t)
1127zig_add_sat_s(isize, intptr_t, int128_t)
1128zig_add_sat_s(short, short, int)
1129zig_add_sat_s(int, int, long)
1130zig_add_sat_s(long, long, long long)
1131
1132#define zig_sub_sat_u(ZT, T) static inline T zig_subs_##ZT(T x, T y, T max) { \
1133 return (x > max + y) ? max : x - y; \
1134}
1135
1136#define zig_sub_sat_s(ZT, T, T2) static inline T zig_subs_##ZT(T2 x, T2 y, T2 min, T2 max) { \
1137 T2 res = x - y; \
1138 return (res < min) ? min : (res > max) ? max : res; \
1139}
1140
1141zig_sub_sat_u( u8, uint8_t)
1142zig_sub_sat_s( i8, int8_t, int16_t)
1143zig_sub_sat_u(u16, uint16_t)
1144zig_sub_sat_s(i16, int16_t, int32_t)
1145zig_sub_sat_u(u32, uint32_t)
1146zig_sub_sat_s(i32, int32_t, int64_t)
1147zig_sub_sat_u(u64, uint64_t)
1148zig_sub_sat_s(i64, int64_t, int128_t)
1149zig_sub_sat_s(isize, intptr_t, int128_t)
1150zig_sub_sat_s(short, short, int)
1151zig_sub_sat_s(int, int, long)
1152zig_sub_sat_s(long, long, long long)
1153
1154
1155#define zig_mul_sat_u(ZT, T, T2) static inline T zig_muls_##ZT(T2 x, T2 y, T2 max) { \
1156 T2 res = x * y; \
1157 return (res > max) ? max : res; \
1158}
1159
1160#define zig_mul_sat_s(ZT, T, T2) static inline T zig_muls_##ZT(T2 x, T2 y, T2 min, T2 max) { \
1161 T2 res = x * y; \
1162 return (res < min) ? min : (res > max) ? max : res; \
1163}
1164
1165zig_mul_sat_u(u8, uint8_t, uint16_t)
1166zig_mul_sat_s(i8, int8_t, int16_t)
1167zig_mul_sat_u(u16, uint16_t, uint32_t)
1168zig_mul_sat_s(i16, int16_t, int32_t)
1169zig_mul_sat_u(u32, uint32_t, uint64_t)
1170zig_mul_sat_s(i32, int32_t, int64_t)
1171zig_mul_sat_u(u64, uint64_t, uint128_t)
1172zig_mul_sat_s(i64, int64_t, int128_t)
1173zig_mul_sat_s(isize, intptr_t, int128_t)
1174zig_mul_sat_s(short, short, int)
1175zig_mul_sat_s(int, int, long)
1176zig_mul_sat_s(long, long, long long)
1177
1178#define zig_shl_sat_u(ZT, T, bits) static inline T zig_shls_##ZT(T x, T y, T max) { \
1179 if(x == 0) return 0; \
1180 T bits_set = 64 - __builtin_clzll(x); \
1181 return (bits_set + y > bits) ? max : x << y; \
1182}
1183
1184#define zig_shl_sat_s(ZT, T, bits) static inline T zig_shls_##ZT(T x, T y, T min, T max) { \
1185 if(x == 0) return 0; \
1186 T x_twos_comp = x < 0 ? -x : x; \
1187 T bits_set = 64 - __builtin_clzll(x_twos_comp); \
1188 T min_or_max = (x < 0) ? min : max; \
1189 return (y + bits_set > bits ) ? min_or_max : x << y; \
1190}
1191
1192zig_shl_sat_u(u8, uint8_t, 8)
1193zig_shl_sat_s(i8, int8_t, 7)
1194zig_shl_sat_u(u16, uint16_t, 16)
1195zig_shl_sat_s(i16, int16_t, 15)
1196zig_shl_sat_u(u32, uint32_t, 32)
1197zig_shl_sat_s(i32, int32_t, 31)
1198zig_shl_sat_u(u64, uint64_t, 64)
1199zig_shl_sat_s(i64, int64_t, 63)
1200zig_shl_sat_s(isize, intptr_t, ((sizeof(intptr_t)) * CHAR_BIT - 1))
1201zig_shl_sat_s(short, short, ((sizeof(short )) * CHAR_BIT - 1))
1202zig_shl_sat_s(int, int, ((sizeof(int )) * CHAR_BIT - 1))
1203zig_shl_sat_s(long, long, ((sizeof(long )) * CHAR_BIT - 1))
1204
1205#define zig_bitsizeof(T) (CHAR_BIT * sizeof(T))
1206#define zig_bit_mask(T, bit_width) \
1207 ((bit_width) == zig_bitsizeof(T) \
1208 ? ((T)-1) \
1209 : (((T)1 << (T)(bit_width)) - 1))
1210
1211static inline int zig_clz(unsigned int value, uint8_t zig_type_bit_width) {
1212 if (value == 0) return zig_type_bit_width;
1213 return __builtin_clz(value) - zig_bitsizeof(unsigned int) + zig_type_bit_width;
1214}
1215
1216static inline int zig_clzl(unsigned long value, uint8_t zig_type_bit_width) {
1217 if (value == 0) return zig_type_bit_width;
1218 return __builtin_clzl(value) - zig_bitsizeof(unsigned long) + zig_type_bit_width;
1219}
1220
1221static inline int zig_clzll(unsigned long long value, uint8_t zig_type_bit_width) {
1222 if (value == 0) return zig_type_bit_width;
1223 return __builtin_clzll(value) - zig_bitsizeof(unsigned long long) + zig_type_bit_width;
1224}
1225
1226#define zig_clz_u8 zig_clz
1227#define zig_clz_i8 zig_clz
1228#define zig_clz_u16 zig_clz
1229#define zig_clz_i16 zig_clz
1230#define zig_clz_u32 zig_clzl
1231#define zig_clz_i32 zig_clzl
1232#define zig_clz_u64 zig_clzll
1233#define zig_clz_i64 zig_clzll
1234
1235static inline int zig_clz_u128(uint128_t value, uint8_t zig_type_bit_width) {
1236 if (value == 0) return zig_type_bit_width;
1237 const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width);
1238 const uint64_t hi = (value & mask) >> 64;
1239 const uint64_t lo = (value & mask);
1240 const int leading_zeroes = (
1241 hi != 0 ? __builtin_clzll(hi) : 64 + (lo != 0 ? __builtin_clzll(lo) : 64));
1242 return leading_zeroes - zig_bitsizeof(uint128_t) + zig_type_bit_width;
1243}
1244
1245#define zig_clz_i128 zig_clz_u128
1246
1247static inline int zig_ctz(unsigned int value, uint8_t zig_type_bit_width) {
1248 if (value == 0) return zig_type_bit_width;
1249 return __builtin_ctz(value & zig_bit_mask(unsigned int, zig_type_bit_width));
1250}
1251
1252static inline int zig_ctzl(unsigned long value, uint8_t zig_type_bit_width) {
1253 if (value == 0) return zig_type_bit_width;
1254 return __builtin_ctzl(value & zig_bit_mask(unsigned long, zig_type_bit_width));
1255}
1256
1257static inline int zig_ctzll(unsigned long value, uint8_t zig_type_bit_width) {
1258 if (value == 0) return zig_type_bit_width;
1259 return __builtin_ctzll(value & zig_bit_mask(unsigned long, zig_type_bit_width));
1260}
1261
1262#define zig_ctz_u8 zig_ctz
1263#define zig_ctz_i8 zig_ctz
1264#define zig_ctz_u16 zig_ctz
1265#define zig_ctz_i16 zig_ctz
1266#define zig_ctz_u32 zig_ctzl
1267#define zig_ctz_i32 zig_ctzl
1268#define zig_ctz_u64 zig_ctzll
1269#define zig_ctz_i64 zig_ctzll
1270
1271static inline int zig_ctz_u128(uint128_t value, uint8_t zig_type_bit_width) {
1272 const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width);
1273 const uint64_t hi = (value & mask) >> 64;
1274 const uint64_t lo = (value & mask);
1275 return (lo != 0 ? __builtin_ctzll(lo) : 64 + (hi != 0 ? __builtin_ctzll(hi) : 64));
1276}
1277
1278#define zig_ctz_i128 zig_ctz_u128
1279
1280static inline int zig_popcount(unsigned int value, uint8_t zig_type_bit_width) {
1281 return __builtin_popcount(value & zig_bit_mask(unsigned int, zig_type_bit_width));
1282}
1283
1284static inline int zig_popcountl(unsigned long value, uint8_t zig_type_bit_width) {
1285 return __builtin_popcountl(value & zig_bit_mask(unsigned long, zig_type_bit_width));
1286}
1287
1288static inline int zig_popcountll(unsigned long value, uint8_t zig_type_bit_width) {
1289 return __builtin_popcountll(value & zig_bit_mask(unsigned long, zig_type_bit_width));
1290}
1291
1292#define zig_popcount_u8 zig_popcount
1293#define zig_popcount_i8 zig_popcount
1294#define zig_popcount_u16 zig_popcount
1295#define zig_popcount_i16 zig_popcount
1296#define zig_popcount_u32 zig_popcountl
1297#define zig_popcount_i32 zig_popcountl
1298#define zig_popcount_u64 zig_popcountll
1299#define zig_popcount_i64 zig_popcountll
1300
1301static inline int zig_popcount_u128(uint128_t value, uint8_t zig_type_bit_width) {
1302 const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width);
1303 const uint64_t hi = (value & mask) >> 64;
1304 const uint64_t lo = (value & mask);
1305 return __builtin_popcountll(hi) + __builtin_popcountll(lo);
1306}
1307
1308#define zig_popcount_i128 zig_popcount_u128
1309
1310static inline bool zig_shlo_i8(int8_t lhs, int8_t rhs, int8_t *res, uint8_t bits) {
1311 *res = lhs << rhs;
1312 if (zig_clz_i8(lhs, bits) >= rhs) return false;
1313 *res &= UINT8_MAX >> (8 - bits);
1314 return true;
1315}
1316
1317static inline bool zig_shlo_i16(int16_t lhs, int16_t rhs, int16_t *res, uint8_t bits) {
1318 *res = lhs << rhs;
1319 if (zig_clz_i16(lhs, bits) >= rhs) return false;
1320 *res &= UINT16_MAX >> (16 - bits);
1321 return true;
1322}
1323
1324static inline bool zig_shlo_i32(int32_t lhs, int32_t rhs, int32_t *res, uint8_t bits) {
1325 *res = lhs << rhs;
1326 if (zig_clz_i32(lhs, bits) >= rhs) return false;
1327 *res &= UINT32_MAX >> (32 - bits);
1328 return true;
1329}
1330
1331static inline bool zig_shlo_i64(int64_t lhs, int64_t rhs, int64_t *res, uint8_t bits) {
1332 *res = lhs << rhs;
1333 if (zig_clz_i64(lhs, bits) >= rhs) return false;
1334 *res &= UINT64_MAX >> (64 - bits);
1335 return true;
1336}
1337
1338static inline bool zig_shlo_i128(int128_t lhs, int128_t rhs, int128_t *res, uint8_t bits) {
1339 *res = lhs << rhs;
1340 if (zig_clz_i128(lhs, bits) >= rhs) return false;
1341 *res &= UINT128_MAX >> (128 - bits);
1342 return true;
1343}
1344
1345static inline bool zig_shlo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t bits) {
1346 *res = lhs << rhs;
1347 if (zig_clz_u8(lhs, bits) >= rhs) return false;
1348 *res &= UINT8_MAX >> (8 - bits);
1349 return true;
1350}
1351
1352static inline uint16_t zig_shlo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint8_t bits) {
1353 *res = lhs << rhs;
1354 if (zig_clz_u16(lhs, bits) >= rhs) return false;
1355 *res &= UINT16_MAX >> (16 - bits);
1356 return true;
1357}
1358
1359static inline uint32_t zig_shlo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint8_t bits) {
1360 *res = lhs << rhs;
1361 if (zig_clz_u32(lhs, bits) >= rhs) return false;
1362 *res &= UINT32_MAX >> (32 - bits);
1363 return true;
1364}
1365
1366static inline uint64_t zig_shlo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint8_t bits) {
1367 *res = lhs << rhs;
1368 if (zig_clz_u64(lhs, bits) >= rhs) return false;
1369 *res &= UINT64_MAX >> (64 - bits);
1370 return true;
1371}
1372
1373static inline uint128_t zig_shlo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint8_t bits) {
1374 *res = lhs << rhs;
1375 if (zig_clz_u128(lhs, bits) >= rhs) return false;
1376 *res &= UINT128_MAX >> (128 - bits);
1377 return true;
1378}
1379
1380#define zig_sign_extend(T) \
1381 static inline T zig_sign_extend_##T(T value, uint8_t zig_type_bit_width) { \
1382 const T m = (T)1 << (T)(zig_type_bit_width - 1); \
1383 return (value ^ m) - m; \
1384 }
1385
1386zig_sign_extend(uint8_t)
1387zig_sign_extend(uint16_t)
1388zig_sign_extend(uint32_t)
1389zig_sign_extend(uint64_t)
1390zig_sign_extend(uint128_t)
1391
1392#define zig_byte_swap_u(ZigTypeBits, CTypeBits) \
1393 static inline uint##CTypeBits##_t zig_byte_swap_u##ZigTypeBits(uint##CTypeBits##_t value, uint8_t zig_type_bit_width) { \
1394 return __builtin_bswap##CTypeBits(value) >> (CTypeBits - zig_type_bit_width); \
1395 }
1396
1397#define zig_byte_swap_s(ZigTypeBits, CTypeBits) \
1398 static inline int##CTypeBits##_t zig_byte_swap_i##ZigTypeBits(int##CTypeBits##_t value, uint8_t zig_type_bit_width) { \
1399 const uint##CTypeBits##_t swapped = zig_byte_swap_u##ZigTypeBits(value, zig_type_bit_width); \
1400 return zig_sign_extend_uint##CTypeBits##_t(swapped, zig_type_bit_width); \
1401 }
1402
1403#define zig_byte_swap(ZigTypeBits, CTypeBits) \
1404 zig_byte_swap_u(ZigTypeBits, CTypeBits) \
1405 zig_byte_swap_s(ZigTypeBits, CTypeBits)
1406
1407zig_byte_swap( 8, 16)
1408zig_byte_swap(16, 16)
1409zig_byte_swap(32, 32)
1410zig_byte_swap(64, 64)
1411
1412static inline uint128_t zig_byte_swap_u128(uint128_t value, uint8_t zig_type_bit_width) {
1413 const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width);
1414 const uint128_t hi = __builtin_bswap64((uint64_t)(value >> 64));
1415 const uint128_t lo = __builtin_bswap64((uint64_t)value);
1416 return (((lo << 64 | hi) >> (128 - zig_type_bit_width))) & mask;
1417}
1418
1419zig_byte_swap_s(128, 128)
1420
1421static const uint8_t zig_bit_reverse_lut[256] = {
1422 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0,
1423 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
1424 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4,
1425 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
1426 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc,
1427 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
1428 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca,
1429 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
1430 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6,
1431 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
1432 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,
1433 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
1434 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9,
1435 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
1436 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd,
1437 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
1438 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3,
1439 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
1440 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7,
1441 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
1442 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf,
1443 0x3f, 0xbf, 0x7f, 0xff
1444};
1445
1446static inline uint8_t zig_bit_reverse_u8(uint8_t value, uint8_t zig_type_bit_width) {
1447 const uint8_t reversed = zig_bit_reverse_lut[value] >> (8 - zig_type_bit_width);
1448 return zig_sign_extend_uint8_t(reversed, zig_type_bit_width);
1449}
1450
1451#define zig_bit_reverse_i8 zig_bit_reverse_u8
1452
1453static inline uint16_t zig_bit_reverse_u16(uint16_t value, uint8_t zig_type_bit_width) {
1454 const uint16_t swapped = zig_byte_swap_u16(value, zig_type_bit_width);
1455 const uint16_t reversed = (
1456 ((uint16_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) |
1457 ((uint16_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00));
1458 return zig_sign_extend_uint16_t(
1459 reversed & zig_bit_mask(uint16_t, zig_type_bit_width),
1460 zig_type_bit_width);
1461}
1462
1463#define zig_bit_reverse_i16 zig_bit_reverse_u16
1464
1465static inline uint32_t zig_bit_reverse_u32(uint32_t value, uint8_t zig_type_bit_width) {
1466 const uint32_t swapped = zig_byte_swap_u32(value, zig_type_bit_width);
1467 const uint32_t reversed = (
1468 ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x18) & 0xff] << 0x18) |
1469 ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x10) & 0xff] << 0x10) |
1470 ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) |
1471 ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00));
1472 return zig_sign_extend_uint32_t(
1473 reversed & zig_bit_mask(uint32_t, zig_type_bit_width),
1474 zig_type_bit_width);
1475}
1476
1477#define zig_bit_reverse_i32 zig_bit_reverse_u32
1478
1479static inline uint64_t zig_bit_reverse_u64(uint64_t value, uint8_t zig_type_bit_width) {
1480 const uint64_t swapped = zig_byte_swap_u64(value, zig_type_bit_width);
1481 const uint64_t reversed = (
1482 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x38) & 0xff] << 0x38) |
1483 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x30) & 0xff] << 0x30) |
1484 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x28) & 0xff] << 0x28) |
1485 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x20) & 0xff] << 0x20) |
1486 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x18) & 0xff] << 0x18) |
1487 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x10) & 0xff] << 0x10) |
1488 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) |
1489 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00));
1490 return zig_sign_extend_uint64_t(
1491 reversed & zig_bit_mask(uint64_t, zig_type_bit_width),
1492 zig_type_bit_width);
1493}
1494
1495#define zig_bit_reverse_i64 zig_bit_reverse_u64
1496
1497static inline uint128_t zig_bit_reverse_u128(uint128_t value, uint8_t zig_type_bit_width) {
1498 const uint128_t swapped = zig_byte_swap_u128(value, zig_type_bit_width);
1499 const uint128_t reversed = (
1500 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x78) & 0xff] << 0x78) |
1501 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x70) & 0xff] << 0x70) |
1502 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x68) & 0xff] << 0x68) |
1503 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x60) & 0xff] << 0x60) |
1504 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x58) & 0xff] << 0x58) |
1505 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x50) & 0xff] << 0x50) |
1506 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x48) & 0xff] << 0x48) |
1507 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x40) & 0xff] << 0x40) |
1508 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x38) & 0xff] << 0x38) |
1509 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x30) & 0xff] << 0x30) |
1510 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x28) & 0xff] << 0x28) |
1511 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x20) & 0xff] << 0x20) |
1512 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x18) & 0xff] << 0x18) |
1513 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x10) & 0xff] << 0x10) |
1514 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) |
1515 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00));
1516 return zig_sign_extend_uint128_t(
1517 reversed & zig_bit_mask(uint128_t, zig_type_bit_width),
1518 zig_type_bit_width);
1519}
1520
1521#define zig_bit_reverse_i128 zig_bit_reverse_u128
1522
1523static inline float zig_div_truncf(float numerator, float denominator) {
1524 return __builtin_truncf(numerator / denominator);
1525}
1526
1527static inline double zig_div_trunc(double numerator, double denominator) {
1528 return __builtin_trunc(numerator / denominator);
1529}
1530
1531static inline long double zig_div_truncl(long double numerator, long double denominator) {
1532 return __builtin_truncf(numerator / denominator);
1533}
1534
1535#define zig_div_trunc_f16 zig_div_truncf
1536#define zig_div_trunc_f32 zig_div_truncf
1537#define zig_div_trunc_f64 zig_div_trunc
1538#define zig_div_trunc_f80 zig_div_truncl
1539#define zig_div_trunc_f128 zig_div_truncl
1540
1541#define zig_div_floorf(numerator, denominator) \
1542 __builtin_floorf((float)(numerator) / (float)(denominator))
1543
1544#define zig_div_floor(numerator, denominator) \
1545 __builtin_floor((double)(numerator) / (double)(denominator))
1546
1547#define zig_div_floorl(numerator, denominator) \
1548 __builtin_floorl((long double)(numerator) / (long double)(denominator))
1549
1550#define zig_div_floor_f16 zig_div_floorf
1551#define zig_div_floor_f32 zig_div_floorf
1552#define zig_div_floor_f64 zig_div_floor
1553#define zig_div_floor_f80 zig_div_floorl
1554#define zig_div_floor_f128 zig_div_floorl
1555
1556#define zig_div_floor_u8 zig_div_floorf
1557#define zig_div_floor_i8 zig_div_floorf
1558#define zig_div_floor_u16 zig_div_floorf
1559#define zig_div_floor_i16 zig_div_floorf
1560#define zig_div_floor_u32 zig_div_floor
1561#define zig_div_floor_i32 zig_div_floor
1562#define zig_div_floor_u64 zig_div_floor
1563#define zig_div_floor_i64 zig_div_floor
1564#define zig_div_floor_u128 zig_div_floorl
1565#define zig_div_floor_i128 zig_div_floorl
1566
1567static inline float zig_modf(float numerator, float denominator) {
1568 return (numerator - (zig_div_floorf(numerator, denominator) * denominator));
1569}
1570
1571static inline double zig_mod(double numerator, double denominator) {
1572 return (numerator - (zig_div_floor(numerator, denominator) * denominator));
1573}
1574
1575static inline long double zig_modl(long double numerator, long double denominator) {
1576 return (numerator - (zig_div_floorl(numerator, denominator) * denominator));
1577}
1578
1579#define zig_mod_f16 zig_modf
1580#define zig_mod_f32 zig_modf
1581#define zig_mod_f64 zig_mod
1582#define zig_mod_f80 zig_modl
1583#define zig_mod_f128 zig_modl
1584
1585#define zig_mod_int(ZigType, CType) \
1586 static inline CType zig_mod_##ZigType(CType numerator, CType denominator) { \
1587 return (numerator - (zig_div_floor_##ZigType(numerator, denominator) * denominator)); \
1588 }
1589
1590zig_mod_int( u8, uint8_t)
1591zig_mod_int( i8, int8_t)
1592zig_mod_int( u16, uint16_t)
1593zig_mod_int( i16, int16_t)
1594zig_mod_int( u32, uint32_t)
1595zig_mod_int( i32, int32_t)
1596zig_mod_int( u64, uint64_t)
1597zig_mod_int( i64, int64_t)
1598zig_mod_int(u128, uint128_t)
1599zig_mod_int(i128, int128_t)
src/link/C.zig+1-1
......@@ -15,7 +15,7 @@ const Air = @import("../Air.zig");
1515const Liveness = @import("../Liveness.zig");
1616
1717pub const base_tag: link.File.Tag = .c;
18pub const zig_h = @embedFile("C/zig.h");
18pub const zig_h = "#include <zig.h>\n";
1919
2020base: link.File,
2121/// This linker backend does not try to incrementally link output C source code.
src/link/C/zig.h deleted-1599
......@@ -1,1599 +0,0 @@
1#undef linux
2
3#if __STDC_VERSION__ >= 201112L
4#define zig_noreturn _Noreturn
5#define zig_threadlocal thread_local
6#elif __GNUC__
7#define zig_noreturn __attribute__ ((noreturn))
8#define zig_threadlocal __thread
9#elif _MSC_VER
10#define zig_noreturn __declspec(noreturn)
11#define zig_threadlocal __declspec(thread)
12#else
13#define zig_noreturn
14#define zig_threadlocal zig_threadlocal_unavailable
15#endif
16
17#if __GNUC__
18#define ZIG_COLD __attribute__ ((cold))
19#else
20#define ZIG_COLD
21#endif
22
23#if __STDC_VERSION__ >= 199901L
24#define ZIG_RESTRICT restrict
25#elif defined(__GNUC__)
26#define ZIG_RESTRICT __restrict
27#else
28#define ZIG_RESTRICT
29#endif
30
31#if __STDC_VERSION__ >= 201112L
32#include <stdalign.h>
33#define ZIG_ALIGN(alignment) alignas(alignment)
34#elif defined(__GNUC__)
35#define ZIG_ALIGN(alignment) __attribute__((aligned(alignment)))
36#else
37#define ZIG_ALIGN(alignment) zig_compile_error("the C compiler being used does not support aligning variables")
38#endif
39
40#if __STDC_VERSION__ >= 199901L
41#include <stdbool.h>
42#else
43#define bool unsigned char
44#define true 1
45#define false 0
46#endif
47
48#if defined(__GNUC__)
49#define zig_unreachable() __builtin_unreachable()
50#else
51#define zig_unreachable()
52#endif
53
54#ifdef __cplusplus
55#define ZIG_EXTERN_C extern "C"
56#else
57#define ZIG_EXTERN_C
58#endif
59
60#if defined(_MSC_VER)
61#define zig_breakpoint() __debugbreak()
62#elif defined(__MINGW32__) || defined(__MINGW64__)
63#define zig_breakpoint() __debugbreak()
64#elif defined(__clang__)
65#define zig_breakpoint() __builtin_debugtrap()
66#elif defined(__GNUC__)
67#define zig_breakpoint() __builtin_trap()
68#elif defined(__i386__) || defined(__x86_64__)
69#define zig_breakpoint() __asm__ volatile("int $0x03");
70#else
71#define zig_breakpoint() raise(SIGTRAP)
72#endif
73
74#if defined(_MSC_VER)
75#define zig_return_address() _ReturnAddress()
76#elif defined(__GNUC__)
77#define zig_return_address() __builtin_extract_return_addr(__builtin_return_address(0))
78#else
79#define zig_return_address() 0
80#endif
81
82#if defined(__GNUC__)
83#define zig_frame_address() __builtin_frame_address(0)
84#else
85#define zig_frame_address() 0
86#endif
87
88#if defined(__GNUC__)
89#define zig_prefetch(addr, rw, locality) __builtin_prefetch(addr, rw, locality)
90#else
91#define zig_prefetch(addr, rw, locality)
92#endif
93
94#if defined(__clang__)
95#define zig_wasm_memory_size(index) __builtin_wasm_memory_size(index)
96#define zig_wasm_memory_grow(index, delta) __builtin_wasm_memory_grow(index, delta)
97#else
98#define zig_wasm_memory_size(index) zig_unimplemented()
99#define zig_wasm_memory_grow(index, delta) zig_unimplemented()
100#endif
101
102#if __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)
103#include <stdatomic.h>
104#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)
105#define zig_cmpxchg_weak (obj, expected, desired, succ, fail) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)
106#define zig_atomicrmw_xchg(obj, arg, order) atomic_exchange_explicit (obj, arg, order)
107#define zig_atomicrmw_add (obj, arg, order) atomic_fetch_add_explicit (obj, arg, order)
108#define zig_atomicrmw_sub (obj, arg, order) atomic_fetch_sub_explicit (obj, arg, order)
109#define zig_atomicrmw_or (obj, arg, order) atomic_fetch_or_explicit (obj, arg, order)
110#define zig_atomicrmw_xor (obj, arg, order) atomic_fetch_xor_explicit (obj, arg, order)
111#define zig_atomicrmw_and (obj, arg, order) atomic_fetch_and_explicit (obj, arg, order)
112#define zig_atomicrmw_nand(obj, arg, order) atomic_fetch_nand_explicit(obj, arg, order)
113#define zig_atomicrmw_min (obj, arg, order) atomic_fetch_min_explicit (obj, arg, order)
114#define zig_atomicrmw_max (obj, arg, order) atomic_fetch_max_explicit (obj, arg, order)
115#define zig_atomic_store (obj, arg, order) atomic_store_explicit (obj, arg, order)
116#define zig_atomic_load (obj, order) atomic_load_explicit (obj, order)
117#define zig_fence(order) atomic_thread_fence(order)
118#elif __GNUC__
119#define memory_order_relaxed __ATOMIC_RELAXED
120#define memory_order_consume __ATOMIC_CONSUME
121#define memory_order_acquire __ATOMIC_ACQUIRE
122#define memory_order_release __ATOMIC_RELEASE
123#define memory_order_acq_rel __ATOMIC_ACQ_REL
124#define memory_order_seq_cst __ATOMIC_SEQ_CST
125#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) __atomic_compare_exchange_n(obj, &(expected), desired, false, succ, fail)
126#define zig_cmpxchg_weak (obj, expected, desired, succ, fail) __atomic_compare_exchange_n(obj, &(expected), desired, true , succ, fail)
127#define zig_atomicrmw_xchg(obj, arg, order) __atomic_exchange_n(obj, arg, order)
128#define zig_atomicrmw_add (obj, arg, order) __atomic_fetch_add (obj, arg, order)
129#define zig_atomicrmw_sub (obj, arg, order) __atomic_fetch_sub (obj, arg, order)
130#define zig_atomicrmw_or (obj, arg, order) __atomic_fetch_or (obj, arg, order)
131#define zig_atomicrmw_xor (obj, arg, order) __atomic_fetch_xor (obj, arg, order)
132#define zig_atomicrmw_and (obj, arg, order) __atomic_fetch_and (obj, arg, order)
133#define zig_atomicrmw_nand(obj, arg, order) __atomic_fetch_nand(obj, arg, order)
134#define zig_atomicrmw_min (obj, arg, order) __atomic_fetch_min (obj, arg, order)
135#define zig_atomicrmw_max (obj, arg, order) __atomic_fetch_max (obj, arg, order)
136#define zig_atomic_store (obj, arg, order) __atomic_store (obj, arg, order)
137#define zig_atomic_load (obj, order) __atomic_load (obj, order)
138#define zig_fence(order) __atomic_thread_fence(order)
139#else
140#define memory_order_relaxed 0
141#define memory_order_consume 1
142#define memory_order_acquire 2
143#define memory_order_release 3
144#define memory_order_acq_rel 4
145#define memory_order_seq_cst 5
146#define zig_cmpxchg_strong(obj, expected, desired, succ, fail) zig_unimplemented()
147#define zig_cmpxchg_weak (obj, expected, desired, succ, fail) zig_unimplemented()
148#define zig_atomicrmw_xchg(obj, arg, order) zig_unimplemented()
149#define zig_atomicrmw_add (obj, arg, order) zig_unimplemented()
150#define zig_atomicrmw_sub (obj, arg, order) zig_unimplemented()
151#define zig_atomicrmw_or (obj, arg, order) zig_unimplemented()
152#define zig_atomicrmw_xor (obj, arg, order) zig_unimplemented()
153#define zig_atomicrmw_and (obj, arg, order) zig_unimplemented()
154#define zig_atomicrmw_nand(obj, arg, order) zig_unimplemented()
155#define zig_atomicrmw_min (obj, arg, order) zig_unimplemented()
156#define zig_atomicrmw_max (obj, arg, order) zig_unimplemented()
157#define zig_atomic_store (obj, arg, order) zig_unimplemented()
158#define zig_atomic_load (obj, order) zig_unimplemented()
159#define zig_fence(order) zig_unimplemented()
160#endif
161
162#include <stdint.h>
163#include <stddef.h>
164#include <limits.h>
165
166#define int128_t __int128
167#define uint128_t unsigned __int128
168#define UINT128_MAX ((uint128_t)(0xffffffffffffffffull) | 0xffffffffffffffffull)
169ZIG_EXTERN_C void *memcpy (void *ZIG_RESTRICT, const void *ZIG_RESTRICT, size_t);
170ZIG_EXTERN_C void *memset (void *, int, size_t);
171ZIG_EXTERN_C int64_t __addodi4(int64_t lhs, int64_t rhs, int *overflow);
172ZIG_EXTERN_C int128_t __addoti4(int128_t lhs, int128_t rhs, int *overflow);
173ZIG_EXTERN_C uint64_t __uaddodi4(uint64_t lhs, uint64_t rhs, int *overflow);
174ZIG_EXTERN_C uint128_t __uaddoti4(uint128_t lhs, uint128_t rhs, int *overflow);
175ZIG_EXTERN_C int32_t __subosi4(int32_t lhs, int32_t rhs, int *overflow);
176ZIG_EXTERN_C int64_t __subodi4(int64_t lhs, int64_t rhs, int *overflow);
177ZIG_EXTERN_C int128_t __suboti4(int128_t lhs, int128_t rhs, int *overflow);
178ZIG_EXTERN_C uint32_t __usubosi4(uint32_t lhs, uint32_t rhs, int *overflow);
179ZIG_EXTERN_C uint64_t __usubodi4(uint64_t lhs, uint64_t rhs, int *overflow);
180ZIG_EXTERN_C uint128_t __usuboti4(uint128_t lhs, uint128_t rhs, int *overflow);
181ZIG_EXTERN_C int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow);
182ZIG_EXTERN_C int128_t __muloti4(int128_t lhs, int128_t rhs, int *overflow);
183ZIG_EXTERN_C uint64_t __umulodi4(uint64_t lhs, uint64_t rhs, int *overflow);
184ZIG_EXTERN_C uint128_t __umuloti4(uint128_t lhs, uint128_t rhs, int *overflow);
185
186
187static inline uint8_t zig_addw_u8(uint8_t lhs, uint8_t rhs, uint8_t max) {
188 uint8_t thresh = max - rhs;
189 if (lhs > thresh) {
190 return lhs - thresh - 1;
191 } else {
192 return lhs + rhs;
193 }
194}
195
196static inline int8_t zig_addw_i8(int8_t lhs, int8_t rhs, int8_t min, int8_t max) {
197 if ((lhs > 0) && (rhs > 0)) {
198 int8_t thresh = max - rhs;
199 if (lhs > thresh) {
200 return min + lhs - thresh - 1;
201 }
202 } else if ((lhs < 0) && (rhs < 0)) {
203 int8_t thresh = min - rhs;
204 if (lhs < thresh) {
205 return max + lhs - thresh + 1;
206 }
207 }
208 return lhs + rhs;
209}
210
211static inline uint16_t zig_addw_u16(uint16_t lhs, uint16_t rhs, uint16_t max) {
212 uint16_t thresh = max - rhs;
213 if (lhs > thresh) {
214 return lhs - thresh - 1;
215 } else {
216 return lhs + rhs;
217 }
218}
219
220static inline int16_t zig_addw_i16(int16_t lhs, int16_t rhs, int16_t min, int16_t max) {
221 if ((lhs > 0) && (rhs > 0)) {
222 int16_t thresh = max - rhs;
223 if (lhs > thresh) {
224 return min + lhs - thresh - 1;
225 }
226 } else if ((lhs < 0) && (rhs < 0)) {
227 int16_t thresh = min - rhs;
228 if (lhs < thresh) {
229 return max + lhs - thresh + 1;
230 }
231 }
232 return lhs + rhs;
233}
234
235static inline uint32_t zig_addw_u32(uint32_t lhs, uint32_t rhs, uint32_t max) {
236 uint32_t thresh = max - rhs;
237 if (lhs > thresh) {
238 return lhs - thresh - 1;
239 } else {
240 return lhs + rhs;
241 }
242}
243
244static inline int32_t zig_addw_i32(int32_t lhs, int32_t rhs, int32_t min, int32_t max) {
245 if ((lhs > 0) && (rhs > 0)) {
246 int32_t thresh = max - rhs;
247 if (lhs > thresh) {
248 return min + lhs - thresh - 1;
249 }
250 } else if ((lhs < 0) && (rhs < 0)) {
251 int32_t thresh = min - rhs;
252 if (lhs < thresh) {
253 return max + lhs - thresh + 1;
254 }
255 }
256 return lhs + rhs;
257}
258
259static inline uint64_t zig_addw_u64(uint64_t lhs, uint64_t rhs, uint64_t max) {
260 uint64_t thresh = max - rhs;
261 if (lhs > thresh) {
262 return lhs - thresh - 1;
263 } else {
264 return lhs + rhs;
265 }
266}
267
268static inline int64_t zig_addw_i64(int64_t lhs, int64_t rhs, int64_t min, int64_t max) {
269 if ((lhs > 0) && (rhs > 0)) {
270 int64_t thresh = max - rhs;
271 if (lhs > thresh) {
272 return min + lhs - thresh - 1;
273 }
274 } else if ((lhs < 0) && (rhs < 0)) {
275 int64_t thresh = min - rhs;
276 if (lhs < thresh) {
277 return max + lhs - thresh + 1;
278 }
279 }
280 return lhs + rhs;
281}
282
283static inline intptr_t zig_addw_isize(intptr_t lhs, intptr_t rhs, intptr_t min, intptr_t max) {
284 return (intptr_t)(((uintptr_t)lhs) + ((uintptr_t)rhs));
285}
286
287static inline short zig_addw_short(short lhs, short rhs, short min, short max) {
288 return (short)(((unsigned short)lhs) + ((unsigned short)rhs));
289}
290
291static inline int zig_addw_int(int lhs, int rhs, int min, int max) {
292 return (int)(((unsigned)lhs) + ((unsigned)rhs));
293}
294
295static inline long zig_addw_long(long lhs, long rhs, long min, long max) {
296 return (long)(((unsigned long)lhs) + ((unsigned long)rhs));
297}
298
299static inline long long zig_addw_longlong(long long lhs, long long rhs, long long min, long long max) {
300 return (long long)(((unsigned long long)lhs) + ((unsigned long long)rhs));
301}
302
303static inline uint8_t zig_subw_u8(uint8_t lhs, uint8_t rhs, uint8_t max) {
304 if (lhs < rhs) {
305 return max - rhs - lhs + 1;
306 } else {
307 return lhs - rhs;
308 }
309}
310
311static inline int8_t zig_subw_i8(int8_t lhs, int8_t rhs, int8_t min, int8_t max) {
312 if ((lhs > 0) && (rhs < 0)) {
313 int8_t thresh = lhs - max;
314 if (rhs < thresh) {
315 return min + (thresh - rhs - 1);
316 }
317 } else if ((lhs < 0) && (rhs > 0)) {
318 int8_t thresh = lhs - min;
319 if (rhs > thresh) {
320 return max - (rhs - thresh - 1);
321 }
322 }
323 return lhs - rhs;
324}
325
326static inline uint16_t zig_subw_u16(uint16_t lhs, uint16_t rhs, uint16_t max) {
327 if (lhs < rhs) {
328 return max - rhs - lhs + 1;
329 } else {
330 return lhs - rhs;
331 }
332}
333
334static inline int16_t zig_subw_i16(int16_t lhs, int16_t rhs, int16_t min, int16_t max) {
335 if ((lhs > 0) && (rhs < 0)) {
336 int16_t thresh = lhs - max;
337 if (rhs < thresh) {
338 return min + (thresh - rhs - 1);
339 }
340 } else if ((lhs < 0) && (rhs > 0)) {
341 int16_t thresh = lhs - min;
342 if (rhs > thresh) {
343 return max - (rhs - thresh - 1);
344 }
345 }
346 return lhs - rhs;
347}
348
349static inline uint32_t zig_subw_u32(uint32_t lhs, uint32_t rhs, uint32_t max) {
350 if (lhs < rhs) {
351 return max - rhs - lhs + 1;
352 } else {
353 return lhs - rhs;
354 }
355}
356
357static inline int32_t zig_subw_i32(int32_t lhs, int32_t rhs, int32_t min, int32_t max) {
358 if ((lhs > 0) && (rhs < 0)) {
359 int32_t thresh = lhs - max;
360 if (rhs < thresh) {
361 return min + (thresh - rhs - 1);
362 }
363 } else if ((lhs < 0) && (rhs > 0)) {
364 int32_t thresh = lhs - min;
365 if (rhs > thresh) {
366 return max - (rhs - thresh - 1);
367 }
368 }
369 return lhs - rhs;
370}
371
372static inline uint64_t zig_subw_u64(uint64_t lhs, uint64_t rhs, uint64_t max) {
373 if (lhs < rhs) {
374 return max - rhs - lhs + 1;
375 } else {
376 return lhs - rhs;
377 }
378}
379
380static inline int64_t zig_subw_i64(int64_t lhs, int64_t rhs, int64_t min, int64_t max) {
381 if ((lhs > 0) && (rhs < 0)) {
382 int64_t thresh = lhs - max;
383 if (rhs < thresh) {
384 return min + (thresh - rhs - 1);
385 }
386 } else if ((lhs < 0) && (rhs > 0)) {
387 int64_t thresh = lhs - min;
388 if (rhs > thresh) {
389 return max - (rhs - thresh - 1);
390 }
391 }
392 return lhs - rhs;
393}
394
395static inline intptr_t zig_subw_isize(intptr_t lhs, intptr_t rhs, intptr_t min, intptr_t max) {
396 return (intptr_t)(((uintptr_t)lhs) - ((uintptr_t)rhs));
397}
398
399static inline short zig_subw_short(short lhs, short rhs, short min, short max) {
400 return (short)(((unsigned short)lhs) - ((unsigned short)rhs));
401}
402
403static inline int zig_subw_int(int lhs, int rhs, int min, int max) {
404 return (int)(((unsigned)lhs) - ((unsigned)rhs));
405}
406
407static inline long zig_subw_long(long lhs, long rhs, long min, long max) {
408 return (long)(((unsigned long)lhs) - ((unsigned long)rhs));
409}
410
411static inline long long zig_subw_longlong(long long lhs, long long rhs, long long min, long long max) {
412 return (long long)(((unsigned long long)lhs) - ((unsigned long long)rhs));
413}
414
415static inline bool zig_addo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) {
416#if defined(__GNUC__) && INT8_MAX == INT_MAX
417 if (min == INT8_MIN && max == INT8_MAX) {
418 return __builtin_sadd_overflow(lhs, rhs, (int*)res);
419 }
420#elif defined(__GNUC__) && INT8_MAX == LONG_MAX
421 if (min == INT8_MIN && max == INT8_MAX) {
422 return __builtin_saddl_overflow(lhs, rhs, (long*)res);
423 }
424#elif defined(__GNUC__) && INT8_MAX == LLONG_MAX
425 if (min == INT8_MIN && max == INT8_MAX) {
426 return __builtin_saddll_overflow(lhs, rhs, (long long*)res);
427 }
428#endif
429 int16_t big_result = (int16_t)lhs + (int16_t)rhs;
430 if (big_result > max) {
431 *res = big_result - ((int16_t)max - (int16_t)min);
432 return true;
433 }
434 if (big_result < min) {
435 *res = big_result + ((int16_t)max - (int16_t)min);
436 return true;
437 }
438 *res = big_result;
439 return false;
440}
441
442static inline bool zig_addo_i16(int16_t lhs, int16_t rhs, int16_t *res, int16_t min, int16_t max) {
443#if defined(__GNUC__) && INT16_MAX == INT_MAX
444 if (min == INT16_MIN && max == INT16_MAX) {
445 return __builtin_sadd_overflow(lhs, rhs, (int*)res);
446 }
447#elif defined(__GNUC__) && INT16_MAX == LONG_MAX
448 if (min == INT16_MIN && max == INT16_MAX) {
449 return __builtin_saddl_overflow(lhs, rhs, (long*)res);
450 }
451#elif defined(__GNUC__) && INT16_MAX == LLONG_MAX
452 if (min == INT16_MIN && max == INT16_MAX) {
453 return __builtin_saddll_overflow(lhs, rhs, (long long*)res);
454 }
455#endif
456 int32_t big_result = (int32_t)lhs + (int32_t)rhs;
457 if (big_result > max) {
458 *res = big_result - ((int32_t)max - (int32_t)min);
459 return true;
460 }
461 if (big_result < min) {
462 *res = big_result + ((int32_t)max - (int32_t)min);
463 return true;
464 }
465 *res = big_result;
466 return false;
467}
468
469static inline bool zig_addo_i32(int32_t lhs, int32_t rhs, int32_t *res, int32_t min, int32_t max) {
470#if defined(__GNUC__) && INT32_MAX == INT_MAX
471 if (min == INT32_MIN && max == INT32_MAX) {
472 return __builtin_sadd_overflow(lhs, rhs, (int*)res);
473 }
474#elif defined(__GNUC__) && INT32_MAX == LONG_MAX
475 if (min == INT32_MIN && max == INT32_MAX) {
476 return __builtin_saddl_overflow(lhs, rhs, (long*)res);
477 }
478#elif defined(__GNUC__) && INT32_MAX == LLONG_MAX
479 if (min == INT32_MIN && max == INT32_MAX) {
480 return __builtin_saddll_overflow(lhs, rhs, (long long*)res);
481 }
482#endif
483 int64_t big_result = (int64_t)lhs + (int64_t)rhs;
484 if (big_result > max) {
485 *res = big_result - ((int64_t)max - (int64_t)min);
486 return true;
487 }
488 if (big_result < min) {
489 *res = big_result + ((int64_t)max - (int64_t)min);
490 return true;
491 }
492 *res = big_result;
493 return false;
494}
495
496static inline bool zig_addo_i64(int64_t lhs, int64_t rhs, int64_t *res, int64_t min, int64_t max) {
497 bool overflow;
498#if defined(__GNUC__) && INT64_MAX == INT_MAX
499 overflow = __builtin_sadd_overflow(lhs, rhs, (int*)res);
500#elif defined(__GNUC__) && INT64_MAX == LONG_MAX
501 overflow = __builtin_saddl_overflow(lhs, rhs, (long*)res);
502#elif defined(__GNUC__) && INT64_MAX == LLONG_MAX
503 overflow = __builtin_saddll_overflow(lhs, rhs, (long long*)res);
504#else
505 int int_overflow;
506 *res = __addodi4(lhs, rhs, &int_overflow);
507 overflow = int_overflow != 0;
508#endif
509 if (!overflow) {
510 if (*res > max) {
511 // TODO adjust the result to be the truncated bits
512 return true;
513 } else if (*res < min) {
514 // TODO adjust the result to be the truncated bits
515 return true;
516 }
517 }
518 return overflow;
519}
520
521static inline bool zig_addo_i128(int128_t lhs, int128_t rhs, int128_t *res, int128_t min, int128_t max) {
522 bool overflow;
523#if defined(__GNUC__) && INT128_MAX == INT_MAX
524 overflow = __builtin_sadd_overflow(lhs, rhs, (int*)res);
525#elif defined(__GNUC__) && INT128_MAX == LONG_MAX
526 overflow = __builtin_saddl_overflow(lhs, rhs, (long*)res);
527#elif defined(__GNUC__) && INT128_MAX == LLONG_MAX
528 overflow = __builtin_saddll_overflow(lhs, rhs, (long long*)res);
529#else
530 int int_overflow;
531 *res = __addoti4(lhs, rhs, &int_overflow);
532 overflow = int_overflow != 0;
533#endif
534 if (!overflow) {
535 if (*res > max) {
536 // TODO adjust the result to be the truncated bits
537 return true;
538 } else if (*res < min) {
539 // TODO adjust the result to be the truncated bits
540 return true;
541 }
542 }
543 return overflow;
544}
545
546static inline bool zig_addo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t max) {
547#if defined(__GNUC__) && UINT8_MAX == UINT_MAX
548 if (max == UINT8_MAX) {
549 return __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res);
550 }
551#elif defined(__GNUC__) && UINT8_MAX == ULONG_MAX
552 if (max == UINT8_MAX) {
553 return __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res);
554 }
555#elif defined(__GNUC__) && UINT8_MAX == ULLONG_MAX
556 if (max == UINT8_MAX) {
557 return __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res);
558 }
559#endif
560 uint16_t big_result = (uint16_t)lhs + (uint16_t)rhs;
561 if (big_result > max) {
562 *res = big_result - max - 1;
563 return true;
564 }
565 *res = big_result;
566 return false;
567}
568
569static inline uint16_t zig_addo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint16_t max) {
570#if defined(__GNUC__) && UINT16_MAX == UINT_MAX
571 if (max == UINT16_MAX) {
572 return __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res);
573 }
574#elif defined(__GNUC__) && UINT16_MAX == ULONG_MAX
575 if (max == UINT16_MAX) {
576 return __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res);
577 }
578#elif defined(__GNUC__) && UINT16_MAX == ULLONG_MAX
579 if (max == UINT16_MAX) {
580 return __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res);
581 }
582#endif
583 uint32_t big_result = (uint32_t)lhs + (uint32_t)rhs;
584 if (big_result > max) {
585 *res = big_result - max - 1;
586 return true;
587 }
588 *res = big_result;
589 return false;
590}
591
592static inline uint32_t zig_addo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint32_t max) {
593#if defined(__GNUC__) && UINT32_MAX == UINT_MAX
594 if (max == UINT32_MAX) {
595 return __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res);
596 }
597#elif defined(__GNUC__) && UINT32_MAX == ULONG_MAX
598 if (max == UINT32_MAX) {
599 return __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res);
600 }
601#elif defined(__GNUC__) && UINT32_MAX == ULLONG_MAX
602 if (max == UINT32_MAX) {
603 return __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res);
604 }
605#endif
606 uint64_t big_result = (uint64_t)lhs + (uint64_t)rhs;
607 if (big_result > max) {
608 *res = big_result - max - 1;
609 return true;
610 }
611 *res = big_result;
612 return false;
613}
614
615static inline uint64_t zig_addo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint64_t max) {
616 bool overflow;
617#if defined(__GNUC__) && UINT64_MAX == UINT_MAX
618 overflow = __builtin_uadd_overflow(lhs, rhs, (unsigned int*)res);
619#elif defined(__GNUC__) && UINT64_MAX == ULONG_MAX
620 overflow = __builtin_uaddl_overflow(lhs, rhs, (unsigned long*)res);
621#elif defined(__GNUC__) && UINT64_MAX == ULLONG_MAX
622 overflow = __builtin_uaddll_overflow(lhs, rhs, (unsigned long long*)res);
623#else
624 int int_overflow;
625 *res = __uaddodi4(lhs, rhs, &int_overflow);
626 overflow = int_overflow != 0;
627#endif
628 if (*res > max && !overflow) {
629 *res -= max - 1;
630 return true;
631 }
632 return overflow;
633}
634
635static inline uint128_t zig_addo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) {
636 int overflow;
637 *res = __uaddoti4(lhs, rhs, &overflow);
638 if (*res > max && overflow == 0) {
639 *res -= max - 1;
640 return true;
641 }
642 return overflow != 0;
643}
644
645static inline bool zig_subo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) {
646#if defined(__GNUC__) && INT8_MAX == INT_MAX
647 if (min == INT8_MIN && max == INT8_MAX) {
648 return __builtin_ssub_overflow(lhs, rhs, (int*)res);
649 }
650#elif defined(__GNUC__) && INT8_MAX == LONG_MAX
651 if (min == INT8_MIN && max == INT8_MAX) {
652 return __builtin_ssubl_overflow(lhs, rhs, (long*)res);
653 }
654#elif defined(__GNUC__) && INT8_MAX == LLONG_MAX
655 if (min == INT8_MIN && max == INT8_MAX) {
656 return __builtin_ssubll_overflow(lhs, rhs, (long long*)res);
657 }
658#endif
659 int16_t big_result = (int16_t)lhs - (int16_t)rhs;
660 if (big_result > max) {
661 *res = big_result - ((int16_t)max - (int16_t)min);
662 return true;
663 }
664 if (big_result < min) {
665 *res = big_result + ((int16_t)max - (int16_t)min);
666 return true;
667 }
668 *res = big_result;
669 return false;
670}
671
672static inline bool zig_subo_i16(int16_t lhs, int16_t rhs, int16_t *res, int16_t min, int16_t max) {
673#if defined(__GNUC__) && INT16_MAX == INT_MAX
674 if (min == INT16_MIN && max == INT16_MAX) {
675 return __builtin_ssub_overflow(lhs, rhs, (int*)res);
676 }
677#elif defined(__GNUC__) && INT16_MAX == LONG_MAX
678 if (min == INT16_MIN && max == INT16_MAX) {
679 return __builtin_ssubl_overflow(lhs, rhs, (long*)res);
680 }
681#elif defined(__GNUC__) && INT16_MAX == LLONG_MAX
682 if (min == INT16_MIN && max == INT16_MAX) {
683 return __builtin_ssubll_overflow(lhs, rhs, (long long*)res);
684 }
685#endif
686 int32_t big_result = (int32_t)lhs - (int32_t)rhs;
687 if (big_result > max) {
688 *res = big_result - ((int32_t)max - (int32_t)min);
689 return true;
690 }
691 if (big_result < min) {
692 *res = big_result + ((int32_t)max - (int32_t)min);
693 return true;
694 }
695 *res = big_result;
696 return false;
697}
698
699static inline bool zig_subo_i32(int32_t lhs, int32_t rhs, int32_t *res, int32_t min, int32_t max) {
700#if defined(__GNUC__) && INT32_MAX == INT_MAX
701 if (min == INT32_MIN && max == INT32_MAX) {
702 return __builtin_ssub_overflow(lhs, rhs, (int*)res);
703 }
704#elif defined(__GNUC__) && INT32_MAX == LONG_MAX
705 if (min == INT32_MIN && max == INT32_MAX) {
706 return __builtin_ssubl_overflow(lhs, rhs, (long*)res);
707 }
708#elif defined(__GNUC__) && INT32_MAX == LLONG_MAX
709 if (min == INT32_MIN && max == INT32_MAX) {
710 return __builtin_ssubll_overflow(lhs, rhs, (long long*)res);
711 }
712#endif
713 int64_t big_result = (int64_t)lhs - (int64_t)rhs;
714 if (big_result > max) {
715 *res = big_result - ((int64_t)max - (int64_t)min);
716 return true;
717 }
718 if (big_result < min) {
719 *res = big_result + ((int64_t)max - (int64_t)min);
720 return true;
721 }
722 *res = big_result;
723 return false;
724}
725
726static inline bool zig_subo_i64(int64_t lhs, int64_t rhs, int64_t *res, int64_t min, int64_t max) {
727 bool overflow;
728#if defined(__GNUC__) && INT64_MAX == INT_MAX
729 overflow = __builtin_ssub_overflow(lhs, rhs, (int*)res);
730#elif defined(__GNUC__) && INT64_MAX == LONG_MAX
731 overflow = __builtin_ssubl_overflow(lhs, rhs, (long*)res);
732#elif defined(__GNUC__) && INT64_MAX == LLONG_MAX
733 overflow = __builtin_ssubll_overflow(lhs, rhs, (long long*)res);
734#else
735 int int_overflow;
736 *res = __subodi4(lhs, rhs, &int_overflow);
737 overflow = int_overflow != 0;
738#endif
739 if (!overflow) {
740 if (*res > max) {
741 // TODO adjust the result to be the truncated bits
742 return true;
743 } else if (*res < min) {
744 // TODO adjust the result to be the truncated bits
745 return true;
746 }
747 }
748 return overflow;
749}
750
751static inline bool zig_subo_i128(int128_t lhs, int128_t rhs, int128_t *res, int128_t min, int128_t max) {
752 bool overflow;
753#if defined(__GNUC__) && INT128_MAX == INT_MAX
754 overflow = __builtin_ssub_overflow(lhs, rhs, (int*)res);
755#elif defined(__GNUC__) && INT128_MAX == LONG_MAX
756 overflow = __builtin_ssubl_overflow(lhs, rhs, (long*)res);
757#elif defined(__GNUC__) && INT128_MAX == LLONG_MAX
758 overflow = __builtin_ssubll_overflow(lhs, rhs, (long long*)res);
759#else
760 int int_overflow;
761 *res = __suboti4(lhs, rhs, &int_overflow);
762 overflow = int_overflow != 0;
763#endif
764 if (!overflow) {
765 if (*res > max) {
766 // TODO adjust the result to be the truncated bits
767 return true;
768 } else if (*res < min) {
769 // TODO adjust the result to be the truncated bits
770 return true;
771 }
772 }
773 return overflow;
774}
775
776static inline bool zig_subo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t max) {
777#if defined(__GNUC__) && UINT8_MAX == UINT_MAX
778 return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res);
779#elif defined(__GNUC__) && UINT8_MAX == ULONG_MAX
780 return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res);
781#elif defined(__GNUC__) && UINT8_MAX == ULLONG_MAX
782 return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res);
783#endif
784 if (rhs > lhs) {
785 *res = max - (rhs - lhs - 1);
786 return true;
787 }
788 *res = lhs - rhs;
789 return false;
790}
791
792static inline uint16_t zig_subo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint16_t max) {
793#if defined(__GNUC__) && UINT16_MAX == UINT_MAX
794 return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res);
795#elif defined(__GNUC__) && UINT16_MAX == ULONG_MAX
796 return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res);
797#elif defined(__GNUC__) && UINT16_MAX == ULLONG_MAX
798 return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res);
799#endif
800 if (rhs > lhs) {
801 *res = max - (rhs - lhs - 1);
802 return true;
803 }
804 *res = lhs - rhs;
805 return false;
806}
807
808static inline uint32_t zig_subo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint32_t max) {
809 if (max == UINT32_MAX) {
810#if defined(__GNUC__) && UINT32_MAX == UINT_MAX
811 return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res);
812#elif defined(__GNUC__) && UINT32_MAX == ULONG_MAX
813 return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res);
814#elif defined(__GNUC__) && UINT32_MAX == ULLONG_MAX
815 return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res);
816#endif
817 int int_overflow;
818 *res = __usubosi4(lhs, rhs, &int_overflow);
819 return int_overflow != 0;
820 } else {
821 if (rhs > lhs) {
822 *res = max - (rhs - lhs - 1);
823 return true;
824 }
825 *res = lhs - rhs;
826 return false;
827 }
828}
829
830static inline uint64_t zig_subo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint64_t max) {
831 if (max == UINT64_MAX) {
832#if defined(__GNUC__) && UINT64_MAX == UINT_MAX
833 return __builtin_usub_overflow(lhs, rhs, (unsigned int*)res);
834#elif defined(__GNUC__) && UINT64_MAX == ULONG_MAX
835 return __builtin_usubl_overflow(lhs, rhs, (unsigned long*)res);
836#elif defined(__GNUC__) && UINT64_MAX == ULLONG_MAX
837 return __builtin_usubll_overflow(lhs, rhs, (unsigned long long*)res);
838#else
839 int int_overflow;
840 *res = __usubodi4(lhs, rhs, &int_overflow);
841 return int_overflow != 0;
842#endif
843 } else {
844 if (rhs > lhs) {
845 *res = max - (rhs - lhs - 1);
846 return true;
847 }
848 *res = lhs - rhs;
849 return false;
850 }
851}
852
853static inline uint128_t zig_subo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) {
854 if (max == UINT128_MAX) {
855 int int_overflow;
856 *res = __usuboti4(lhs, rhs, &int_overflow);
857 return int_overflow != 0;
858 } else {
859 if (rhs > lhs) {
860 *res = max - (rhs - lhs - 1);
861 return true;
862 }
863 *res = lhs - rhs;
864 return false;
865 }
866}
867
868static inline bool zig_mulo_i8(int8_t lhs, int8_t rhs, int8_t *res, int8_t min, int8_t max) {
869#if defined(__GNUC__) && INT8_MAX == INT_MAX
870 if (min == INT8_MIN && max == INT8_MAX) {
871 return __builtin_smul_overflow(lhs, rhs, (int*)res);
872 }
873#elif defined(__GNUC__) && INT8_MAX == LONG_MAX
874 if (min == INT8_MIN && max == INT8_MAX) {
875 return __builtin_smull_overflow(lhs, rhs, (long*)res);
876 }
877#elif defined(__GNUC__) && INT8_MAX == LLONG_MAX
878 if (min == INT8_MIN && max == INT8_MAX) {
879 return __builtin_smulll_overflow(lhs, rhs, (long long*)res);
880 }
881#endif
882 int16_t big_result = (int16_t)lhs * (int16_t)rhs;
883 if (big_result > max) {
884 *res = big_result - ((int16_t)max - (int16_t)min);
885 return true;
886 }
887 if (big_result < min) {
888 *res = big_result + ((int16_t)max - (int16_t)min);
889 return true;
890 }
891 *res = big_result;
892 return false;
893}
894
895static inline bool zig_mulo_i16(int16_t lhs, int16_t rhs, int16_t *res, int16_t min, int16_t max) {
896#if defined(__GNUC__) && INT16_MAX == INT_MAX
897 if (min == INT16_MIN && max == INT16_MAX) {
898 return __builtin_smul_overflow(lhs, rhs, (int*)res);
899 }
900#elif defined(__GNUC__) && INT16_MAX == LONG_MAX
901 if (min == INT16_MIN && max == INT16_MAX) {
902 return __builtin_smull_overflow(lhs, rhs, (long*)res);
903 }
904#elif defined(__GNUC__) && INT16_MAX == LLONG_MAX
905 if (min == INT16_MIN && max == INT16_MAX) {
906 return __builtin_smulll_overflow(lhs, rhs, (long long*)res);
907 }
908#endif
909 int32_t big_result = (int32_t)lhs * (int32_t)rhs;
910 if (big_result > max) {
911 *res = big_result - ((int32_t)max - (int32_t)min);
912 return true;
913 }
914 if (big_result < min) {
915 *res = big_result + ((int32_t)max - (int32_t)min);
916 return true;
917 }
918 *res = big_result;
919 return false;
920}
921
922static inline bool zig_mulo_i32(int32_t lhs, int32_t rhs, int32_t *res, int32_t min, int32_t max) {
923#if defined(__GNUC__) && INT32_MAX == INT_MAX
924 if (min == INT32_MIN && max == INT32_MAX) {
925 return __builtin_smul_overflow(lhs, rhs, (int*)res);
926 }
927#elif defined(__GNUC__) && INT32_MAX == LONG_MAX
928 if (min == INT32_MIN && max == INT32_MAX) {
929 return __builtin_smull_overflow(lhs, rhs, (long*)res);
930 }
931#elif defined(__GNUC__) && INT32_MAX == LLONG_MAX
932 if (min == INT32_MIN && max == INT32_MAX) {
933 return __builtin_smulll_overflow(lhs, rhs, (long long*)res);
934 }
935#endif
936 int64_t big_result = (int64_t)lhs * (int64_t)rhs;
937 if (big_result > max) {
938 *res = big_result - ((int64_t)max - (int64_t)min);
939 return true;
940 }
941 if (big_result < min) {
942 *res = big_result + ((int64_t)max - (int64_t)min);
943 return true;
944 }
945 *res = big_result;
946 return false;
947}
948
949static inline bool zig_mulo_i64(int64_t lhs, int64_t rhs, int64_t *res, int64_t min, int64_t max) {
950 bool overflow;
951#if defined(__GNUC__) && INT64_MAX == INT_MAX
952 overflow = __builtin_smul_overflow(lhs, rhs, (int*)res);
953#elif defined(__GNUC__) && INT64_MAX == LONG_MAX
954 overflow = __builtin_smull_overflow(lhs, rhs, (long*)res);
955#elif defined(__GNUC__) && INT64_MAX == LLONG_MAX
956 overflow = __builtin_smulll_overflow(lhs, rhs, (long long*)res);
957#else
958 int int_overflow;
959 *res = __mulodi4(lhs, rhs, &int_overflow);
960 overflow = int_overflow != 0;
961#endif
962 if (!overflow) {
963 if (*res > max) {
964 // TODO adjust the result to be the truncated bits
965 return true;
966 } else if (*res < min) {
967 // TODO adjust the result to be the truncated bits
968 return true;
969 }
970 }
971 return overflow;
972}
973
974static inline bool zig_mulo_i128(int128_t lhs, int128_t rhs, int128_t *res, int128_t min, int128_t max) {
975 bool overflow;
976#if defined(__GNUC__) && INT128_MAX == INT_MAX
977 overflow = __builtin_smul_overflow(lhs, rhs, (int*)res);
978#elif defined(__GNUC__) && INT128_MAX == LONG_MAX
979 overflow = __builtin_smull_overflow(lhs, rhs, (long*)res);
980#elif defined(__GNUC__) && INT128_MAX == LLONG_MAX
981 overflow = __builtin_smulll_overflow(lhs, rhs, (long long*)res);
982#else
983 int int_overflow;
984 *res = __muloti4(lhs, rhs, &int_overflow);
985 overflow = int_overflow != 0;
986#endif
987 if (!overflow) {
988 if (*res > max) {
989 // TODO adjust the result to be the truncated bits
990 return true;
991 } else if (*res < min) {
992 // TODO adjust the result to be the truncated bits
993 return true;
994 }
995 }
996 return overflow;
997}
998
999static inline bool zig_mulo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t max) {
1000#if defined(__GNUC__) && UINT8_MAX == UINT_MAX
1001 if (max == UINT8_MAX) {
1002 return __builtin_umul_overflow(lhs, rhs, (unsigned int*)res);
1003 }
1004#elif defined(__GNUC__) && UINT8_MAX == ULONG_MAX
1005 if (max == UINT8_MAX) {
1006 return __builtin_umull_overflow(lhs, rhs, (unsigned long*)res);
1007 }
1008#elif defined(__GNUC__) && UINT8_MAX == ULLONG_MAX
1009 if (max == UINT8_MAX) {
1010 return __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res);
1011 }
1012#endif
1013 uint16_t big_result = (uint16_t)lhs * (uint16_t)rhs;
1014 if (big_result > max) {
1015 *res = big_result - max - 1;
1016 return true;
1017 }
1018 *res = big_result;
1019 return false;
1020}
1021
1022static inline uint16_t zig_mulo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint16_t max) {
1023#if defined(__GNUC__) && UINT16_MAX == UINT_MAX
1024 if (max == UINT16_MAX) {
1025 return __builtin_umul_overflow(lhs, rhs, (unsigned int*)res);
1026 }
1027#elif defined(__GNUC__) && UINT16_MAX == ULONG_MAX
1028 if (max == UINT16_MAX) {
1029 return __builtin_umull_overflow(lhs, rhs, (unsigned long*)res);
1030 }
1031#elif defined(__GNUC__) && UINT16_MAX == ULLONG_MAX
1032 if (max == UINT16_MAX) {
1033 return __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res);
1034 }
1035#endif
1036 uint32_t big_result = (uint32_t)lhs * (uint32_t)rhs;
1037 if (big_result > max) {
1038 *res = big_result - max - 1;
1039 return true;
1040 }
1041 *res = big_result;
1042 return false;
1043}
1044
1045static inline uint32_t zig_mulo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint32_t max) {
1046#if defined(__GNUC__) && UINT32_MAX == UINT_MAX
1047 if (max == UINT32_MAX) {
1048 return __builtin_umul_overflow(lhs, rhs, (unsigned int*)res);
1049 }
1050#elif defined(__GNUC__) && UINT32_MAX == ULONG_MAX
1051 if (max == UINT32_MAX) {
1052 return __builtin_umull_overflow(lhs, rhs, (unsigned long*)res);
1053 }
1054#elif defined(__GNUC__) && UINT32_MAX == ULLONG_MAX
1055 if (max == UINT32_MAX) {
1056 return __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res);
1057 }
1058#endif
1059 uint64_t big_result = (uint64_t)lhs * (uint64_t)rhs;
1060 if (big_result > max) {
1061 *res = big_result - max - 1;
1062 return true;
1063 }
1064 *res = big_result;
1065 return false;
1066}
1067
1068static inline uint64_t zig_mulo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint64_t max) {
1069 bool overflow;
1070#if defined(__GNUC__) && UINT64_MAX == UINT_MAX
1071 overflow = __builtin_umul_overflow(lhs, rhs, (unsigned int*)res);
1072#elif defined(__GNUC__) && UINT64_MAX == ULONG_MAX
1073 overflow = __builtin_umull_overflow(lhs, rhs, (unsigned long*)res);
1074#elif defined(__GNUC__) && UINT64_MAX == ULLONG_MAX
1075 overflow = __builtin_umulll_overflow(lhs, rhs, (unsigned long long*)res);
1076#else
1077 int int_overflow;
1078 *res = __umulodi4(lhs, rhs, &int_overflow);
1079 overflow = int_overflow != 0;
1080#endif
1081 if (*res > max && !overflow) {
1082 *res -= max - 1;
1083 return true;
1084 }
1085 return overflow;
1086}
1087
1088static inline uint128_t zig_mulo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint128_t max) {
1089 int overflow;
1090 *res = __umuloti4(lhs, rhs, &overflow);
1091 if (*res > max && overflow == 0) {
1092 *res -= max - 1;
1093 return true;
1094 }
1095 return overflow != 0;
1096}
1097
1098static inline float zig_bitcast_f32_u32(uint32_t arg) {
1099 float dest;
1100 memcpy(&dest, &arg, sizeof dest);
1101 return dest;
1102}
1103
1104static inline float zig_bitcast_f64_u64(uint64_t arg) {
1105 double dest;
1106 memcpy(&dest, &arg, sizeof dest);
1107 return dest;
1108}
1109
1110#define zig_add_sat_u(ZT, T) static inline T zig_adds_##ZT(T x, T y, T max) { \
1111 return (x > max - y) ? max : x + y; \
1112}
1113
1114#define zig_add_sat_s(ZT, T, T2) static inline T zig_adds_##ZT(T2 x, T2 y, T2 min, T2 max) { \
1115 T2 res = x + y; \
1116 return (res < min) ? min : (res > max) ? max : res; \
1117}
1118
1119zig_add_sat_u( u8, uint8_t)
1120zig_add_sat_s( i8, int8_t, int16_t)
1121zig_add_sat_u(u16, uint16_t)
1122zig_add_sat_s(i16, int16_t, int32_t)
1123zig_add_sat_u(u32, uint32_t)
1124zig_add_sat_s(i32, int32_t, int64_t)
1125zig_add_sat_u(u64, uint64_t)
1126zig_add_sat_s(i64, int64_t, int128_t)
1127zig_add_sat_s(isize, intptr_t, int128_t)
1128zig_add_sat_s(short, short, int)
1129zig_add_sat_s(int, int, long)
1130zig_add_sat_s(long, long, long long)
1131
1132#define zig_sub_sat_u(ZT, T) static inline T zig_subs_##ZT(T x, T y, T max) { \
1133 return (x > max + y) ? max : x - y; \
1134}
1135
1136#define zig_sub_sat_s(ZT, T, T2) static inline T zig_subs_##ZT(T2 x, T2 y, T2 min, T2 max) { \
1137 T2 res = x - y; \
1138 return (res < min) ? min : (res > max) ? max : res; \
1139}
1140
1141zig_sub_sat_u( u8, uint8_t)
1142zig_sub_sat_s( i8, int8_t, int16_t)
1143zig_sub_sat_u(u16, uint16_t)
1144zig_sub_sat_s(i16, int16_t, int32_t)
1145zig_sub_sat_u(u32, uint32_t)
1146zig_sub_sat_s(i32, int32_t, int64_t)
1147zig_sub_sat_u(u64, uint64_t)
1148zig_sub_sat_s(i64, int64_t, int128_t)
1149zig_sub_sat_s(isize, intptr_t, int128_t)
1150zig_sub_sat_s(short, short, int)
1151zig_sub_sat_s(int, int, long)
1152zig_sub_sat_s(long, long, long long)
1153
1154
1155#define zig_mul_sat_u(ZT, T, T2) static inline T zig_muls_##ZT(T2 x, T2 y, T2 max) { \
1156 T2 res = x * y; \
1157 return (res > max) ? max : res; \
1158}
1159
1160#define zig_mul_sat_s(ZT, T, T2) static inline T zig_muls_##ZT(T2 x, T2 y, T2 min, T2 max) { \
1161 T2 res = x * y; \
1162 return (res < min) ? min : (res > max) ? max : res; \
1163}
1164
1165zig_mul_sat_u(u8, uint8_t, uint16_t)
1166zig_mul_sat_s(i8, int8_t, int16_t)
1167zig_mul_sat_u(u16, uint16_t, uint32_t)
1168zig_mul_sat_s(i16, int16_t, int32_t)
1169zig_mul_sat_u(u32, uint32_t, uint64_t)
1170zig_mul_sat_s(i32, int32_t, int64_t)
1171zig_mul_sat_u(u64, uint64_t, uint128_t)
1172zig_mul_sat_s(i64, int64_t, int128_t)
1173zig_mul_sat_s(isize, intptr_t, int128_t)
1174zig_mul_sat_s(short, short, int)
1175zig_mul_sat_s(int, int, long)
1176zig_mul_sat_s(long, long, long long)
1177
1178#define zig_shl_sat_u(ZT, T, bits) static inline T zig_shls_##ZT(T x, T y, T max) { \
1179 if(x == 0) return 0; \
1180 T bits_set = 64 - __builtin_clzll(x); \
1181 return (bits_set + y > bits) ? max : x << y; \
1182}
1183
1184#define zig_shl_sat_s(ZT, T, bits) static inline T zig_shls_##ZT(T x, T y, T min, T max) { \
1185 if(x == 0) return 0; \
1186 T x_twos_comp = x < 0 ? -x : x; \
1187 T bits_set = 64 - __builtin_clzll(x_twos_comp); \
1188 T min_or_max = (x < 0) ? min : max; \
1189 return (y + bits_set > bits ) ? min_or_max : x << y; \
1190}
1191
1192zig_shl_sat_u(u8, uint8_t, 8)
1193zig_shl_sat_s(i8, int8_t, 7)
1194zig_shl_sat_u(u16, uint16_t, 16)
1195zig_shl_sat_s(i16, int16_t, 15)
1196zig_shl_sat_u(u32, uint32_t, 32)
1197zig_shl_sat_s(i32, int32_t, 31)
1198zig_shl_sat_u(u64, uint64_t, 64)
1199zig_shl_sat_s(i64, int64_t, 63)
1200zig_shl_sat_s(isize, intptr_t, ((sizeof(intptr_t)) * CHAR_BIT - 1))
1201zig_shl_sat_s(short, short, ((sizeof(short )) * CHAR_BIT - 1))
1202zig_shl_sat_s(int, int, ((sizeof(int )) * CHAR_BIT - 1))
1203zig_shl_sat_s(long, long, ((sizeof(long )) * CHAR_BIT - 1))
1204
1205#define zig_bitsizeof(T) (CHAR_BIT * sizeof(T))
1206#define zig_bit_mask(T, bit_width) \
1207 ((bit_width) == zig_bitsizeof(T) \
1208 ? ((T)-1) \
1209 : (((T)1 << (T)(bit_width)) - 1))
1210
1211static inline int zig_clz(unsigned int value, uint8_t zig_type_bit_width) {
1212 if (value == 0) return zig_type_bit_width;
1213 return __builtin_clz(value) - zig_bitsizeof(unsigned int) + zig_type_bit_width;
1214}
1215
1216static inline int zig_clzl(unsigned long value, uint8_t zig_type_bit_width) {
1217 if (value == 0) return zig_type_bit_width;
1218 return __builtin_clzl(value) - zig_bitsizeof(unsigned long) + zig_type_bit_width;
1219}
1220
1221static inline int zig_clzll(unsigned long long value, uint8_t zig_type_bit_width) {
1222 if (value == 0) return zig_type_bit_width;
1223 return __builtin_clzll(value) - zig_bitsizeof(unsigned long long) + zig_type_bit_width;
1224}
1225
1226#define zig_clz_u8 zig_clz
1227#define zig_clz_i8 zig_clz
1228#define zig_clz_u16 zig_clz
1229#define zig_clz_i16 zig_clz
1230#define zig_clz_u32 zig_clzl
1231#define zig_clz_i32 zig_clzl
1232#define zig_clz_u64 zig_clzll
1233#define zig_clz_i64 zig_clzll
1234
1235static inline int zig_clz_u128(uint128_t value, uint8_t zig_type_bit_width) {
1236 if (value == 0) return zig_type_bit_width;
1237 const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width);
1238 const uint64_t hi = (value & mask) >> 64;
1239 const uint64_t lo = (value & mask);
1240 const int leading_zeroes = (
1241 hi != 0 ? __builtin_clzll(hi) : 64 + (lo != 0 ? __builtin_clzll(lo) : 64));
1242 return leading_zeroes - zig_bitsizeof(uint128_t) + zig_type_bit_width;
1243}
1244
1245#define zig_clz_i128 zig_clz_u128
1246
1247static inline int zig_ctz(unsigned int value, uint8_t zig_type_bit_width) {
1248 if (value == 0) return zig_type_bit_width;
1249 return __builtin_ctz(value & zig_bit_mask(unsigned int, zig_type_bit_width));
1250}
1251
1252static inline int zig_ctzl(unsigned long value, uint8_t zig_type_bit_width) {
1253 if (value == 0) return zig_type_bit_width;
1254 return __builtin_ctzl(value & zig_bit_mask(unsigned long, zig_type_bit_width));
1255}
1256
1257static inline int zig_ctzll(unsigned long value, uint8_t zig_type_bit_width) {
1258 if (value == 0) return zig_type_bit_width;
1259 return __builtin_ctzll(value & zig_bit_mask(unsigned long, zig_type_bit_width));
1260}
1261
1262#define zig_ctz_u8 zig_ctz
1263#define zig_ctz_i8 zig_ctz
1264#define zig_ctz_u16 zig_ctz
1265#define zig_ctz_i16 zig_ctz
1266#define zig_ctz_u32 zig_ctzl
1267#define zig_ctz_i32 zig_ctzl
1268#define zig_ctz_u64 zig_ctzll
1269#define zig_ctz_i64 zig_ctzll
1270
1271static inline int zig_ctz_u128(uint128_t value, uint8_t zig_type_bit_width) {
1272 const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width);
1273 const uint64_t hi = (value & mask) >> 64;
1274 const uint64_t lo = (value & mask);
1275 return (lo != 0 ? __builtin_ctzll(lo) : 64 + (hi != 0 ? __builtin_ctzll(hi) : 64));
1276}
1277
1278#define zig_ctz_i128 zig_ctz_u128
1279
1280static inline int zig_popcount(unsigned int value, uint8_t zig_type_bit_width) {
1281 return __builtin_popcount(value & zig_bit_mask(unsigned int, zig_type_bit_width));
1282}
1283
1284static inline int zig_popcountl(unsigned long value, uint8_t zig_type_bit_width) {
1285 return __builtin_popcountl(value & zig_bit_mask(unsigned long, zig_type_bit_width));
1286}
1287
1288static inline int zig_popcountll(unsigned long value, uint8_t zig_type_bit_width) {
1289 return __builtin_popcountll(value & zig_bit_mask(unsigned long, zig_type_bit_width));
1290}
1291
1292#define zig_popcount_u8 zig_popcount
1293#define zig_popcount_i8 zig_popcount
1294#define zig_popcount_u16 zig_popcount
1295#define zig_popcount_i16 zig_popcount
1296#define zig_popcount_u32 zig_popcountl
1297#define zig_popcount_i32 zig_popcountl
1298#define zig_popcount_u64 zig_popcountll
1299#define zig_popcount_i64 zig_popcountll
1300
1301static inline int zig_popcount_u128(uint128_t value, uint8_t zig_type_bit_width) {
1302 const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width);
1303 const uint64_t hi = (value & mask) >> 64;
1304 const uint64_t lo = (value & mask);
1305 return __builtin_popcountll(hi) + __builtin_popcountll(lo);
1306}
1307
1308#define zig_popcount_i128 zig_popcount_u128
1309
1310static inline bool zig_shlo_i8(int8_t lhs, int8_t rhs, int8_t *res, uint8_t bits) {
1311 *res = lhs << rhs;
1312 if (zig_clz_i8(lhs, bits) >= rhs) return false;
1313 *res &= UINT8_MAX >> (8 - bits);
1314 return true;
1315}
1316
1317static inline bool zig_shlo_i16(int16_t lhs, int16_t rhs, int16_t *res, uint8_t bits) {
1318 *res = lhs << rhs;
1319 if (zig_clz_i16(lhs, bits) >= rhs) return false;
1320 *res &= UINT16_MAX >> (16 - bits);
1321 return true;
1322}
1323
1324static inline bool zig_shlo_i32(int32_t lhs, int32_t rhs, int32_t *res, uint8_t bits) {
1325 *res = lhs << rhs;
1326 if (zig_clz_i32(lhs, bits) >= rhs) return false;
1327 *res &= UINT32_MAX >> (32 - bits);
1328 return true;
1329}
1330
1331static inline bool zig_shlo_i64(int64_t lhs, int64_t rhs, int64_t *res, uint8_t bits) {
1332 *res = lhs << rhs;
1333 if (zig_clz_i64(lhs, bits) >= rhs) return false;
1334 *res &= UINT64_MAX >> (64 - bits);
1335 return true;
1336}
1337
1338static inline bool zig_shlo_i128(int128_t lhs, int128_t rhs, int128_t *res, uint8_t bits) {
1339 *res = lhs << rhs;
1340 if (zig_clz_i128(lhs, bits) >= rhs) return false;
1341 *res &= UINT128_MAX >> (128 - bits);
1342 return true;
1343}
1344
1345static inline bool zig_shlo_u8(uint8_t lhs, uint8_t rhs, uint8_t *res, uint8_t bits) {
1346 *res = lhs << rhs;
1347 if (zig_clz_u8(lhs, bits) >= rhs) return false;
1348 *res &= UINT8_MAX >> (8 - bits);
1349 return true;
1350}
1351
1352static inline uint16_t zig_shlo_u16(uint16_t lhs, uint16_t rhs, uint16_t *res, uint8_t bits) {
1353 *res = lhs << rhs;
1354 if (zig_clz_u16(lhs, bits) >= rhs) return false;
1355 *res &= UINT16_MAX >> (16 - bits);
1356 return true;
1357}
1358
1359static inline uint32_t zig_shlo_u32(uint32_t lhs, uint32_t rhs, uint32_t *res, uint8_t bits) {
1360 *res = lhs << rhs;
1361 if (zig_clz_u32(lhs, bits) >= rhs) return false;
1362 *res &= UINT32_MAX >> (32 - bits);
1363 return true;
1364}
1365
1366static inline uint64_t zig_shlo_u64(uint64_t lhs, uint64_t rhs, uint64_t *res, uint8_t bits) {
1367 *res = lhs << rhs;
1368 if (zig_clz_u64(lhs, bits) >= rhs) return false;
1369 *res &= UINT64_MAX >> (64 - bits);
1370 return true;
1371}
1372
1373static inline uint128_t zig_shlo_u128(uint128_t lhs, uint128_t rhs, uint128_t *res, uint8_t bits) {
1374 *res = lhs << rhs;
1375 if (zig_clz_u128(lhs, bits) >= rhs) return false;
1376 *res &= UINT128_MAX >> (128 - bits);
1377 return true;
1378}
1379
1380#define zig_sign_extend(T) \
1381 static inline T zig_sign_extend_##T(T value, uint8_t zig_type_bit_width) { \
1382 const T m = (T)1 << (T)(zig_type_bit_width - 1); \
1383 return (value ^ m) - m; \
1384 }
1385
1386zig_sign_extend(uint8_t)
1387zig_sign_extend(uint16_t)
1388zig_sign_extend(uint32_t)
1389zig_sign_extend(uint64_t)
1390zig_sign_extend(uint128_t)
1391
1392#define zig_byte_swap_u(ZigTypeBits, CTypeBits) \
1393 static inline uint##CTypeBits##_t zig_byte_swap_u##ZigTypeBits(uint##CTypeBits##_t value, uint8_t zig_type_bit_width) { \
1394 return __builtin_bswap##CTypeBits(value) >> (CTypeBits - zig_type_bit_width); \
1395 }
1396
1397#define zig_byte_swap_s(ZigTypeBits, CTypeBits) \
1398 static inline int##CTypeBits##_t zig_byte_swap_i##ZigTypeBits(int##CTypeBits##_t value, uint8_t zig_type_bit_width) { \
1399 const uint##CTypeBits##_t swapped = zig_byte_swap_u##ZigTypeBits(value, zig_type_bit_width); \
1400 return zig_sign_extend_uint##CTypeBits##_t(swapped, zig_type_bit_width); \
1401 }
1402
1403#define zig_byte_swap(ZigTypeBits, CTypeBits) \
1404 zig_byte_swap_u(ZigTypeBits, CTypeBits) \
1405 zig_byte_swap_s(ZigTypeBits, CTypeBits)
1406
1407zig_byte_swap( 8, 16)
1408zig_byte_swap(16, 16)
1409zig_byte_swap(32, 32)
1410zig_byte_swap(64, 64)
1411
1412static inline uint128_t zig_byte_swap_u128(uint128_t value, uint8_t zig_type_bit_width) {
1413 const uint128_t mask = zig_bit_mask(uint128_t, zig_type_bit_width);
1414 const uint128_t hi = __builtin_bswap64((uint64_t)(value >> 64));
1415 const uint128_t lo = __builtin_bswap64((uint64_t)value);
1416 return (((lo << 64 | hi) >> (128 - zig_type_bit_width))) & mask;
1417}
1418
1419zig_byte_swap_s(128, 128)
1420
1421static const uint8_t zig_bit_reverse_lut[256] = {
1422 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, 0xd0,
1423 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
1424 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, 0x84, 0x44, 0xc4,
1425 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
1426 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, 0x1c, 0x9c, 0x5c, 0xdc,
1427 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
1428 0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca,
1429 0x2a, 0xaa, 0x6a, 0xea, 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
1430 0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6,
1431 0x36, 0xb6, 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
1432 0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1,
1433 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
1434 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, 0x59, 0xd9,
1435 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
1436 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, 0x0d, 0x8d, 0x4d, 0xcd,
1437 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
1438 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3,
1439 0x33, 0xb3, 0x73, 0xf3, 0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
1440 0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7,
1441 0x27, 0xa7, 0x67, 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
1442 0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf,
1443 0x3f, 0xbf, 0x7f, 0xff
1444};
1445
1446static inline uint8_t zig_bit_reverse_u8(uint8_t value, uint8_t zig_type_bit_width) {
1447 const uint8_t reversed = zig_bit_reverse_lut[value] >> (8 - zig_type_bit_width);
1448 return zig_sign_extend_uint8_t(reversed, zig_type_bit_width);
1449}
1450
1451#define zig_bit_reverse_i8 zig_bit_reverse_u8
1452
1453static inline uint16_t zig_bit_reverse_u16(uint16_t value, uint8_t zig_type_bit_width) {
1454 const uint16_t swapped = zig_byte_swap_u16(value, zig_type_bit_width);
1455 const uint16_t reversed = (
1456 ((uint16_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) |
1457 ((uint16_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00));
1458 return zig_sign_extend_uint16_t(
1459 reversed & zig_bit_mask(uint16_t, zig_type_bit_width),
1460 zig_type_bit_width);
1461}
1462
1463#define zig_bit_reverse_i16 zig_bit_reverse_u16
1464
1465static inline uint32_t zig_bit_reverse_u32(uint32_t value, uint8_t zig_type_bit_width) {
1466 const uint32_t swapped = zig_byte_swap_u32(value, zig_type_bit_width);
1467 const uint32_t reversed = (
1468 ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x18) & 0xff] << 0x18) |
1469 ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x10) & 0xff] << 0x10) |
1470 ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) |
1471 ((uint32_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00));
1472 return zig_sign_extend_uint32_t(
1473 reversed & zig_bit_mask(uint32_t, zig_type_bit_width),
1474 zig_type_bit_width);
1475}
1476
1477#define zig_bit_reverse_i32 zig_bit_reverse_u32
1478
1479static inline uint64_t zig_bit_reverse_u64(uint64_t value, uint8_t zig_type_bit_width) {
1480 const uint64_t swapped = zig_byte_swap_u64(value, zig_type_bit_width);
1481 const uint64_t reversed = (
1482 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x38) & 0xff] << 0x38) |
1483 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x30) & 0xff] << 0x30) |
1484 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x28) & 0xff] << 0x28) |
1485 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x20) & 0xff] << 0x20) |
1486 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x18) & 0xff] << 0x18) |
1487 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x10) & 0xff] << 0x10) |
1488 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) |
1489 ((uint64_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00));
1490 return zig_sign_extend_uint64_t(
1491 reversed & zig_bit_mask(uint64_t, zig_type_bit_width),
1492 zig_type_bit_width);
1493}
1494
1495#define zig_bit_reverse_i64 zig_bit_reverse_u64
1496
1497static inline uint128_t zig_bit_reverse_u128(uint128_t value, uint8_t zig_type_bit_width) {
1498 const uint128_t swapped = zig_byte_swap_u128(value, zig_type_bit_width);
1499 const uint128_t reversed = (
1500 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x78) & 0xff] << 0x78) |
1501 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x70) & 0xff] << 0x70) |
1502 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x68) & 0xff] << 0x68) |
1503 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x60) & 0xff] << 0x60) |
1504 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x58) & 0xff] << 0x58) |
1505 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x50) & 0xff] << 0x50) |
1506 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x48) & 0xff] << 0x48) |
1507 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x40) & 0xff] << 0x40) |
1508 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x38) & 0xff] << 0x38) |
1509 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x30) & 0xff] << 0x30) |
1510 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x28) & 0xff] << 0x28) |
1511 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x20) & 0xff] << 0x20) |
1512 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x18) & 0xff] << 0x18) |
1513 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x10) & 0xff] << 0x10) |
1514 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x08) & 0xff] << 0x08) |
1515 ((uint128_t)zig_bit_reverse_lut[(swapped >> 0x00) & 0xff] << 0x00));
1516 return zig_sign_extend_uint128_t(
1517 reversed & zig_bit_mask(uint128_t, zig_type_bit_width),
1518 zig_type_bit_width);
1519}
1520
1521#define zig_bit_reverse_i128 zig_bit_reverse_u128
1522
1523static inline float zig_div_truncf(float numerator, float denominator) {
1524 return __builtin_truncf(numerator / denominator);
1525}
1526
1527static inline double zig_div_trunc(double numerator, double denominator) {
1528 return __builtin_trunc(numerator / denominator);
1529}
1530
1531static inline long double zig_div_truncl(long double numerator, long double denominator) {
1532 return __builtin_truncf(numerator / denominator);
1533}
1534
1535#define zig_div_trunc_f16 zig_div_truncf
1536#define zig_div_trunc_f32 zig_div_truncf
1537#define zig_div_trunc_f64 zig_div_trunc
1538#define zig_div_trunc_f80 zig_div_truncl
1539#define zig_div_trunc_f128 zig_div_truncl
1540
1541#define zig_div_floorf(numerator, denominator) \
1542 __builtin_floorf((float)(numerator) / (float)(denominator))
1543
1544#define zig_div_floor(numerator, denominator) \
1545 __builtin_floor((double)(numerator) / (double)(denominator))
1546
1547#define zig_div_floorl(numerator, denominator) \
1548 __builtin_floorl((long double)(numerator) / (long double)(denominator))
1549
1550#define zig_div_floor_f16 zig_div_floorf
1551#define zig_div_floor_f32 zig_div_floorf
1552#define zig_div_floor_f64 zig_div_floor
1553#define zig_div_floor_f80 zig_div_floorl
1554#define zig_div_floor_f128 zig_div_floorl
1555
1556#define zig_div_floor_u8 zig_div_floorf
1557#define zig_div_floor_i8 zig_div_floorf
1558#define zig_div_floor_u16 zig_div_floorf
1559#define zig_div_floor_i16 zig_div_floorf
1560#define zig_div_floor_u32 zig_div_floor
1561#define zig_div_floor_i32 zig_div_floor
1562#define zig_div_floor_u64 zig_div_floor
1563#define zig_div_floor_i64 zig_div_floor
1564#define zig_div_floor_u128 zig_div_floorl
1565#define zig_div_floor_i128 zig_div_floorl
1566
1567static inline float zig_modf(float numerator, float denominator) {
1568 return (numerator - (zig_div_floorf(numerator, denominator) * denominator));
1569}
1570
1571static inline double zig_mod(double numerator, double denominator) {
1572 return (numerator - (zig_div_floor(numerator, denominator) * denominator));
1573}
1574
1575static inline long double zig_modl(long double numerator, long double denominator) {
1576 return (numerator - (zig_div_floorl(numerator, denominator) * denominator));
1577}
1578
1579#define zig_mod_f16 zig_modf
1580#define zig_mod_f32 zig_modf
1581#define zig_mod_f64 zig_mod
1582#define zig_mod_f80 zig_modl
1583#define zig_mod_f128 zig_modl
1584
1585#define zig_mod_int(ZigType, CType) \
1586 static inline CType zig_mod_##ZigType(CType numerator, CType denominator) { \
1587 return (numerator - (zig_div_floor_##ZigType(numerator, denominator) * denominator)); \
1588 }
1589
1590zig_mod_int( u8, uint8_t)
1591zig_mod_int( i8, int8_t)
1592zig_mod_int( u16, uint16_t)
1593zig_mod_int( i16, int16_t)
1594zig_mod_int( u32, uint32_t)
1595zig_mod_int( i32, int32_t)
1596zig_mod_int( u64, uint64_t)
1597zig_mod_int( i64, int64_t)
1598zig_mod_int(u128, uint128_t)
1599zig_mod_int(i128, int128_t)