1#undef linux
2
3#include <stdarg.h>
4#include <stddef.h>
5
6#if defined(_MSC_VER)
7#define zig_msvc
8#elif defined(__clang__)
9#define zig_clang
10#define zig_gnuc
11#elif defined(__GNUC__)
12#define zig_gcc
13#define zig_gnuc
14#elif defined(__TINYC__)
15#define zig_tinyc
16#elif defined(__slimcc__)
17#define zig_slimcc
18#endif
19
20#if defined(__aarch64__) || (defined(zig_msvc) && defined(_M_ARM64))
21#define zig_aarch64
22#elif defined(__alpha__)
23#define zig_alpha
24#elif defined(__thumb__) || (defined(zig_msvc) && defined(_M_ARM))
25#define zig_thumb
26#define zig_arm
27#elif defined(__arm__)
28#define zig_arm
29#elif defined(__arc__)
30#define zig_arc
31#elif defined(__csky__)
32#define zig_csky
33#elif defined(__hexagon__)
34#define zig_hexagon
35#elif defined(__hppa__) && defined(_LP64)
36#define zig_hppa64
37#define zig_hppa
38#elif defined(__hppa__)
39#define zig_hppa32
40#define zig_hppa
41#elif defined(__kvx__)
42#define zig_kvx
43#elif defined(__loongarch32)
44#define zig_loongarch32
45#define zig_loongarch
46#elif defined(__loongarch64)
47#define zig_loongarch64
48#define zig_loongarch
49#elif defined(__m68k__)
50#define zig_m68k
51#elif defined(__m88k__)
52#define zig_m88k
53#elif defined(__microblaze__)
54#define zig_microblaze
55#elif defined(__mips64)
56#define zig_mips64
57#define zig_mips
58#elif defined(__mips__)
59#define zig_mips32
60#define zig_mips
61#elif defined(__or1k__)
62#define zig_or1k
63#elif defined(__powerpc64__)
64#define zig_powerpc64
65#define zig_powerpc
66#elif defined(__powerpc__)
67#define zig_powerpc32
68#define zig_powerpc
69#elif defined(__riscv) && __riscv_xlen == 32
70#define zig_riscv32
71#define zig_riscv
72#elif defined(__riscv) && __riscv_xlen == 64
73#define zig_riscv64
74#define zig_riscv
75#elif defined(__s390x__)
76#define zig_s390x
77#elif defined(__sh__)
78#define zig_sh
79#elif defined(__sparc__) && defined(__arch64__)
80#define zig_sparc64
81#define zig_sparc
82#elif defined(__sparc__)
83#define zig_sparc32
84#define zig_sparc
85#elif defined(__wasm32__)
86#define zig_wasm32
87#define zig_wasm
88#elif defined(__wasm64__)
89#define zig_wasm64
90#define zig_wasm
91#elif defined(__i386__) || (defined(zig_msvc) && defined(_M_IX86))
92#define zig_x86_32
93#define zig_x86
94#elif defined (__x86_64__) || (defined(zig_msvc) && defined(_M_X64))
95#define zig_x86_64
96#define zig_x86
97#elif defined(__I86__)
98#define zig_x86_16
99#define zig_x86
100#elif defined(__xtensa__)
101#define zig_xtensa
102#elif defined (__ez80)
103#define zig_ez80
104#define zig_z80
105#endif
106
107#if defined(zig_msvc) || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
108#define zig_little_endian 1
109#define zig_big_endian 0
110#else
111#define zig_little_endian 0
112#define zig_big_endian 1
113#endif
114
115#if defined(__APPLE__)
116#define zig_darwin
117#elif defined(__DragonFly__)
118#define zig_dragonfly
119#elif defined(__EMSCRIPTEN__)
120#define zig_emscripten
121#elif defined(__FreeBSD__)
122#define zig_freebsd
123#elif defined(__Fuchsia__)
124#define zig_fuchsia
125#elif defined(__HAIKU__)
126#define zig_haiku
127#elif defined(__gnu_hurd__)
128#define zig_hurd
129#elif defined(__illumos__)
130#define zig_illumos
131#elif defined(__linux__)
132#define zig_linux
133#elif defined(__NetBSD__)
134#define zig_netbsd
135#elif defined(__OpenBSD__)
136#define zig_openbsd
137#elif defined(__serenity__)
138#define zig_serenity
139#elif defined(__wasi__)
140#define zig_wasi
141#elif defined(_WIN32)
142#define zig_windows
143#endif
144
145#if defined(zig_windows)
146#define zig_coff
147#elif defined(__ELF__)
148#define zig_elf
149#elif defined(zig_darwin)
150#define zig_macho
151#endif
152
153#define zig_concat(lhs, rhs) lhs##rhs
154#define zig_expand_concat(lhs, rhs) zig_concat(lhs, rhs)
155
156#if defined(__has_include)
157#define zig_has_include(include) __has_include(include)
158#else
159#define zig_has_include(include) 0
160#endif
161
162#if defined(__has_builtin)
163#define zig_has_builtin(builtin) __has_builtin(__builtin_##builtin)
164#else
165#define zig_has_builtin(builtin) 0
166#endif
167#define zig_expand_has_builtin(b) zig_has_builtin(b)
168
169#if defined(__has_feature)
170#define zig_has_feature(feature) __has_feature(feature)
171#else
172#define zig_has_feature(feature) 0
173#endif
174
175#if defined(__has_attribute)
176#define zig_has_attribute(attribute) __has_attribute(attribute)
177#else
178#define zig_has_attribute(attribute) 0
179#endif
180
181#if __STDC_VERSION__ >= 201112L
182#define zig_static_assert(cond, msg) _Static_assert(cond, msg)
183#elif zig_has_attribute(unused)
184#define zig_static_assert(cond, msg) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[(cond) ? 1 : -1] __attribute__((unused))
185#else
186#define zig_static_assert(cond, msg) typedef char zig_expand_concat(zig_static_assert_fail_, __LINE__)[(cond) ? 1 : -1]
187#endif
188
189#if __STDC_VERSION__ >= 202311L
190#define zig_threadlocal thread_local
191#elif __STDC_VERSION__ >= 201112L
192#define zig_threadlocal _Thread_local
193#elif defined(zig_gnuc) || defined(zig_slimcc)
194#define zig_threadlocal __thread
195#elif defined(zig_msvc)
196#define zig_threadlocal __declspec(thread)
197#else
198#define zig_threadlocal zig_threadlocal_unavailable
199#endif
200
201#if defined(zig_msvc)
202#define zig_callconv(c) __##c
203#else
204#define zig_callconv(c) __attribute__((c))
205#endif
206
207#if zig_has_attribute(naked) || defined(zig_gcc)
208#define zig_naked_decl __attribute__((naked))
209#define zig_naked __attribute__((naked))
210#elif defined(zig_msvc)
211#define zig_naked_decl
212#define zig_naked __declspec(naked)
213#else
214#define zig_naked_decl zig_naked_unavailable
215#define zig_naked zig_naked_unavailable
216#endif
217
218#if zig_has_attribute(cold)
219#define zig_cold __attribute__((cold))
220#else
221#define zig_cold
222#endif
223
224#if zig_has_attribute(flatten)
225#define zig_maybe_flatten __attribute__((flatten))
226#else
227#define zig_maybe_flatten
228#endif
229
230#if zig_has_attribute(noinline)
231#define zig_never_inline __attribute__((noinline)) zig_maybe_flatten
232#elif defined(zig_msvc)
233#define zig_never_inline __declspec(noinline) zig_maybe_flatten
234#else
235#define zig_never_inline zig_never_inline_unavailable
236#endif
237
238#if zig_has_attribute(not_tail_called)
239#define zig_never_tail __attribute__((not_tail_called)) zig_never_inline
240#else
241#define zig_never_tail zig_never_tail_unavailable
242#endif
243
244#if zig_has_attribute(musttail)
245#define zig_always_tail __attribute__((musttail))
246#else
247#define zig_always_tail zig_always_tail_unavailable
248#endif
249
250#if __STDC_VERSION__ >= 199901L
251#define zig_restrict restrict
252#elif defined(zig_gnuc) || defined(zig_tinyc)
253#define zig_restrict __restrict
254#else
255#define zig_restrict
256#endif
257
258#if zig_has_attribute(no_builtin)
259#define zig_no_builtin __attribute__((no_builtin))
260#else
261#define zig_no_builtin
262#endif
263
264#if zig_has_attribute(aligned) || defined(zig_tinyc)
265#define zig_under_align(alignment) __attribute__((aligned(alignment)))
266#elif defined(zig_msvc)
267#define zig_under_align(alignment) __declspec(align(alignment))
268#else
269#define zig_under_align zig_align_unavailable
270#endif
271
272#if __STDC_VERSION__ >= 202311L
273#define zig_align(alignment) alignas(alignment)
274#elif __STDC_VERSION__ >= 201112L || zig_has_feature(c_alignas)
275#define zig_align(alignment) _Alignas(alignment)
276#else
277#define zig_align(alignment) zig_under_align(alignment)
278#endif
279
280#if __STDC_VERSION__ >= 202311L
281#define zig_alignOf(Type) alignof(Type)
282#elif __STDC_VERSION__ >= 201112L || zig_has_feature(c_alignof)
283#define zig_alignOf(Type) _Alignof(Type)
284#else
285#define zig_alignOf(Type) (sizeof(struct { char c; Type t; }) - sizeof(Type))
286#endif
287
288#if zig_has_attribute(aligned) || defined(zig_tinyc)
289#define zig_align_fn(alignment) __attribute__((aligned(alignment)))
290#elif defined(zig_msvc)
291#define zig_align_fn(alignment)
292#else
293#define zig_align_fn zig_align_fn_unavailable
294#endif
295
296#if zig_has_attribute(nonstring)
297#define zig_nonstring __attribute__((nonstring))
298#else
299#define zig_nonstring
300#endif
301
302#if zig_has_attribute(packed) || defined(zig_tinyc)
303#define zig_packed(definition) definition __attribute__((packed))
304#elif defined(zig_msvc)
305#define zig_packed(definition) __pragma(pack(1)) definition __pragma(pack())
306#else
307#define zig_packed(definition) zig_packed_unavailable
308#endif
309
310#if zig_has_attribute(section) || defined(zig_tinyc)
311#define zig_linksection(name) __attribute__((section(name)))
312#define zig_linksection_fn zig_linksection
313#elif defined(zig_msvc)
314#define zig_linksection(name) __pragma(section(name, read, write)) __declspec(allocate(name))
315#define zig_linksection_fn(name) __pragma(section(name, read, execute)) __declspec(code_seg(name))
316#else
317#define zig_linksection(name) zig_linksection_unavailable
318#define zig_linksection_fn zig_linksection
319#endif
320
321#if zig_has_attribute(visibility)
322#define zig_visibility(name) __attribute__((visibility(#name)))
323#else
324#define zig_visibility(name) zig_visibility_##name
325#define zig_visibility_default
326#define zig_visibility_hidden zig_visibility_hidden_unavailable
327#define zig_visibility_protected zig_visibility_protected_unavailable
328#endif
329
330#if zig_has_builtin(unreachable) || defined(zig_gcc) || defined(zig_tinyc)
331#define zig_unreachable() __builtin_unreachable()
332#elif defined(zig_msvc)
333#define zig_unreachable() __assume(0)
334#else
335#define zig_unreachable()
336#endif
337
338#if defined(__cplusplus)
339#define zig_extern extern "C"
340#else
341#define zig_extern extern
342#endif
343
344#if defined(zig_msvc)
345#if defined(zig_x86_64)
346#define zig_mangle_c(symbol) symbol
347#else /* zig_x86_64 */
348#define zig_mangle_c(symbol) "_" symbol
349#endif /* zig_x86_64 */
350#else /* zig_msvc */
351#if defined(zig_macho)
352#define zig_mangle_c(symbol) "_" symbol
353#else /* zig_macho */
354#define zig_mangle_c(symbol) symbol
355#endif /* zig_macho */
356#endif /* zig_msvc */
357
358#if defined(zig_msvc)
359#define zig_export(symbol, name) ; \
360 __pragma(comment(linker, "/alternatename:" zig_mangle_c(name) "=" zig_mangle_c(symbol)))
361#elif (zig_has_attribute(alias) || defined(zig_tinyc)) && !defined(zig_macho)
362#define zig_export(symbol, name) __attribute__((alias(symbol)))
363#else
364#define zig_export(symbol, name) ; \
365 __asm("\t.globl\t" zig_mangle_c(name) "\n" zig_mangle_c(name) " = " zig_mangle_c(symbol))
366#endif
367
368#if defined(zig_msvc)
369#define zig_mangled(mangled, unmangled) ; \
370 zig_export(#mangled, unmangled)
371#define zig_mangled_export(mangled, unmangled, symbol) \
372 zig_export(unmangled, #mangled) \
373 zig_export(symbol, unmangled)
374#else /* zig_msvc */
375#define zig_mangled(mangled, unmangled) __asm(zig_mangle_c(unmangled))
376#define zig_mangled_export(mangled, unmangled, symbol) \
377 zig_mangled(mangled, unmangled) \
378 zig_export(symbol, unmangled)
379#endif /* zig_msvc */
380
381#if defined(zig_msvc)
382#define zig_import(Type, fn_name, libc_name, sig_args, call_args) zig_extern Type fn_name sig_args;\
383 __pragma(comment(linker, "/alternatename:" zig_mangle_c(#fn_name) "=" zig_mangle_c(#libc_name)));
384#define zig_import_builtin(Type, fn_name, libc_name, sig_args, call_args) zig_import(Type, fn_name, libc_name, sig_args, call_args)
385#else /* zig_msvc */
386#define zig_import(Type, fn_name, libc_name, sig_args, call_args) zig_extern Type fn_name sig_args __asm(zig_mangle_c(#libc_name));
387#define zig_import_builtin(Type, fn_name, libc_name, sig_args, call_args) zig_extern Type libc_name sig_args; \
388 static inline Type fn_name sig_args { return libc_name call_args; }
389#endif
390
391#define zig_expand_import_0(Type, fn_name, libc_name, sig_args, call_args) zig_import(Type, fn_name, libc_name, sig_args, call_args)
392#define zig_expand_import_1(Type, fn_name, libc_name, sig_args, call_args) zig_import_builtin(Type, fn_name, libc_name, sig_args, call_args)
393
394#if zig_has_attribute(weak) || defined(zig_gcc) || defined(zig_tinyc)
395#define zig_weak_linkage __attribute__((weak))
396#define zig_weak_linkage_fn __attribute__((weak))
397#elif defined(zig_msvc)
398#define zig_weak_linkage __declspec(selectany)
399#define zig_weak_linkage_fn
400#else
401#define zig_weak_linkage zig_weak_linkage_unavailable
402#define zig_weak_linkage_fn zig_weak_linkage_unavailable
403#endif
404
405#if defined(zig_gnuc) || defined(zig_tinyc) || defined(zig_slimcc)
406#define zig_gnuc_asm
407#endif
408
409#if zig_has_builtin(trap)
410#define zig_trap() __builtin_trap()
411#elif defined(zig_msvc)
412
413#if defined(zig_x86)
414#define zig_trap() __ud2()
415#else
416#define zig_trap() __fastfail(7)
417#endif
418
419#elif defined(zig_gnuc_asm)
420
421#if defined(zig_alpha)
422#define zig_trap() __asm__ volatile("call_pal 0x000000")
423#elif defined(zig_thumb)
424#define zig_trap() __asm__ volatile("udf #0xfe")
425#elif defined(zig_arm) || defined(zig_aarch64)
426#define zig_trap() __asm__ volatile("udf #0xfdee")
427#elif defined(zig_arc)
428#define zig_trap() __asm__ volatile("unimp_s")
429#elif defined(zig_csky)
430#define zig_trap() __asm__ volatile(".word 0x3fff")
431#elif defined(zig_hexagon)
432#define zig_trap() __asm__ volatile("r27:26 = memd(#0xbadc0fee)")
433#elif defined(zig_hppa)
434#define zig_trap() __asm__ volatile("iitlbp %r0, (%sr0, %r0)")
435#elif defined(zig_kvx) || defined(zig_loongarch) || defined(zig_powerpc)
436#define zig_trap() __asm__ volatile(".word 0x0")
437#elif defined(zig_m68k)
438#define zig_trap() __asm__ volatile("illegal")
439#elif defined(zig_m88k)
440#define zig_trap() __asm__ volatile("tb0 0, %%r0, 511")
441#elif defined(zig_microblaze)
442#define zig_trap() __asm__ volatile("getd r0, r0")
443#elif defined(zig_mips)
444#define zig_trap() __asm__ volatile(".word 0x3d")
445#elif defined(zig_or1k)
446#define zig_trap() __asm__ volatile("l.cust8")
447#elif defined(zig_riscv)
448#define zig_trap() __asm__ volatile("unimp")
449#elif defined(zig_s390x)
450#define zig_trap() __asm__ volatile("j 0x2")
451#elif defined(zig_sh)
452#define zig_trap() __asm__ volatile(".word 0x0001")
453#elif defined(zig_sparc)
454#define zig_trap() __asm__ volatile("illtrap")
455#elif defined(zig_x86_16)
456#define zig_trap() __asm__ volatile("int $0x3")
457#elif defined(zig_x86)
458#define zig_trap() __asm__ volatile("ud2")
459#elif defined(zig_xtensa)
460#define zig_trap() __asm__ volatile("ill")
461#elif defined(zig_z80)
462#define zig_trap() __asm__ volatile("rst 00h")
463#else
464#define zig_trap() zig_trap_unavailable
465#endif
466
467#else
468#define zig_trap() zig_trap_unavailable
469#endif
470
471#if zig_has_builtin(debugtrap)
472#define zig_breakpoint() __builtin_debugtrap()
473#elif defined(zig_msvc)
474#define zig_breakpoint() __debugbreak()
475#elif defined(zig_gnuc_asm)
476
477#if defined(zig_alpha)
478#define zig_breakpoint() __asm__ volatile("call_pal 0x000080")
479#elif defined(zig_arm) || defined(zig_csky)
480#define zig_breakpoint() __asm__ volatile("bkpt #0x0")
481#elif defined(zig_aarch64)
482#define zig_breakpoint() __asm__ volatile("brk #0xf000")
483#elif defined(zig_arc)
484#define zig_breakpoint() __asm__ volatile("brk_s")
485#elif defined(zig_hexagon)
486#define zig_breakpoint() __asm__ volatile("brkpt")
487#elif defined(zig_hppa)
488#define zig_breakpoint() __asm__ volatile("break 0x04, 0x0008")
489#elif defined(zig_kvx) || defined(zig_loongarch)
490#define zig_breakpoint() __asm__ volatile("break 0x0")
491#elif defined(zig_m88k)
492#define zig_breakpoint() __asm__ volatile("illop1")
493#elif defined(zig_microblaze)
494#define zig_breakpoint() __asm__ volatile("brki r16, 0x0018")
495#elif defined(zig_mips)
496#define zig_breakpoint() __asm__ volatile("break")
497#elif defined(zig_or1k)
498#define zig_breakpoint() __asm__ volatile("l.trap 0x0")
499#elif defined(zig_powerpc)
500#define zig_breakpoint() __asm__ volatile("trap")
501#elif defined(zig_riscv)
502#define zig_breakpoint() __asm__ volatile("ebreak")
503#elif defined(zig_s390x)
504#define zig_breakpoint() __asm__ volatile("j 0x6")
505#elif defined(zig_sh)
506#define zig_breakpoint() __asm__ volatile("trapa #0xc3")
507#elif defined(zig_sparc)
508#define zig_breakpoint() __asm__ volatile("ta 0x1")
509#elif defined(zig_x86)
510#define zig_breakpoint() __asm__ volatile("int $0x3")
511#elif defined(zig_xtensa)
512#define zig_breakpoint() __asm__ volatile("break 1, 1")
513#else
514#define zig_breakpoint() zig_breakpoint_unavailable
515#endif
516
517#else
518#define zig_breakpoint() zig_breakpoint_unavailable
519#endif
520
521#if zig_has_builtin(return_address) || defined(zig_gcc) || defined(zig_tinyc)
522#define zig_return_address() __builtin_extract_return_addr(__builtin_return_address(0))
523#elif defined(zig_msvc)
524#define zig_return_address() _ReturnAddress()
525#else
526#define zig_return_address() 0
527#endif
528
529#if zig_has_builtin(frame_address) || defined(zig_gcc) || defined(zig_tinyc)
530#define zig_frame_address() __builtin_frame_address(0)
531#elif defined(zig_msvc)
532#define zig_frame_address() _AddressOfReturnAddress()
533#else
534#define zig_frame_address() 0
535#endif
536
537#if zig_has_builtin(prefetch) || defined(zig_gcc)
538#define zig_prefetch(addr, rw, locality) __builtin_prefetch(addr, rw, locality)
539#else
540#define zig_prefetch(addr, rw, locality)
541#endif
542
543#if zig_has_builtin(memory_size) && zig_has_builtin(memory_grow)
544#define zig_wasm_memory_size(index) __builtin_wasm_memory_size(index)
545#define zig_wasm_memory_grow(index, delta) __builtin_wasm_memory_grow(index, delta)
546#else
547#define zig_wasm_memory_size(index) zig_unimplemented()
548#define zig_wasm_memory_grow(index, delta) zig_unimplemented()
549#endif
550
551#if __STDC_VERSION__ >= 202311L
552#define zig_noreturn [[noreturn]]
553#elif __STDC_VERSION__ >= 201112L
554#define zig_noreturn _Noreturn
555#elif zig_has_attribute(noreturn) || defined(zig_gcc) || defined(zig_tinyc)
556#define zig_noreturn __attribute__((noreturn))
557#elif defined(zig_msvc)
558#define zig_noreturn __declspec(noreturn)
559#else
560#define zig_noreturn
561#endif
562
563#define zig_has_always 1
564#define zig_has_never 0
565
566#define zig_compiler_rt_abbrev_uint32_t si
567#define zig_compiler_rt_abbrev_int32_t si
568#define zig_compiler_rt_abbrev_uint64_t di
569#define zig_compiler_rt_abbrev_int64_t di
570#define zig_compiler_rt_abbrev_zig_u128 ti
571#define zig_compiler_rt_abbrev_zig_i128 ti
572#define zig_compiler_rt_abbrev_zig_f16 hf
573#define zig_compiler_rt_abbrev_zig_f32 sf
574#define zig_compiler_rt_abbrev_zig_f64 df
575#define zig_compiler_rt_abbrev_zig_f80 xf
576#ifdef zig_powerpc
577#define zig_compiler_rt_abbrev_zig_f128 kf
578#else
579#define zig_compiler_rt_abbrev_zig_f128 tf
580#endif
581
582zig_extern void *memcpy (void *zig_restrict, void const *zig_restrict, size_t);
583zig_extern void *memset (void *, int, size_t);
584zig_extern void *memmove (void *, void const *, size_t);
585
586/* ================ Bool and 8/16/24/32/48/64-bit Integer Support ================= */
587
588#include <limits.h>
589
590#define zig_bitSizeOf(T) (CHAR_BIT * sizeof(T))
591
592#if __STDC_VERSION__ >= 202311L
593/* bool, true, and false are provided by the language. */
594#elif __STDC_VERSION__ >= 199901L || zig_has_include(<stdbool.h>)
595#include <stdbool.h>
596#else
597typedef char bool;
598#define false 0
599#define true 1
600#endif
601
602#if __STDC_VERSION__ >= 199901L || defined(zig_msvc) || zig_has_include(<stdint.h>)
603#include <stdint.h>
604#else
605#if SCHAR_MIN == ~0x7F && SCHAR_MAX == 0x7F && UCHAR_MAX == 0xFF
606typedef unsigned char uint8_t;
607typedef signed char int8_t;
608#define INT8_C(c) c
609#define UINT8_C(c) c##U
610#elif SHRT_MIN == ~0x7F && SHRT_MAX == 0x7F && USHRT_MAX == 0xFF
611typedef unsigned short uint8_t;
612typedef signed short int8_t;
613#define INT8_C(c) c
614#define UINT8_C(c) c##U
615#elif INT_MIN == ~0x7F && INT_MAX == 0x7F && UINT_MAX == 0xFF
616typedef unsigned int uint8_t;
617typedef signed int int8_t;
618#define INT8_C(c) c
619#define UINT8_C(c) c##U
620#elif LONG_MIN == ~0x7F && LONG_MAX == 0x7F && ULONG_MAX == 0xFF
621typedef unsigned long uint8_t;
622typedef signed long int8_t;
623#define INT8_C(c) c##L
624#define UINT8_C(c) c##LU
625#elif LLONG_MIN == ~0x7F && LLONG_MAX == 0x7F && ULLONG_MAX == 0xFF
626typedef unsigned long long uint8_t;
627typedef signed long long int8_t;
628#define INT8_C(c) c##LL
629#define UINT8_C(c) c##LLU
630#endif
631#define INT8_MIN (~INT8_C(0x7F))
632#define INT8_MAX ( INT8_C(0x7F))
633#define UINT8_MAX ( INT8_C(0xFF))
634
635#if SCHAR_MIN == ~0x7FFF && SCHAR_MAX == 0x7FFF && UCHAR_MAX == 0xFFFF
636typedef unsigned char uint16_t;
637typedef signed char int16_t;
638#define INT16_C(c) c
639#define UINT16_C(c) c##U
640#elif SHRT_MIN == ~0x7FFF && SHRT_MAX == 0x7FFF && USHRT_MAX == 0xFFFF
641typedef unsigned short uint16_t;
642typedef signed short int16_t;
643#define INT16_C(c) c
644#define UINT16_C(c) c##U
645#elif INT_MIN == ~0x7FFF && INT_MAX == 0x7FFF && UINT_MAX == 0xFFFF
646typedef unsigned int uint16_t;
647typedef signed int int16_t;
648#define INT16_C(c) c
649#define UINT16_C(c) c##U
650#elif LONG_MIN == ~0x7FFF && LONG_MAX == 0x7FFF && ULONG_MAX == 0xFFFF
651typedef unsigned long uint16_t;
652typedef signed long int16_t;
653#define INT16_C(c) c##L
654#define UINT16_C(c) c##LU
655#elif LLONG_MIN == ~0x7FFF && LLONG_MAX == 0x7FFF && ULLONG_MAX == 0xFFFF
656typedef unsigned long long uint16_t;
657typedef signed long long int16_t;
658#define INT16_C(c) c##LL
659#define UINT16_C(c) c##LLU
660#endif
661#define INT16_MIN (~INT16_C(0x7FFF))
662#define INT16_MAX ( INT16_C(0x7FFF))
663#define UINT16_MAX ( INT16_C(0xFFFF))
664
665#if SCHAR_MIN == ~0x7FFFFFFF && SCHAR_MAX == 0x7FFFFFFF && UCHAR_MAX == 0xFFFFFFFF
666typedef unsigned char uint32_t;
667typedef signed char int32_t;
668#define INT32_C(c) c
669#define UINT32_C(c) c##U
670#elif SHRT_MIN == ~0x7FFFFFFF && SHRT_MAX == 0x7FFFFFFF && USHRT_MAX == 0xFFFFFFFF
671typedef unsigned short uint32_t;
672typedef signed short int32_t;
673#define INT32_C(c) c
674#define UINT32_C(c) c##U
675#elif INT_MIN == ~0x7FFFFFFF && INT_MAX == 0x7FFFFFFF && UINT_MAX == 0xFFFFFFFF
676typedef unsigned int uint32_t;
677typedef signed int int32_t;
678#define INT32_C(c) c
679#define UINT32_C(c) c##U
680#elif LONG_MIN == ~0x7FFFFFFF && LONG_MAX == 0x7FFFFFFF && ULONG_MAX == 0xFFFFFFFF
681typedef unsigned long uint32_t;
682typedef signed long int32_t;
683#define INT32_C(c) c##L
684#define UINT32_C(c) c##LU
685#elif LLONG_MIN == ~0x7FFFFFFF && LLONG_MAX == 0x7FFFFFFF && ULLONG_MAX == 0xFFFFFFFF
686typedef unsigned long long uint32_t;
687typedef signed long long int32_t;
688#define INT32_C(c) c##LL
689#define UINT32_C(c) c##LLU
690#endif
691#define INT32_MIN (~INT32_C(0x7FFFFFFF))
692#define INT32_MAX ( INT32_C(0x7FFFFFFF))
693#define UINT32_MAX ( INT32_C(0xFFFFFFFF))
694
695#if SCHAR_MIN == ~0x7FFFFFFFFFFFFFFF && SCHAR_MAX == 0x7FFFFFFFFFFFFFFF && UCHAR_MAX == 0xFFFFFFFFFFFFFFFF
696typedef unsigned char uint64_t;
697typedef signed char int64_t;
698#define INT64_C(c) c
699#define UINT64_C(c) c##U
700#elif SHRT_MIN == ~0x7FFFFFFFFFFFFFFF && SHRT_MAX == 0x7FFFFFFFFFFFFFFF && USHRT_MAX == 0xFFFFFFFFFFFFFFFF
701typedef unsigned short uint64_t;
702typedef signed short int64_t;
703#define INT64_C(c) c
704#define UINT64_C(c) c##U
705#elif INT_MIN == ~0x7FFFFFFFFFFFFFFF && INT_MAX == 0x7FFFFFFFFFFFFFFF && UINT_MAX == 0xFFFFFFFFFFFFFFFF
706typedef unsigned int uint64_t;
707typedef signed int int64_t;
708#define INT64_C(c) c
709#define UINT64_C(c) c##U
710#elif LONG_MIN == ~0x7FFFFFFFFFFFFFFF && LONG_MAX == 0x7FFFFFFFFFFFFFFF && ULONG_MAX == 0xFFFFFFFFFFFFFFFF
711typedef unsigned long uint64_t;
712typedef signed long int64_t;
713#define INT64_C(c) c##L
714#define UINT64_C(c) c##LU
715#elif LLONG_MIN == ~0x7FFFFFFFFFFFFFFF && LLONG_MAX == 0x7FFFFFFFFFFFFFFF && ULLONG_MAX == 0xFFFFFFFFFFFFFFFF
716typedef unsigned long long uint64_t;
717typedef signed long long int64_t;
718#define INT64_C(c) c##LL
719#define UINT64_C(c) c##LLU
720#endif
721#define INT64_MIN (~INT64_C(0x7FFFFFFFFFFFFFFF))
722#define INT64_MAX ( INT64_C(0x7FFFFFFFFFFFFFFF))
723#define UINT64_MAX ( INT64_C(0xFFFFFFFFFFFFFFFF))
724
725#if defined(zig_ez80)
726
727typedef unsigned int uint24_t;
728typedef signed int int24_t;
729#define INT24_C(c) c
730#define UINT24_C(c) c##U
731#define INT24_MIN (~INT24_C(0x7FFF))
732#define INT24_MAX ( INT24_C(0x7FFF))
733#define UINT24_MAX ( INT24_C(0xFFFF))
734
735typedef unsigned __int48 uint48_t;
736typedef signed __int48 int48_t;
737#define INT48_C(c) c
738/* no suffix */
739#define UINT48_C(c) ((uint48_t)(c))
740#define INT48_MIN (~INT48_C(0x7FFFFFFFFFFF))
741#define INT48_MAX ( INT48_C(0x7FFFFFFFFFFF))
742#define UINT48_MAX ( INT48_C(0xFFFFFFFFFFFF))
743
744#endif
745
746typedef size_t uintptr_t;
747typedef ptrdiff_t intptr_t;
748
749#endif
750
751#define zig_minInt_i8 INT8_MIN
752#define zig_maxInt_i8 INT8_MAX
753#define zig_minInt_u8 UINT8_C(0)
754#define zig_maxInt_u8 UINT8_MAX
755#define zig_minInt_i16 INT16_MIN
756#define zig_maxInt_i16 INT16_MAX
757#define zig_minInt_u16 UINT16_C(0)
758#define zig_maxInt_u16 UINT16_MAX
759#define zig_minInt_i32 INT32_MIN
760#define zig_maxInt_i32 INT32_MAX
761#define zig_minInt_u32 UINT32_C(0)
762#define zig_maxInt_u32 UINT32_MAX
763#define zig_minInt_i64 INT64_MIN
764#define zig_maxInt_i64 INT64_MAX
765#define zig_minInt_u64 UINT64_C(0)
766#define zig_maxInt_u64 UINT64_MAX
767
768// zig_promoted_T implements C integral promotions except with signedness preserved, which
769// allows wrapping operations to avoid the ub that would be caused by the normal promotion.
770
771#if INT8_MAX <= INT_MAX
772typedef unsigned int zig_promoted_i8;
773#elif INT8_MAX <= LONG_MAX
774typedef unsigned long zig_promoted_i8;
775#elif INT8_MAX <= LLONG_MAX
776typedef unsigned long long zig_promoted_i8;
777#else
778typedef int8_t zig_promoted_i8;
779#endif
780#if UINT8_MAX <= UINT_MAX
781typedef unsigned int zig_promoted_u8;
782#elif UINT8_MAX <= ULONG_MAX
783typedef unsigned long zig_promoted_u8;
784#elif UINT8_MAX <= ULLONG_MAX
785typedef unsigned long long zig_promoted_u8;
786#else
787typedef uint8_t zig_promoted_u8;
788#endif
789
790#if INT16_MAX <= INT_MAX
791typedef unsigned int zig_promoted_i16;
792#elif INT16_MAX <= LONG_MAX
793typedef unsigned long zig_promoted_i16;
794#elif INT16_MAX <= LLONG_MAX
795typedef unsigned long long zig_promoted_i16;
796#else
797typedef int16_t zig_promoted_i16;
798#endif
799#if UINT16_MAX <= UINT_MAX
800typedef unsigned int zig_promoted_u16;
801#elif UINT16_MAX <= ULONG_MAX
802typedef unsigned long zig_promoted_u16;
803#elif UINT16_MAX <= ULLONG_MAX
804typedef unsigned long long zig_promoted_u16;
805#else
806typedef uint16_t zig_promoted_u16;
807#endif
808
809#if INT32_MAX <= INT_MAX
810typedef unsigned int zig_promoted_i32;
811#elif INT32_MAX <= LONG_MAX
812typedef unsigned long zig_promoted_i32;
813#elif INT32_MAX <= LLONG_MAX
814typedef unsigned long long zig_promoted_i32;
815#else
816typedef int32_t zig_promoted_i32;
817#endif
818#if UINT32_MAX <= UINT_MAX
819typedef unsigned int zig_promoted_u32;
820#elif UINT32_MAX <= ULONG_MAX
821typedef unsigned long zig_promoted_u32;
822#elif UINT32_MAX <= ULLONG_MAX
823typedef unsigned long long zig_promoted_u32;
824#else
825typedef uint32_t zig_promoted_u32;
826#endif
827
828#if INT64_MAX <= INT_MAX
829typedef unsigned int zig_promoted_i64;
830#elif INT64_MAX <= LONG_MAX
831typedef unsigned long zig_promoted_i64;
832#elif INT64_MAX <= LLONG_MAX
833typedef unsigned long long zig_promoted_i64;
834#else
835typedef int64_t zig_promoted_i64;
836#endif
837#if UINT64_MAX <= UINT_MAX
838typedef unsigned int zig_promoted_u64;
839#elif UINT64_MAX <= ULONG_MAX
840typedef unsigned long zig_promoted_u64;
841#elif UINT64_MAX <= ULLONG_MAX
842typedef unsigned long long zig_promoted_u64;
843#else
844typedef uint64_t zig_promoted_u64;
845#endif
846
847#ifdef zig_ez80
848
849#define zig_minInt_i24 INT24_MIN
850#define zig_maxInt_i24 INT24_MAX
851#define zig_minInt_u24 UINT24_C(0)
852#define zig_maxInt_u24 UINT24_MAX
853#define zig_minInt_i48 INT48_MIN
854#define zig_maxInt_i48 INT48_MAX
855#define zig_minInt_u48 UINT48_C(0)
856#define zig_maxInt_u48 UINT48_MAX
857
858#if INT24_MAX <= INT_MAX
859typedef unsigned int zig_promoted_i24;
860#elif INT24_MAX <= LONG_MAX
861typedef unsigned long zig_promoted_i24;
862#elif INT24_MAX <= LLONG_MAX
863typedef unsigned long long zig_promoted_i24;
864#else
865typedef int24_t zig_promoted_i24;
866#endif
867#if UINT24_MAX <= UINT_MAX
868typedef unsigned int zig_promoted_u24;
869#elif UINT24_MAX <= ULONG_MAX
870typedef unsigned long zig_promoted_u24;
871#elif UINT24_MAX <= ULLONG_MAX
872typedef unsigned long long zig_promoted_u24;
873#else
874typedef uint24_t zig_promoted_u24;
875#endif
876
877#if INT48_MAX <= INT_MAX
878typedef unsigned int zig_promoted_i48;
879#elif INT48_MAX <= LONG_MAX
880typedef unsigned long zig_promoted_i48;
881#elif INT48_MAX <= LLONG_MAX
882typedef unsigned long long zig_promoted_i48;
883#else
884typedef int48_t zig_promoted_i48;
885#endif
886#if UINT48_MAX <= UINT_MAX
887typedef unsigned int zig_promoted_u48;
888#elif UINT48_MAX <= ULONG_MAX
889typedef unsigned long zig_promoted_u48;
890#elif UINT48_MAX <= ULLONG_MAX
891typedef unsigned long long zig_promoted_u48;
892#else
893typedef uint48_t zig_promoted_u48;
894#endif
895
896#endif
897
898#define zig_intLimit(s, w, limit, bits) zig_shr_##s##w(zig_##limit##Int_##s##w, w - (bits))
899#define zig_minInt_i(w, bits) zig_intLimit(i, w, min, bits)
900#define zig_maxInt_i(w, bits) zig_intLimit(i, w, max, bits)
901#define zig_minInt_u(w, bits) zig_intLimit(u, w, min, bits)
902#define zig_maxInt_u(w, bits) zig_intLimit(u, w, max, bits)
903
904#define zig_operator(Type, RhsType, operation, operator) \
905 static inline Type zig_##operation(Type lhs, RhsType rhs) { \
906 return lhs operator rhs; \
907 }
908#define zig_basic_operator(Type, operation, operator) \
909 zig_operator(Type, Type, operation, operator)
910#define zig_shift_operator(Type, operation, operator) \
911 zig_operator(Type, uint8_t, operation, operator)
912
913#define zig_int_casts_common(bw, sw) \
914 static inline uint##bw##_t zig_u##bw##_intCast_u##sw(uint##sw##_t arg) { \
915 return arg; \
916 } \
917\
918 static inline uint##bw##_t zig_u##bw##_intCast_i##sw(int##sw##_t arg) { \
919 return (uint##bw##_t)arg; \
920 } \
921\
922 static inline int##bw##_t zig_i##bw##_intCast_u##sw(uint##sw##_t arg) { \
923 return arg; \
924 } \
925\
926 static inline int##bw##_t zig_i##bw##_intCast_i##sw(int##sw##_t arg) { \
927 return arg; \
928 } \
929\
930 static inline uint##sw##_t zig_u##sw##_truncate_u##bw(uint##bw##_t arg, uint8_t bits) { \
931 return (uint##sw##_t)arg & zig_maxInt_u(sw, bits); \
932 } \
933\
934 static inline int##sw##_t zig_i##sw##_truncate_i##bw(int##bw##_t arg, uint8_t bits) { \
935 return ((uint##sw##_t)arg & UINT##sw##_C(1) << (bits - UINT8_C(1))) != UINT##sw##_C(0) \
936 ? (int##sw##_t)arg | zig_minInt_i(sw, bits) : (int##sw##_t)arg & zig_maxInt_i(sw, bits); \
937 }
938#define zig_int_operators(w) \
939 zig_basic_operator(uint##w##_t, and_u##w, &) \
940 zig_basic_operator( int##w##_t, and_i##w, &) \
941 zig_basic_operator(uint##w##_t, or_u##w, |) \
942 zig_basic_operator( int##w##_t, or_i##w, |) \
943 zig_basic_operator(uint##w##_t, xor_u##w, ^) \
944 zig_basic_operator( int##w##_t, xor_i##w, ^) \
945 zig_shift_operator(uint##w##_t, shl_u##w, <<) \
946 zig_shift_operator( int##w##_t, shl_i##w, <<) \
947 zig_shift_operator(uint##w##_t, shr_u##w, >>) \
948\
949 static inline int##w##_t zig_shr_i##w(int##w##_t lhs, uint8_t rhs) { \
950 int##w##_t sign_mask = lhs < INT##w##_C(0) ? -INT##w##_C(1) : INT##w##_C(0); \
951 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask; \
952 } \
953\
954 static inline uint##w##_t zig_not_u##w(uint##w##_t arg, uint8_t bits) { \
955 return arg ^ zig_maxInt_u(w, bits); \
956 } \
957\
958 static inline int##w##_t zig_not_i##w(int##w##_t arg, uint8_t bits) { \
959 (void)bits; \
960 return ~arg; \
961 } \
962\
963 zig_basic_operator(uint##w##_t, divFloor_u##w, /) \
964\
965 static inline int##w##_t zig_divFloor_i##w(int##w##_t lhs, int##w##_t rhs) { \
966 return lhs / rhs + (lhs % rhs != INT##w##_C(0) ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) : INT##w##_C(0)); \
967 } \
968\
969 static inline uint##w##_t zig_divCeil_u##w(uint##w##_t lhs, uint##w##_t rhs) { \
970 return lhs / rhs + (lhs % rhs != UINT##w##_C(0) ? UINT##w##_C(1) : UINT##w##_C(0)); \
971 } \
972\
973 static inline int##w##_t zig_divCeil_i##w(int##w##_t lhs, int##w##_t rhs) { \
974 return lhs / rhs + (lhs % rhs != INT##w##_C(0) \
975 ? zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) + INT##w##_C(1) : INT##w##_C(0)); \
976 } \
977\
978 zig_basic_operator(uint##w##_t, mod_u##w, %) \
979 zig_int_casts_common(w, w) \
980\
981 static inline uint##w##_t zig_u##w##_bitCast_u##w(uint##w##_t arg, uint8_t bits) { \
982 return zig_u##w##_truncate_u##w(arg, bits); \
983 } \
984\
985 static inline uint##w##_t zig_u##w##_bitCast_i##w(int##w##_t arg, uint8_t bits) { \
986 return zig_u##w##_bitCast_u##w((uint##w##_t)arg, bits); \
987 } \
988\
989 static inline int##w##_t zig_i##w##_bitCast_i##w(int##w##_t arg, uint8_t bits) { \
990 return zig_i##w##_truncate_i##w(arg, bits); \
991 } \
992\
993 static inline int##w##_t zig_i##w##_bitCast_u##w(uint##w##_t arg, uint8_t bits) { \
994 return zig_i##w##_bitCast_i##w((int##w##_t)arg, bits); \
995 } \
996\
997 static inline int##w##_t zig_mod_i##w(int##w##_t lhs, int##w##_t rhs) { \
998 int##w##_t rem = lhs % rhs; \
999 return rem + (rem != INT##w##_C(0) ? rhs & zig_shr_i##w(lhs ^ rhs, UINT8_C(w) - UINT8_C(1)) : INT##w##_C(0)); \
1000 } \
1001\
1002 static inline uint##w##_t zig_shlw_u##w(uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \
1003 return zig_u##w##_truncate_u##w(zig_shl_u##w(lhs, rhs), bits); \
1004 } \
1005\
1006 static inline int##w##_t zig_shlw_i##w(int##w##_t lhs, uint8_t rhs, uint8_t bits) { \
1007 return zig_i##w##_bitCast_u##w(zig_shl_u##w(zig_u##w##_bitCast_i##w(lhs, bits), rhs), bits); \
1008 } \
1009\
1010 static inline uint##w##_t zig_addw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
1011 return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs + rhs, bits); \
1012 } \
1013\
1014 static inline int##w##_t zig_addw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
1015 return zig_i##w##_bitCast_u##w(zig_addw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \
1016 } \
1017\
1018 static inline uint##w##_t zig_subw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
1019 return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs - rhs, bits); \
1020 } \
1021\
1022 static inline int##w##_t zig_subw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
1023 return zig_i##w##_bitCast_u##w(zig_subw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \
1024 } \
1025\
1026 static inline uint##w##_t zig_mulw_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
1027 return zig_u##w##_truncate_u##w((zig_promoted_u##w)lhs * rhs, bits); \
1028 } \
1029\
1030 static inline int##w##_t zig_mulw_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
1031 return zig_i##w##_bitCast_u##w(zig_mulw_u##w(zig_u##w##_bitCast_i##w(lhs, bits), zig_u##w##_bitCast_i##w(rhs, bits), bits), bits); \
1032 } \
1033\
1034 static inline uint##w##_t zig_abs_i##w(int##w##_t arg) { \
1035 int##w##_t tmp = zig_shr_i##w(arg, UINT8_C(w) - UINT8_C(1)); \
1036 return zig_u##w##_bitCast_i##w(zig_subw_i##w(zig_xor_i##w(arg, tmp), tmp, UINT8_C(w)), UINT8_C(w)); \
1037 } \
1038\
1039 static inline uint##w##_t zig_min_u##w(uint##w##_t lhs, uint##w##_t rhs) { \
1040 return lhs < rhs ? lhs : rhs; \
1041 } \
1042\
1043 static inline int##w##_t zig_min_i##w(int##w##_t lhs, int##w##_t rhs) { \
1044 return lhs < rhs ? lhs : rhs; \
1045 } \
1046\
1047 static inline uint##w##_t zig_max_u##w(uint##w##_t lhs, uint##w##_t rhs) { \
1048 return lhs >= rhs ? lhs : rhs; \
1049 } \
1050\
1051 static inline int##w##_t zig_max_i##w(int##w##_t lhs, int##w##_t rhs) { \
1052 return lhs >= rhs ? lhs : rhs; \
1053 }
1054zig_int_operators(8)
1055zig_int_operators(16)
1056zig_int_operators(32)
1057zig_int_operators(64)
1058#ifdef zig_ez80
1059zig_int_operators(24)
1060zig_int_operators(48)
1061#endif
1062
1063#define zig_int_casts(bw, sw) \
1064 static inline uint##sw##_t zig_u##sw##_intCast_u##bw(uint##bw##_t arg) { \
1065 return (uint##sw##_t)arg; \
1066 } \
1067\
1068 static inline uint##sw##_t zig_u##sw##_intCast_i##bw(int##bw##_t arg) { \
1069 return (uint##sw##_t)arg; \
1070 } \
1071\
1072 static inline int##sw##_t zig_i##sw##_intCast_u##bw(uint##bw##_t arg) { \
1073 return (int##sw##_t)arg; \
1074 } \
1075\
1076 static inline int##sw##_t zig_i##sw##_intCast_i##bw(int##bw##_t arg) { \
1077 return (int##sw##_t)arg; \
1078 } \
1079\
1080 zig_int_casts_common(bw, sw)
1081zig_int_casts(16, 8)
1082zig_int_casts(32, 8)
1083zig_int_casts(64, 8)
1084zig_int_casts(32, 16)
1085zig_int_casts(64, 16)
1086zig_int_casts(64, 32)
1087#ifdef zig_ez80
1088zig_int_casts(32, 24)
1089zig_int_casts(48, 24)
1090zig_int_casts(64, 24)
1091zig_int_casts(64, 48)
1092#endif
1093
1094static inline bool zig_addo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
1095#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1096 uint32_t full_res;
1097 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1098 *res = zig_u32_truncate_u32(full_res, bits);
1099 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);
1100#else
1101 *res = zig_addw_u32(lhs, rhs, bits);
1102 return *res < lhs;
1103#endif
1104}
1105
1106static inline bool zig_addo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) {
1107#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1108 int32_t full_res;
1109 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1110 *res = zig_i32_truncate_i32(full_res, bits);
1111 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
1112#else
1113 *res = zig_addw_i32(lhs, rhs, bits);
1114 return ((*res ^ lhs) & (*res ^ rhs)) < INT32_C(0);
1115#endif
1116}
1117
1118static inline bool zig_addo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
1119#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1120 uint64_t full_res;
1121 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1122 *res = zig_u64_truncate_u64(full_res, bits);
1123 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);
1124#else
1125 *res = zig_addw_u64(lhs, rhs, bits);
1126 return *res < lhs;
1127#endif
1128}
1129
1130static inline bool zig_addo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) {
1131#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1132 int64_t full_res;
1133 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1134 *res = zig_i64_truncate_i64(full_res, bits);
1135 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
1136#else
1137 *res = zig_addw_i64(lhs, rhs, bits);
1138 return ((*res ^ lhs) & (*res ^ rhs)) < INT64_C(0);
1139#endif
1140}
1141
1142static inline bool zig_addo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {
1143#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1144 uint8_t full_res;
1145 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1146 *res = zig_u8_truncate_u8(full_res, bits);
1147 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);
1148#else
1149 uint32_t full_res;
1150 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
1151 *res = zig_u8_intCast_u32(full_res);
1152 return overflow;
1153#endif
1154}
1155
1156static inline bool zig_addo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits) {
1157#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1158 int8_t full_res;
1159 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1160 *res = zig_i8_truncate_i8(full_res, bits);
1161 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);
1162#else
1163 int32_t full_res;
1164 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
1165 *res = zig_i8_intCast_i32(full_res);
1166 return overflow;
1167#endif
1168}
1169
1170static inline bool zig_addo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8_t bits) {
1171#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1172 uint16_t full_res;
1173 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1174 *res = zig_u16_truncate_u16(full_res, bits);
1175 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);
1176#else
1177 uint32_t full_res;
1178 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
1179 *res = zig_u16_intCast_u32(full_res);
1180 return overflow;
1181#endif
1182}
1183
1184static inline bool zig_addo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t bits) {
1185#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1186 int16_t full_res;
1187 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1188 *res = zig_i16_truncate_i16(full_res, bits);
1189 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);
1190#else
1191 int32_t full_res;
1192 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
1193 *res = zig_i16_intCast_i32(full_res);
1194 return overflow;
1195#endif
1196}
1197
1198#if defined(zig_ez80)
1199
1200static inline bool zig_addo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
1201#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1202 uint24_t full_res;
1203 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1204 *res = zig_u24_truncate_u24(full_res, bits);
1205 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
1206#else
1207 uint32_t full_res;
1208 bool overflow = zig_addo_u32(&full_res, lhs, rhs, bits);
1209 *res = zig_u24_intCast_u32(full_res);
1210 return overflow;
1211#endif
1212}
1213
1214static inline bool zig_addo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t bits) {
1215#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1216 int24_t full_res;
1217 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1218 *res = zig_i24_truncate_i24(full_res, bits);
1219 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
1220#else
1221 int32_t full_res;
1222 bool overflow = zig_addo_i32(&full_res, lhs, rhs, bits);
1223 *res = zig_i24_intCast_i32(full_res);
1224 return overflow;
1225#endif
1226}
1227
1228static inline bool zig_addo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
1229#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1230 uint48_t full_res;
1231 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1232 *res = zig_u48_truncate_u48(full_res, bits);
1233 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
1234#else
1235 uint64_t full_res;
1236 bool overflow = zig_addo_u64(&full_res, lhs, rhs, bits);
1237 *res = zig_u48_intCast_u64(full_res);
1238 return overflow;
1239#endif
1240}
1241
1242static inline bool zig_addo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t bits) {
1243#if zig_has_builtin(add_overflow) || defined(zig_gcc)
1244 int48_t full_res;
1245 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
1246 *res = zig_i48_truncate_i48(full_res, bits);
1247 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
1248#else
1249 int64_t full_res;
1250 bool overflow = zig_addo_i64(&full_res, lhs, rhs, bits);
1251 *res = zig_i48_intCast_i64(full_res);
1252 return overflow;
1253#endif
1254}
1255
1256#endif
1257
1258static inline bool zig_subo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
1259#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1260 uint32_t full_res;
1261 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1262 *res = zig_u32_truncate_u32(full_res, bits);
1263 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);
1264#else
1265 *res = zig_subw_u32(lhs, rhs, bits);
1266 return *res > lhs;
1267#endif
1268}
1269
1270static inline bool zig_subo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) {
1271#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1272 int32_t full_res;
1273 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1274 *res = zig_i32_truncate_i32(full_res, bits);
1275 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
1276#else
1277 *res = zig_subw_i32(lhs, rhs, bits);
1278 return ((lhs ^ rhs) & (*res ^ lhs)) < INT32_C(0);
1279#endif
1280}
1281
1282static inline bool zig_subo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
1283#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1284 uint64_t full_res;
1285 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1286 *res = zig_u64_truncate_u64(full_res, bits);
1287 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);
1288#else
1289 *res = zig_subw_u64(lhs, rhs, bits);
1290 return *res > lhs;
1291#endif
1292}
1293
1294static inline bool zig_subo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) {
1295#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1296 int64_t full_res;
1297 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1298 *res = zig_i64_truncate_i64(full_res, bits);
1299 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
1300#else
1301 *res = zig_subw_i64(lhs, rhs, bits);
1302 return ((lhs ^ rhs) & (*res ^ lhs)) < INT64_C(0);
1303#endif
1304}
1305
1306static inline bool zig_subo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {
1307#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1308 uint8_t full_res;
1309 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1310 *res = zig_u8_truncate_u8(full_res, bits);
1311 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);
1312#else
1313 uint32_t full_res;
1314 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
1315 *res = zig_u8_intCast_u32(full_res);
1316 return overflow;
1317#endif
1318}
1319
1320static inline bool zig_subo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits) {
1321#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1322 int8_t full_res;
1323 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1324 *res = zig_i8_truncate_i8(full_res, bits);
1325 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);
1326#else
1327 int32_t full_res;
1328 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
1329 *res = zig_i8_intCast_i32(full_res);
1330 return overflow;
1331#endif
1332}
1333
1334static inline bool zig_subo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8_t bits) {
1335#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1336 uint16_t full_res;
1337 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1338 *res = zig_u16_truncate_u16(full_res, bits);
1339 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);
1340#else
1341 uint32_t full_res;
1342 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
1343 *res = zig_u16_intCast_u32(full_res);
1344 return overflow;
1345#endif
1346}
1347
1348static inline bool zig_subo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t bits) {
1349#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1350 int16_t full_res;
1351 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1352 *res = zig_i16_truncate_i16(full_res, bits);
1353 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);
1354#else
1355 int32_t full_res;
1356 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
1357 *res = zig_i16_intCast_i32(full_res);
1358 return overflow;
1359#endif
1360}
1361
1362#if defined(zig_ez80)
1363
1364static inline bool zig_subo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
1365#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1366 uint24_t full_res;
1367 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1368 *res = zig_u24_truncate_u24(full_res, bits);
1369 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
1370#else
1371 uint32_t full_res;
1372 bool overflow = zig_subo_u32(&full_res, lhs, rhs, bits);
1373 *res = zig_u24_intCast_u32(full_res);
1374 return overflow;
1375#endif
1376}
1377
1378static inline bool zig_subo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t bits) {
1379#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1380 int24_t full_res;
1381 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1382 *res = zig_i24_truncate_i24(full_res, bits);
1383 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
1384#else
1385 int32_t full_res;
1386 bool overflow = zig_subo_i32(&full_res, lhs, rhs, bits);
1387 *res = zig_i24_intCast_i32(full_res);
1388 return overflow;
1389#endif
1390}
1391
1392static inline bool zig_subo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
1393#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1394 uint48_t full_res;
1395 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1396 *res = zig_u48_truncate_u48(full_res, bits);
1397 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
1398#else
1399 uint64_t full_res;
1400 bool overflow = zig_subo_u64(&full_res, lhs, rhs, bits);
1401 *res = zig_u48_intCast_u64(full_res);
1402 return overflow;
1403#endif
1404}
1405
1406static inline bool zig_subo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t bits) {
1407#if zig_has_builtin(sub_overflow) || defined(zig_gcc)
1408 int48_t full_res;
1409 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
1410 *res = zig_i48_truncate_i48(full_res, bits);
1411 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
1412#else
1413 int64_t full_res;
1414 bool overflow = zig_subo_i64(&full_res, lhs, rhs, bits);
1415 *res = zig_i48_intCast_i64(full_res);
1416 return overflow;
1417#endif
1418}
1419
1420#endif
1421
1422static inline bool zig_mulo_u32(uint32_t *res, uint32_t lhs, uint32_t rhs, uint8_t bits) {
1423#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1424 uint32_t full_res;
1425 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1426 *res = zig_u32_truncate_u32(full_res, bits);
1427 return overflow || full_res < zig_minInt_u(32, bits) || full_res > zig_maxInt_u(32, bits);
1428#else
1429 *res = zig_mulw_u32(lhs, rhs, bits);
1430 return rhs != UINT32_C(0) && lhs > zig_maxInt_u(32, bits) / rhs;
1431#endif
1432}
1433
1434static inline bool zig_mulo_i32(int32_t *res, int32_t lhs, int32_t rhs, uint8_t bits) {
1435 zig_extern int32_t __mulosi4(int32_t lhs, int32_t rhs, int *overflow);
1436#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1437 int32_t full_res;
1438 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1439#else
1440 int overflow_int;
1441 int32_t full_res = __mulosi4(lhs, rhs, &overflow_int);
1442 bool overflow = overflow_int != 0;
1443#endif
1444 *res = zig_i32_truncate_i32(full_res, bits);
1445 return overflow || full_res < zig_minInt_i(32, bits) || full_res > zig_maxInt_i(32, bits);
1446}
1447
1448static inline bool zig_mulo_u64(uint64_t *res, uint64_t lhs, uint64_t rhs, uint8_t bits) {
1449#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1450 uint64_t full_res;
1451 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1452 *res = zig_u64_truncate_u64(full_res, bits);
1453 return overflow || full_res < zig_minInt_u(64, bits) || full_res > zig_maxInt_u(64, bits);
1454#else
1455 *res = zig_mulw_u64(lhs, rhs, bits);
1456 return rhs != UINT64_C(0) && lhs > zig_maxInt_u(64, bits) / rhs;
1457#endif
1458}
1459
1460static inline bool zig_mulo_i64(int64_t *res, int64_t lhs, int64_t rhs, uint8_t bits) {
1461 zig_extern int64_t __mulodi4(int64_t lhs, int64_t rhs, int *overflow);
1462#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1463 int64_t full_res;
1464 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1465#else
1466 int overflow_int;
1467 int64_t full_res = __mulodi4(lhs, rhs, &overflow_int);
1468 bool overflow = overflow_int != 0;
1469#endif
1470 *res = zig_i64_truncate_i64(full_res, bits);
1471 return overflow || full_res < zig_minInt_i(64, bits) || full_res > zig_maxInt_i(64, bits);
1472}
1473
1474static inline bool zig_mulo_u8(uint8_t *res, uint8_t lhs, uint8_t rhs, uint8_t bits) {
1475#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1476 uint8_t full_res;
1477 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1478 *res = zig_u8_truncate_u8(full_res, bits);
1479 return overflow || full_res < zig_minInt_u(8, bits) || full_res > zig_maxInt_u(8, bits);
1480#else
1481 uint32_t full_res;
1482 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
1483 *res = zig_u8_intCast_u32(full_res);
1484 return overflow;
1485#endif
1486}
1487
1488static inline bool zig_mulo_i8(int8_t *res, int8_t lhs, int8_t rhs, uint8_t bits) {
1489#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1490 int8_t full_res;
1491 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1492 *res = zig_i8_truncate_i8(full_res, bits);
1493 return overflow || full_res < zig_minInt_i(8, bits) || full_res > zig_maxInt_i(8, bits);
1494#else
1495 int32_t full_res;
1496 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
1497 *res = zig_i8_intCast_i32(full_res);
1498 return overflow;
1499#endif
1500}
1501
1502static inline bool zig_mulo_u16(uint16_t *res, uint16_t lhs, uint16_t rhs, uint8_t bits) {
1503#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1504 uint16_t full_res;
1505 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1506 *res = zig_u16_truncate_u16(full_res, bits);
1507 return overflow || full_res < zig_minInt_u(16, bits) || full_res > zig_maxInt_u(16, bits);
1508#else
1509 uint32_t full_res;
1510 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
1511 *res = zig_u16_intCast_u32(full_res);
1512 return overflow;
1513#endif
1514}
1515
1516static inline bool zig_mulo_i16(int16_t *res, int16_t lhs, int16_t rhs, uint8_t bits) {
1517#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1518 int16_t full_res;
1519 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1520 *res = zig_i16_truncate_i16(full_res, bits);
1521 return overflow || full_res < zig_minInt_i(16, bits) || full_res > zig_maxInt_i(16, bits);
1522#else
1523 int32_t full_res;
1524 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
1525 *res = zig_i16_intCast_i32(full_res);
1526 return overflow;
1527#endif
1528}
1529
1530#if defined(zig_ez80)
1531
1532static inline bool zig_mulo_u24(uint24_t *res, uint24_t lhs, uint24_t rhs, uint8_t bits) {
1533#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1534 uint24_t full_res;
1535 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1536 *res = zig_u24_truncate_u24(full_res, bits);
1537 return overflow || full_res < zig_minInt_u(24, bits) || full_res > zig_maxInt_u(24, bits);
1538#else
1539 uint32_t full_res;
1540 bool overflow = zig_mulo_u32(&full_res, lhs, rhs, bits);
1541 *res = zig_u24_intCast_u32(full_res);
1542 return overflow;
1543#endif
1544}
1545
1546static inline bool zig_mulo_i24(int24_t *res, int24_t lhs, int24_t rhs, uint8_t bits) {
1547#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1548 int24_t full_res;
1549 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1550 *res = zig_i24_truncate_i24(full_res, bits);
1551 return overflow || full_res < zig_minInt_i(24, bits) || full_res > zig_maxInt_i(24, bits);
1552#else
1553 int32_t full_res;
1554 bool overflow = zig_mulo_i32(&full_res, lhs, rhs, bits);
1555 *res = zig_i24_intCast_i32(full_res);
1556 return overflow;
1557#endif
1558}
1559
1560static inline bool zig_mulo_u48(uint48_t *res, uint48_t lhs, uint48_t rhs, uint8_t bits) {
1561#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1562 uint48_t full_res;
1563 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1564 *res = zig_u48_truncate_u48(full_res, bits);
1565 return overflow || full_res < zig_minInt_u(48, bits) || full_res > zig_maxInt_u(48, bits);
1566#else
1567 uint64_t full_res;
1568 bool overflow = zig_mulo_u64(&full_res, lhs, rhs, bits);
1569 *res = zig_u48_intCast_u64(full_res);
1570 return overflow;
1571#endif
1572}
1573
1574static inline bool zig_mulo_i48(int48_t *res, int48_t lhs, int48_t rhs, uint8_t bits) {
1575#if zig_has_builtin(mul_overflow) || defined(zig_gcc)
1576 int48_t full_res;
1577 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
1578 *res = zig_i48_truncate_i48(full_res, bits);
1579 return overflow || full_res < zig_minInt_i(48, bits) || full_res > zig_maxInt_i(48, bits);
1580#else
1581 int64_t full_res;
1582 bool overflow = zig_mulo_i64(&full_res, lhs, rhs, bits);
1583 *res = zig_i48_intCast_i64(full_res);
1584 return overflow;
1585#endif
1586}
1587
1588#endif
1589
1590#define zig_shls_builtins(lw, rw) \
1591 static inline uint##lw##_t zig_shls_u##lw##_u##rw(uint##lw##_t lhs, uint##rw##_t rhs, uint8_t bits) { \
1592 uint##lw##_t res; \
1593 if (rhs < bits && !zig_shlo_u##lw(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
1594 return lhs == INT##lw##_C(0) ? zig_minInt_u(lw, bits) : zig_maxInt_u(lw, bits); \
1595 } \
1596\
1597 static inline int##lw##_t zig_shls_i##lw##_u##rw(int##lw##_t lhs, uint##rw##_t rhs, uint8_t bits) { \
1598 int##lw##_t res; \
1599 if (rhs < bits && !zig_shlo_i##lw(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
1600 return lhs == INT##lw##_C(0) ? INT##lw##_C(0) : \
1601 lhs < INT##lw##_C(0) ? zig_minInt_i(lw, bits) : zig_maxInt_i(lw, bits); \
1602 }
1603#define zig_int_sat_builtins(w) \
1604 static inline bool zig_shlo_u##w(uint##w##_t *res, uint##w##_t lhs, uint8_t rhs, uint8_t bits) { \
1605 *res = zig_shlw_u##w(lhs, rhs, bits); \
1606 return lhs > zig_maxInt_u(w, bits) >> rhs; \
1607 } \
1608\
1609 static inline bool zig_shlo_i##w(int##w##_t *res, int##w##_t lhs, uint8_t rhs, uint8_t bits) { \
1610 *res = zig_shlw_i##w(lhs, rhs, bits); \
1611 int##w##_t mask = (int##w##_t)(UINT##w##_MAX << (bits - rhs - 1)); \
1612 return (lhs & mask) != INT##w##_C(0) && (lhs & mask) != mask; \
1613 } \
1614\
1615 zig_shls_builtins(w, 8) \
1616 zig_shls_builtins(w, 16) \
1617 zig_shls_builtins(w, 32) \
1618 zig_shls_builtins(w, 64) \
1619\
1620 static inline uint##w##_t zig_adds_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
1621 uint##w##_t res; \
1622 return zig_addo_u##w(&res, lhs, rhs, bits) ? zig_maxInt_u(w, bits) : res; \
1623 } \
1624\
1625 static inline int##w##_t zig_adds_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
1626 int##w##_t res; \
1627 if (!zig_addo_i##w(&res, lhs, rhs, bits)) return res; \
1628 return res >= INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \
1629 } \
1630\
1631 static inline uint##w##_t zig_subs_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
1632 uint##w##_t res; \
1633 return zig_subo_u##w(&res, lhs, rhs, bits) ? zig_minInt_u(w, bits) : res; \
1634 } \
1635\
1636 static inline int##w##_t zig_subs_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
1637 int##w##_t res; \
1638 if (!zig_subo_i##w(&res, lhs, rhs, bits)) return res; \
1639 return res >= INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \
1640 } \
1641\
1642 static inline uint##w##_t zig_muls_u##w(uint##w##_t lhs, uint##w##_t rhs, uint8_t bits) { \
1643 uint##w##_t res; \
1644 return zig_mulo_u##w(&res, lhs, rhs, bits) ? zig_maxInt_u(w, bits) : res; \
1645 } \
1646\
1647 static inline int##w##_t zig_muls_i##w(int##w##_t lhs, int##w##_t rhs, uint8_t bits) { \
1648 int##w##_t res; \
1649 if (!zig_mulo_i##w(&res, lhs, rhs, bits)) return res; \
1650 return (lhs ^ rhs) < INT##w##_C(0) ? zig_minInt_i(w, bits) : zig_maxInt_i(w, bits); \
1651 }
1652zig_int_sat_builtins(8)
1653zig_int_sat_builtins(16)
1654zig_int_sat_builtins(32)
1655zig_int_sat_builtins(64)
1656#if defined(zig_ez80)
1657zig_int_sat_builtins(24)
1658zig_int_sat_builtins(48)
1659#endif
1660
1661#define zig_builtin8(name, arg) __builtin_##name(arg)
1662typedef unsigned int zig_Builtin8;
1663
1664#define zig_builtin16(name, arg) __builtin_##name(arg)
1665typedef unsigned int zig_Builtin16;
1666
1667#if INT_MIN <= INT32_MIN
1668#define zig_builtin32(name, arg) __builtin_##name(arg)
1669typedef unsigned int zig_Builtin32;
1670#elif LONG_MIN <= INT32_MIN
1671#define zig_builtin32(name, arg) __builtin_##name##l(arg)
1672typedef unsigned long zig_Builtin32;
1673#endif
1674
1675#if INT_MIN <= INT64_MIN
1676#define zig_builtin64(name, arg) __builtin_##name(arg)
1677typedef unsigned int zig_Builtin64;
1678#elif LONG_MIN <= INT64_MIN
1679#define zig_builtin64(name, arg) __builtin_##name##l(arg)
1680typedef unsigned long zig_Builtin64;
1681#elif LLONG_MIN <= INT64_MIN
1682#define zig_builtin64(name, arg) __builtin_##name##ll(arg)
1683typedef unsigned long long zig_Builtin64;
1684#endif
1685
1686#if defined(zig_ez80)
1687#define zig_builtin24(name, arg) __builtin_##name(arg)
1688typedef unsigned int zig_Builtin24;
1689#define zig_builtin48(name, arg) __builtin_##name(arg)
1690typedef unsigned long long zig_Builtin48;
1691#endif
1692
1693static inline uint8_t zig_byteSwap_u8(uint8_t arg, uint8_t bits) {
1694 return zig_u8_truncate_u8(arg >> (8 - bits), bits);
1695}
1696
1697static inline int8_t zig_byteSwap_i8(int8_t arg, uint8_t bits) {
1698 return zig_i8_truncate_i8((int8_t)zig_byteSwap_u8((uint8_t)arg, bits), bits);
1699}
1700
1701static inline uint16_t zig_byteSwap_u16(uint16_t arg, uint8_t bits) {
1702 uint16_t full_res;
1703#if zig_has_builtin(bswap16) || defined(zig_gcc)
1704 full_res = __builtin_bswap16(arg);
1705#else
1706 full_res = (uint16_t)zig_byteSwap_u8((uint8_t)(arg >> 0), 8) << 8 |
1707 (uint16_t)zig_byteSwap_u8((uint8_t)(arg >> 8), 8) >> 0;
1708#endif
1709 return zig_u16_truncate_u16(full_res >> (16 - bits), bits);
1710}
1711
1712static inline int16_t zig_byteSwap_i16(int16_t arg, uint8_t bits) {
1713 return zig_i16_truncate_i16((int16_t)zig_byteSwap_u16((uint16_t)arg, bits), bits);
1714}
1715
1716#if defined(zig_ez80)
1717static inline uint16_t zig_byteSwap_u24(uint24_t arg, uint8_t bits) {
1718 uint24_t full_res;
1719#if zig_has_builtin(bswap24) || defined(zig_gcc)
1720 full_res = __builtin_bswap24(arg);
1721#else
1722 full_res = (uint24_t)zig_byteSwap_u8((uint8_t)(arg >> 0), 8) << 16 |
1723 (uint24_t)zig_byteSwap_u16((uint16_t)(arg >> 8), 16) >> 0;
1724#endif
1725 return zig_u24_truncate_u24(full_res >> (24 - bits), bits);
1726}
1727
1728static inline int16_t zig_byteSwap_i24(int24_t arg, uint8_t bits) {
1729 return zig_i24_truncate_i24((int24_t)zig_byteSwap_u24((uint24_t)arg, bits), bits);
1730}
1731#endif
1732
1733static inline uint32_t zig_byteSwap_u32(uint32_t arg, uint8_t bits) {
1734 uint32_t full_res;
1735#if zig_has_builtin(bswap32) || defined(zig_gcc)
1736 full_res = __builtin_bswap32(arg);
1737#else
1738 full_res = (uint32_t)zig_byteSwap_u16((uint16_t)(arg >> 0), 16) << 16 |
1739 (uint32_t)zig_byteSwap_u16((uint16_t)(arg >> 16), 16) >> 0;
1740#endif
1741 return zig_u32_truncate_u32(full_res >> (32 - bits), bits);
1742}
1743
1744static inline int32_t zig_byteSwap_i32(int32_t arg, uint8_t bits) {
1745 return zig_i32_truncate_i32((int32_t)zig_byteSwap_u32((uint32_t)arg, bits), bits);
1746}
1747
1748#if defined(zig_ez80)
1749static inline uint32_t zig_byteSwap_u48(uint48_t arg, uint8_t bits) {
1750 uint48_t full_res;
1751#if zig_has_builtin(bswap48) || defined(zig_gcc)
1752 full_res = __builtin_bswap48(arg);
1753#else
1754 full_res = (uint48_t)zig_byteSwap_u24((uint24_t)(arg >> 0), 24) << 24 |
1755 (uint48_t)zig_byteSwap_u24((uint24_t)(arg >> 24), 24) >> 0;
1756#endif
1757 return zig_u48_truncate_u48(full_res >> (48 - bits), bits);
1758}
1759
1760static inline int32_t zig_byteSwap_i48(int48_t arg, uint8_t bits) {
1761 return zig_i48_truncate_i48((int48_t)zig_byteSwap_u48((uint48_t)arg, bits), bits);
1762}
1763#endif
1764
1765static inline uint64_t zig_byteSwap_u64(uint64_t arg, uint8_t bits) {
1766 uint64_t full_res;
1767#if zig_has_builtin(bswap64) || defined(zig_gcc)
1768 full_res = __builtin_bswap64(arg);
1769#else
1770 full_res = (uint64_t)zig_byteSwap_u32((uint32_t)(arg >> 0), 32) << 32 |
1771 (uint64_t)zig_byteSwap_u32((uint32_t)(arg >> 32), 32) >> 0;
1772#endif
1773 return zig_u64_truncate_u64(full_res >> (64 - bits), bits);
1774}
1775
1776static inline int64_t zig_byteSwap_i64(int64_t arg, uint8_t bits) {
1777 return zig_i64_truncate_i64((int64_t)zig_byteSwap_u64((uint64_t)arg, bits), bits);
1778}
1779
1780static inline uint8_t zig_bitReverse_u8(uint8_t arg, uint8_t bits) {
1781 uint8_t full_res;
1782#if zig_has_builtin(bitreverse8)
1783 full_res = __builtin_bitreverse8(arg);
1784#else
1785 static uint8_t const lut[0x10] = {
1786 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
1787 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf
1788 };
1789 full_res = lut[arg >> 0 & 0xF] << 4 | lut[arg >> 4 & 0xF] << 0;
1790#endif
1791 return zig_u8_truncate_u8(full_res >> (8 - bits), bits);
1792}
1793
1794static inline int8_t zig_bitReverse_i8(int8_t arg, uint8_t bits) {
1795 return zig_i8_truncate_i8((int8_t)zig_bitReverse_u8((uint8_t)arg, bits), bits);
1796}
1797
1798static inline uint16_t zig_bitReverse_u16(uint16_t arg, uint8_t bits) {
1799 uint16_t full_res;
1800#if zig_has_builtin(bitreverse16)
1801 full_res = __builtin_bitreverse16(arg);
1802#else
1803 full_res = (uint16_t)zig_bitReverse_u8((uint8_t)(arg >> 0), 8) << 8 |
1804 (uint16_t)zig_bitReverse_u8((uint8_t)(arg >> 8), 8) >> 0;
1805#endif
1806 return zig_u16_truncate_u16(full_res >> (16 - bits), bits);
1807}
1808
1809static inline int16_t zig_bitReverse_i16(int16_t arg, uint8_t bits) {
1810 return zig_i16_truncate_i16((int16_t)zig_bitReverse_u16((uint16_t)arg, bits), bits);
1811}
1812
1813#if defined(zig_ez80)
1814static inline uint24_t zig_bitReverse_u24(uint24_t arg, uint8_t bits) {
1815 uint24_t full_res;
1816#if zig_has_builtin(bitreverse24)
1817 full_res = __builtin_bitreverse24(arg);
1818#else
1819 full_res = (uint24_t)zig_bitReverse_u8((uint8_t)(arg >> 0), 8) << 16 |
1820 (uint24_t)zig_bitReverse_u16((uint16_t)(arg >> 8), 16) >> 0;
1821#endif
1822 return zig_u24_truncate_u24(full_res >> (24 - bits), bits);
1823}
1824
1825static inline int24_t zig_bitReverse_i24(int24_t arg, uint8_t bits) {
1826 return zig_i24_truncate_i24((int24_t)zig_bitReverse_u24((uint24_t)arg, bits), bits);
1827}
1828#endif
1829
1830static inline uint32_t zig_bitReverse_u32(uint32_t arg, uint8_t bits) {
1831 uint32_t full_res;
1832#if zig_has_builtin(bitreverse32)
1833 full_res = __builtin_bitreverse32(arg);
1834#else
1835 full_res = (uint32_t)zig_bitReverse_u16((uint16_t)(arg >> 0), 16) << 16 |
1836 (uint32_t)zig_bitReverse_u16((uint16_t)(arg >> 16), 16) >> 0;
1837#endif
1838 return zig_u32_truncate_u32(full_res >> (32 - bits), bits);
1839}
1840
1841static inline int32_t zig_bitReverse_i32(int32_t arg, uint8_t bits) {
1842 return zig_i32_truncate_i32((int32_t)zig_bitReverse_u32((uint32_t)arg, bits), bits);
1843}
1844
1845#if defined(zig_ez80)
1846static inline uint32_t zig_bitReverse_u48(uint48_t arg, uint8_t bits) {
1847 uint48_t full_res;
1848#if zig_has_builtin(bitreverse48)
1849 full_res = __builtin_bitreverse48(arg);
1850#else
1851 full_res = (uint48_t)zig_bitReverse_u24((uint24_t)(arg >> 0), 24) << 24 |
1852 (uint48_t)zig_bitReverse_u24((uint24_t)(arg >> 24), 24) >> 0;
1853#endif
1854 return zig_u48_truncate_u48(full_res >> (48 - bits), bits);
1855}
1856
1857static inline int32_t zig_bitReverse_i48(int48_t arg, uint8_t bits) {
1858 return zig_i48_truncate_i48((int48_t)zig_bitReverse_u48((uint48_t)arg, bits), bits);
1859}
1860#endif
1861
1862static inline uint64_t zig_bitReverse_u64(uint64_t arg, uint8_t bits) {
1863 uint64_t full_res;
1864#if zig_has_builtin(bitreverse64)
1865 full_res = __builtin_bitreverse64(arg);
1866#else
1867 full_res = (uint64_t)zig_bitReverse_u32((uint32_t)(arg >> 0), 32) << 32 |
1868 (uint64_t)zig_bitReverse_u32((uint32_t)(arg >> 32), 32) >> 0;
1869#endif
1870 return zig_u64_truncate_u64(full_res >> (64 - bits), bits);
1871}
1872
1873static inline int64_t zig_bitReverse_i64(int64_t arg, uint8_t bits) {
1874 return zig_i64_truncate_i64((int64_t)zig_bitReverse_u64((uint64_t)arg, bits), bits);
1875}
1876
1877#define zig_builtin_popCount_common(w) \
1878 static inline uint8_t zig_popCount_i##w(int##w##_t arg, uint8_t bits) { \
1879 return zig_popCount_u##w((uint##w##_t)arg, bits); \
1880 }
1881#if zig_has_builtin(popCount) || defined(zig_gcc) || defined(zig_tinyc)
1882#define zig_builtin_popCount(w) \
1883 static inline uint8_t zig_popCount_u##w(uint##w##_t arg, uint8_t bits) { \
1884 (void)bits; \
1885 return zig_builtin##w(popcount, arg); \
1886 } \
1887\
1888 zig_builtin_popCount_common(w)
1889#else
1890#define zig_builtin_popCount(w) \
1891 static inline uint8_t zig_popCount_u##w(uint##w##_t arg, uint8_t bits) { \
1892 (void)bits; \
1893 uint##w##_t temp = arg - ((arg >> 1) & (UINT##w##_MAX / 3)); \
1894 temp = (temp & (UINT##w##_MAX / 5)) + ((temp >> 2) & (UINT##w##_MAX / 5)); \
1895 temp = (temp + (temp >> 4)) & (UINT##w##_MAX / 17); \
1896 return temp * (UINT##w##_MAX / 255) >> (UINT8_C(w) - UINT8_C(8)); \
1897 } \
1898\
1899 zig_builtin_popCount_common(w)
1900#endif
1901zig_builtin_popCount(8)
1902zig_builtin_popCount(16)
1903zig_builtin_popCount(32)
1904zig_builtin_popCount(64)
1905#if defined(zig_ez80)
1906zig_builtin_popCount(24)
1907zig_builtin_popCount(48)
1908#endif
1909
1910#define zig_builtin_ctz_common(w) \
1911 static inline uint8_t zig_ctz_i##w(int##w##_t arg, uint8_t bits) { \
1912 return zig_ctz_u##w((uint##w##_t)arg, bits); \
1913 }
1914#if zig_has_builtin(ctz) || defined(zig_gcc) || defined(zig_tinyc)
1915#define zig_builtin_ctz(w) \
1916 static inline uint8_t zig_ctz_u##w(uint##w##_t arg, uint8_t bits) { \
1917 if (arg == 0) return bits; \
1918 return zig_builtin##w(ctz, arg); \
1919 } \
1920\
1921 zig_builtin_ctz_common(w)
1922#else
1923#define zig_builtin_ctz(w) \
1924 static inline uint8_t zig_ctz_u##w(uint##w##_t arg, uint8_t bits) { \
1925 return zig_popCount_u##w(zig_not_u##w(arg, bits) & zig_subw_u##w(arg, 1, bits), bits); \
1926 } \
1927\
1928 zig_builtin_ctz_common(w)
1929#endif
1930zig_builtin_ctz(8)
1931zig_builtin_ctz(16)
1932zig_builtin_ctz(32)
1933zig_builtin_ctz(64)
1934#if defined(zig_ez80)
1935zig_builtin_ctz(24)
1936zig_builtin_ctz(48)
1937#endif
1938
1939#define zig_builtin_clz_common(w) \
1940 static inline uint8_t zig_clz_i##w(int##w##_t arg, uint8_t bits) { \
1941 return zig_clz_u##w((uint##w##_t)arg, bits); \
1942 }
1943#if zig_has_builtin(clz) || defined(zig_gcc) || defined(zig_tinyc)
1944#define zig_builtin_clz(w) \
1945 static inline uint8_t zig_clz_u##w(uint##w##_t arg, uint8_t bits) { \
1946 if (arg == 0) return bits; \
1947 return zig_builtin##w(clz, arg) - (zig_bitSizeOf(zig_Builtin##w) - bits); \
1948 } \
1949\
1950 zig_builtin_clz_common(w)
1951#else
1952#define zig_builtin_clz(w) \
1953 static inline uint8_t zig_clz_u##w(uint##w##_t arg, uint8_t bits) { \
1954 return zig_ctz_u##w(zig_bitReverse_u##w(arg, bits), bits); \
1955 } \
1956\
1957 zig_builtin_clz_common(w)
1958#endif
1959zig_builtin_clz(8)
1960zig_builtin_clz(16)
1961zig_builtin_clz(32)
1962zig_builtin_clz(64)
1963#if defined(zig_ez80)
1964zig_builtin_clz(24)
1965zig_builtin_clz(48)
1966#endif
1967
1968/* ======================== 128-bit Integer Support ========================= */
1969
1970#if !defined(zig_has_int128)
1971# if defined(__SIZEOF_INT128__)
1972# define zig_has_int128 1
1973# else
1974# define zig_has_int128 0
1975# endif
1976#endif
1977
1978#if zig_has_int128
1979
1980typedef unsigned __int128 zig_u128;
1981typedef signed __int128 zig_i128;
1982
1983#define zig_init_u128(hi, lo) ((zig_u128)(hi)<<64|(lo))
1984#define zig_init_i128(hi, lo) ((zig_i128)zig_make_u128(hi, lo))
1985#define zig_make_u128(hi, lo) zig_init_u128(hi, lo)
1986#define zig_make_i128(hi, lo) zig_init_i128(hi, lo)
1987#define zig_hi_u128(arg) ((uint64_t)((arg) >> 64))
1988#define zig_lo_u128(arg) ((uint64_t)((arg) >> 0))
1989#define zig_hi_i128(arg) (( int64_t)((arg) >> 64))
1990#define zig_lo_i128(arg) ((uint64_t)((arg) >> 0))
1991#define zig_cmp_int128(Type) \
1992 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
1993 return (lhs > rhs) - (lhs < rhs); \
1994 }
1995#define zig_bit_int128(Type, operation, operator) \
1996 static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
1997 return lhs operator rhs; \
1998 }
1999
2000static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
2001 return lhs << rhs;
2002}
2003
2004static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) {
2005 return lhs >> rhs;
2006}
2007
2008static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {
2009 return lhs << rhs;
2010}
2011
2012static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
2013 // This works around a GCC miscompilation, but it has the side benefit of
2014 // emitting better code. It is behind the `#if` because it depends on
2015 // arithmetic right shift, which is implementation-defined in C, but should
2016 // be guaranteed on any GCC-compatible compiler.
2017#if defined(zig_gnuc)
2018 return lhs >> rhs;
2019#else
2020 zig_i128 sign_mask = lhs < zig_make_i128(0, 0) ? -zig_make_i128(0, 1) : zig_make_i128(0, 0);
2021 return ((lhs ^ sign_mask) >> rhs) ^ sign_mask;
2022#endif
2023}
2024
2025#else /* zig_has_int128 */
2026
2027#if zig_little_endian
2028typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t lo; uint64_t hi; } zig_u128;
2029typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t lo; int64_t hi; } zig_i128;
2030#else
2031typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) uint64_t hi; uint64_t lo; } zig_u128;
2032typedef struct { zig_align(ZIG_TARGET_MAX_INT_ALIGNMENT) int64_t hi; uint64_t lo; } zig_i128;
2033#endif
2034
2035#define zig_init_u128(hi, lo) { .h##i = hi, .l##o = lo }
2036#define zig_init_i128(hi, lo) { .h##i = hi, .l##o = lo }
2037#define zig_make_u128(hi, lo) (zig_u128)zig_init_u128(hi, lo)
2038#define zig_make_i128(hi, lo) (zig_i128)zig_init_i128(hi, lo)
2039#define zig_hi_u128(arg) (arg).hi
2040#define zig_lo_u128(arg) (arg).lo
2041#define zig_hi_i128(arg) (arg).hi
2042#define zig_lo_i128(arg) (arg).lo
2043#define zig_cmp_int128(Type) \
2044 static inline int32_t zig_cmp_##Type(zig_##Type lhs, zig_##Type rhs) { \
2045 return (lhs.hi == rhs.hi) \
2046 ? (lhs.lo > rhs.lo) - (lhs.lo < rhs.lo) \
2047 : (lhs.hi > rhs.hi) - (lhs.hi < rhs.hi); \
2048 }
2049#define zig_bit_int128(Type, operation, operator) \
2050 static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
2051 return (zig_##Type){ .hi = lhs.hi operator rhs.hi, .lo = lhs.lo operator rhs.lo }; \
2052 }
2053
2054static inline zig_u128 zig_shl_u128(zig_u128 lhs, uint8_t rhs) {
2055 if (rhs == UINT8_C(0)) return lhs;
2056 if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };
2057 return (zig_u128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
2058}
2059
2060static inline zig_u128 zig_shr_u128(zig_u128 lhs, uint8_t rhs) {
2061 if (rhs == UINT8_C(0)) return lhs;
2062 if (rhs >= UINT8_C(64)) return (zig_u128){ .hi = zig_minInt_u64, .lo = lhs.hi >> (rhs - UINT8_C(64)) };
2063 return (zig_u128){ .hi = lhs.hi >> rhs, .lo = lhs.hi << (UINT8_C(64) - rhs) | lhs.lo >> rhs };
2064}
2065
2066static inline zig_i128 zig_shl_i128(zig_i128 lhs, uint8_t rhs) {
2067 if (rhs == UINT8_C(0)) return lhs;
2068 if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = lhs.lo << (rhs - UINT8_C(64)), .lo = zig_minInt_u64 };
2069 return (zig_i128){ .hi = lhs.hi << rhs | lhs.lo >> (UINT8_C(64) - rhs), .lo = lhs.lo << rhs };
2070}
2071
2072static inline zig_i128 zig_shr_i128(zig_i128 lhs, uint8_t rhs) {
2073 if (rhs == UINT8_C(0)) return lhs;
2074 if (rhs >= UINT8_C(64)) return (zig_i128){ .hi = zig_shr_i64(lhs.hi, 63), .lo = zig_shr_i64(lhs.hi, (rhs - UINT8_C(64))) };
2075 return (zig_i128){ .hi = zig_shr_i64(lhs.hi, rhs), .lo = lhs.lo >> rhs | (uint64_t)lhs.hi << (UINT8_C(64) - rhs) };
2076}
2077
2078#endif /* zig_has_int128 */
2079
2080#define zig_minInt_u128 zig_make_u128(zig_minInt_u64, zig_minInt_u64)
2081#define zig_maxInt_u128 zig_make_u128(zig_maxInt_u64, zig_maxInt_u64)
2082#define zig_minInt_i128 zig_make_i128(zig_minInt_i64, zig_minInt_u64)
2083#define zig_maxInt_i128 zig_make_i128(zig_maxInt_i64, zig_maxInt_u64)
2084
2085zig_cmp_int128(u128)
2086zig_cmp_int128(i128)
2087
2088zig_bit_int128(u128, and, &)
2089zig_bit_int128(i128, and, &)
2090
2091zig_bit_int128(u128, or, |)
2092zig_bit_int128(i128, or, |)
2093
2094zig_bit_int128(u128, xor, ^)
2095zig_bit_int128(i128, xor, ^)
2096
2097static inline uint8_t zig_u8_intCast_u128(zig_u128 arg) {
2098 return (uint8_t)zig_lo_u128(arg);
2099}
2100static inline uint8_t zig_u8_intCast_i128(zig_i128 arg) {
2101 return (uint8_t)zig_lo_i128(arg);
2102}
2103static inline int8_t zig_i8_intCast_i128(zig_i128 arg) {
2104 return (int8_t)zig_lo_i128(arg);
2105}
2106static inline int8_t zig_i8_intCast_u128(zig_u128 arg) {
2107 return (int8_t)zig_lo_u128(arg);
2108}
2109
2110static inline uint16_t zig_u16_intCast_u128(zig_u128 arg) {
2111 return (uint16_t)zig_lo_u128(arg);
2112}
2113static inline uint16_t zig_u16_intCast_i128(zig_i128 arg) {
2114 return (uint16_t)zig_lo_i128(arg);
2115}
2116static inline int16_t zig_i16_intCast_i128(zig_i128 arg) {
2117 return (int16_t)zig_lo_i128(arg);
2118}
2119static inline int16_t zig_i16_intCast_u128(zig_u128 arg) {
2120 return (int16_t)zig_lo_u128(arg);
2121}
2122
2123static inline uint32_t zig_u32_intCast_u128(zig_u128 arg) {
2124 return (uint32_t)zig_lo_u128(arg);
2125}
2126static inline uint32_t zig_u32_intCast_i128(zig_i128 arg) {
2127 return (uint32_t)zig_lo_i128(arg);
2128}
2129static inline int32_t zig_i32_intCast_i128(zig_i128 arg) {
2130 return (int32_t)zig_lo_i128(arg);
2131}
2132static inline int32_t zig_i32_intCast_u128(zig_u128 arg) {
2133 return (int32_t)zig_lo_u128(arg);
2134}
2135
2136static inline uint64_t zig_u64_intCast_u128(zig_u128 arg) {
2137 return zig_lo_u128(arg);
2138}
2139static inline uint64_t zig_u64_intCast_i128(zig_i128 arg) {
2140 return zig_lo_i128(arg);
2141}
2142static inline int64_t zig_i64_intCast_i128(zig_i128 arg) {
2143 return (int64_t)zig_lo_i128(arg);
2144}
2145static inline int64_t zig_i64_intCast_u128(zig_u128 arg) {
2146 return (int64_t)zig_lo_u128(arg);
2147}
2148
2149static inline zig_u128 zig_u128_intCast_u8(uint8_t arg) {
2150 return zig_make_u128(UINT8_C(0), arg);
2151}
2152static inline zig_u128 zig_u128_intCast_i8(int8_t arg) {
2153 return zig_make_u128(UINT8_C(0), (uint8_t)arg);
2154}
2155static inline zig_i128 zig_i128_intCast_i8(int8_t arg) {
2156 return zig_make_i128(zig_shr_i64(arg, 63), (uint8_t)arg);
2157}
2158static inline zig_i128 zig_i128_intCast_u8(uint8_t arg) {
2159 return zig_make_i128(INT8_C(0), arg);
2160}
2161
2162static inline zig_u128 zig_u128_intCast_u16(uint16_t arg) {
2163 return zig_make_u128(UINT16_C(0), arg);
2164}
2165static inline zig_u128 zig_u128_intCast_i16(int16_t arg) {
2166 return zig_make_u128(UINT16_C(0), (uint16_t)arg);
2167}
2168static inline zig_i128 zig_i128_intCast_i16(int16_t arg) {
2169 return zig_make_i128(zig_shr_i64(arg, 63), (uint16_t)arg);
2170}
2171static inline zig_i128 zig_i128_intCast_u16(uint16_t arg) {
2172 return zig_make_i128(INT16_C(0), arg);
2173}
2174
2175static inline zig_u128 zig_u128_intCast_u32(uint32_t arg) {
2176 return zig_make_u128(UINT32_C(0), arg);
2177}
2178static inline zig_u128 zig_u128_intCast_i32(int32_t arg) {
2179 return zig_make_u128(UINT32_C(0), (uint32_t)arg);
2180}
2181static inline zig_i128 zig_i128_intCast_i32(int32_t arg) {
2182 return zig_make_i128(zig_shr_i64(arg, 63), (uint32_t)arg);
2183}
2184static inline zig_i128 zig_i128_intCast_u32(uint32_t arg) {
2185 return zig_make_i128(INT32_C(0), arg);
2186}
2187
2188static inline zig_u128 zig_u128_intCast_u64(uint64_t arg) {
2189 return zig_make_u128(UINT64_C(0), arg);
2190}
2191static inline zig_u128 zig_u128_intCast_i64(int64_t arg) {
2192 return zig_make_u128(UINT64_C(0), (uint64_t)arg);
2193}
2194static inline zig_i128 zig_i128_intCast_i64(int64_t arg) {
2195 return zig_make_i128(zig_shr_i64(arg, 63), (uint64_t)arg);
2196}
2197static inline zig_i128 zig_i128_intCast_u64(uint64_t arg) {
2198 return zig_make_i128(INT64_C(0), arg);
2199}
2200
2201static inline zig_u128 zig_u128_intCast_u128(zig_u128 arg) {
2202 return arg;
2203}
2204static inline zig_u128 zig_u128_intCast_i128(zig_i128 arg) {
2205#if zig_has_int128
2206 return (zig_u128)arg;
2207#else
2208 return zig_make_u128(zig_u64_bitCast_i64(zig_hi_i128(arg), UINT8_C(64)), zig_lo_u128(arg));
2209#endif
2210}
2211static inline zig_i128 zig_i128_intCast_i128(zig_i128 arg) {
2212 return arg;
2213}
2214static inline zig_i128 zig_i128_intCast_u128(zig_u128 arg) {
2215#if zig_has_int128
2216 return (zig_i128)arg;
2217#else
2218 return zig_make_i128(zig_i64_bitCast_u64(zig_hi_i128(arg), UINT8_C(64)), zig_lo_u128(arg));
2219#endif
2220}
2221
2222#define zig_int128_cast_builtins(w) \
2223 static inline uint##w##_t zig_u##w##_truncate_u128(zig_u128 arg, uint8_t bits) { \
2224 return zig_u##w##_truncate_u##w((uint##w##_t)zig_lo_u128(arg), bits); \
2225 } \
2226\
2227 static inline int##w##_t zig_i##w##_truncate_i128(zig_i128 arg, uint8_t bits) { \
2228 return zig_i##w##_truncate_i##w((int##w##_t)zig_lo_i128(arg), bits); \
2229 }
2230zig_int128_cast_builtins(8)
2231zig_int128_cast_builtins(16)
2232zig_int128_cast_builtins(32)
2233zig_int128_cast_builtins(64)
2234
2235static inline zig_u128 zig_u128_truncate_u128(zig_u128 arg, uint8_t bits) {
2236 return zig_and_u128(arg, zig_maxInt_u(128, bits));
2237}
2238static inline zig_i128 zig_i128_truncate_i128(zig_i128 arg, uint8_t bits) {
2239 if (bits > UINT8_C(64)) return zig_make_i128(zig_i64_truncate_i64(zig_hi_i128(arg), bits - UINT8_C(64)), zig_lo_i128(arg));
2240 int64_t lo = zig_i64_truncate_i128(arg, bits);
2241 return zig_make_i128(zig_shr_i64(lo, 63), (uint64_t)lo);
2242}
2243
2244static inline zig_u128 zig_u128_bitCast_u128(zig_u128 arg, uint8_t bits) {
2245 (void)bits;
2246 return arg;
2247}
2248static inline zig_u128 zig_u128_bitCast_i128(zig_i128 arg, uint8_t bits) {
2249 return zig_u128_truncate_u128(zig_u128_intCast_i128(arg), bits);
2250}
2251static inline zig_i128 zig_i128_bitCast_i128(zig_i128 arg, uint8_t bits) {
2252 (void)bits;
2253 return arg;
2254}
2255static inline zig_i128 zig_i128_bitCast_u128(zig_u128 arg, uint8_t bits) {
2256 return zig_i128_truncate_i128(zig_i128_intCast_u128(arg), bits);
2257}
2258
2259#if zig_has_int128
2260
2261static inline zig_u128 zig_not_u128(zig_u128 arg, uint8_t bits) {
2262 return arg ^ zig_maxInt_u(128, bits);
2263}
2264
2265static inline zig_i128 zig_not_i128(zig_i128 arg, uint8_t bits) {
2266 (void)bits;
2267 return ~arg;
2268}
2269
2270static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) {
2271 return lhs + rhs;
2272}
2273
2274static inline zig_i128 zig_add_i128(zig_i128 lhs, zig_i128 rhs) {
2275 return lhs + rhs;
2276}
2277
2278static inline zig_u128 zig_sub_u128(zig_u128 lhs, zig_u128 rhs) {
2279 return lhs - rhs;
2280}
2281
2282static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {
2283 return lhs - rhs;
2284}
2285
2286static inline zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {
2287 return lhs * rhs;
2288}
2289
2290static inline zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {
2291 return lhs * rhs;
2292}
2293
2294static inline zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) {
2295 return lhs / rhs;
2296}
2297
2298static inline zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) {
2299 return lhs / rhs;
2300}
2301
2302static inline zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) {
2303 return lhs % rhs;
2304}
2305
2306static inline zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) {
2307 return lhs % rhs;
2308}
2309
2310#else /* zig_has_int128 */
2311
2312static inline zig_u128 zig_not_u128(zig_u128 arg, uint8_t bits) {
2313 if (bits <= UINT8_C(64)) return (zig_u128){ .hi = UINT64_C(0), .lo = zig_not_u64(arg.lo, bits) };
2314 return (zig_u128){ .hi = zig_not_u64(arg.hi, bits - UINT8_C(64)), .lo = zig_not_u64(arg.lo, UINT8_C(64)) };
2315}
2316
2317static inline zig_i128 zig_not_i128(zig_i128 arg, uint8_t bits) {
2318 (void)bits;
2319 return (zig_i128){ .hi = ~arg.hi, .lo = ~arg.lo };
2320}
2321
2322static inline zig_u128 zig_add_u128(zig_u128 lhs, zig_u128 rhs) {
2323 zig_u128 res;
2324 res.hi = lhs.hi + rhs.hi + zig_addo_u64(&res.lo, lhs.lo, rhs.lo, 64);
2325 return res;
2326}
2327
2328static inline zig_i128 zig_add_i128(zig_i128 lhs, zig_i128 rhs) {
2329 zig_i128 res;
2330 res.hi = lhs.hi + rhs.hi + zig_addo_u64(&res.lo, lhs.lo, rhs.lo, 64);
2331 return res;
2332}
2333
2334static inline zig_u128 zig_sub_u128(zig_u128 lhs, zig_u128 rhs) {
2335 zig_u128 res;
2336 res.hi = lhs.hi - rhs.hi - zig_subo_u64(&res.lo, lhs.lo, rhs.lo, 64);
2337 return res;
2338}
2339
2340static inline zig_i128 zig_sub_i128(zig_i128 lhs, zig_i128 rhs) {
2341 zig_i128 res;
2342 res.hi = lhs.hi - rhs.hi - zig_subo_u64(&res.lo, lhs.lo, rhs.lo, 64);
2343 return res;
2344}
2345
2346static zig_i128 zig_mul_i128(zig_i128 lhs, zig_i128 rhs) {
2347 zig_extern zig_i128 __multi3(zig_i128 lhs, zig_i128 rhs);
2348 return __multi3(lhs, rhs);
2349}
2350
2351static zig_u128 zig_mul_u128(zig_u128 lhs, zig_u128 rhs) {
2352 return zig_u128_bitCast_i128(zig_mul_i128(zig_i128_bitCast_u128(lhs, UINT8_C(128)), zig_i128_bitCast_u128(rhs, UINT8_C(128))), UINT8_C(128));
2353}
2354
2355static zig_u128 zig_divTrunc_u128(zig_u128 lhs, zig_u128 rhs) {
2356 zig_extern zig_u128 __udivti3(zig_u128 lhs, zig_u128 rhs);
2357 return __udivti3(lhs, rhs);
2358}
2359
2360static zig_i128 zig_divTrunc_i128(zig_i128 lhs, zig_i128 rhs) {
2361 zig_extern zig_i128 __divti3(zig_i128 lhs, zig_i128 rhs);
2362 return __divti3(lhs, rhs);
2363}
2364
2365static zig_u128 zig_rem_u128(zig_u128 lhs, zig_u128 rhs) {
2366 zig_extern zig_u128 __umodti3(zig_u128 lhs, zig_u128 rhs);
2367 return __umodti3(lhs, rhs);
2368}
2369
2370static zig_i128 zig_rem_i128(zig_i128 lhs, zig_i128 rhs) {
2371 zig_extern zig_i128 __modti3(zig_i128 lhs, zig_i128 rhs);
2372 return __modti3(lhs, rhs);
2373}
2374
2375#endif /* zig_has_int128 */
2376
2377#define zig_divFloor_u128 zig_divTrunc_u128
2378
2379static inline zig_i128 zig_divFloor_i128(zig_i128 lhs, zig_i128 rhs) {
2380 zig_i128 rem = zig_rem_i128(lhs, rhs);
2381 int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0)
2382 ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) : INT64_C(0);
2383 return zig_add_i128(zig_divTrunc_i128(lhs, rhs), zig_make_i128(mask, (uint64_t)mask));
2384}
2385
2386static inline zig_u128 zig_divCeil_u128(zig_u128 lhs, zig_u128 rhs) {
2387 zig_u128 rem = zig_rem_u128(lhs, rhs);
2388 uint64_t mask = zig_or_u64(zig_hi_u128(rem), zig_lo_u128(rem)) != UINT64_C(0)
2389 ? UINT64_C(1) : UINT64_C(0);
2390 return zig_add_u128(zig_divTrunc_u128(lhs, rhs), zig_make_u128(UINT64_C(0), mask));
2391}
2392
2393static inline zig_i128 zig_divCeil_i128(zig_i128 lhs, zig_i128 rhs) {
2394 zig_i128 rem = zig_rem_i128(lhs, rhs);
2395 int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0)
2396 ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) + INT64_C(1)
2397 : INT64_C(0);
2398 return zig_add_i128(zig_divTrunc_i128(lhs, rhs), zig_make_i128(INT64_C(0), (uint64_t)mask));
2399}
2400
2401#define zig_mod_u128 zig_rem_u128
2402
2403static inline zig_i128 zig_mod_i128(zig_i128 lhs, zig_i128 rhs) {
2404 zig_i128 rem = zig_rem_i128(lhs, rhs);
2405 int64_t mask = zig_or_u64((uint64_t)zig_hi_i128(rem), zig_lo_i128(rem)) != UINT64_C(0)
2406 ? zig_shr_i64(zig_xor_i64(zig_hi_i128(lhs), zig_hi_i128(rhs)), UINT8_C(63)) : INT64_C(0);
2407 return zig_add_i128(rem, zig_and_i128(rhs, zig_make_i128(mask, (uint64_t)mask)));
2408}
2409
2410static inline zig_u128 zig_min_u128(zig_u128 lhs, zig_u128 rhs) {
2411 return zig_cmp_u128(lhs, rhs) < INT32_C(0) ? lhs : rhs;
2412}
2413
2414static inline zig_i128 zig_min_i128(zig_i128 lhs, zig_i128 rhs) {
2415 return zig_cmp_i128(lhs, rhs) < INT32_C(0) ? lhs : rhs;
2416}
2417
2418static inline zig_u128 zig_max_u128(zig_u128 lhs, zig_u128 rhs) {
2419 return zig_cmp_u128(lhs, rhs) > INT32_C(0) ? lhs : rhs;
2420}
2421
2422static inline zig_i128 zig_max_i128(zig_i128 lhs, zig_i128 rhs) {
2423 return zig_cmp_i128(lhs, rhs) > INT32_C(0) ? lhs : rhs;
2424}
2425
2426static inline zig_u128 zig_shlw_u128(zig_u128 lhs, uint8_t rhs, uint8_t bits) {
2427 return zig_u128_truncate_u128(zig_shl_u128(lhs, rhs), bits);
2428}
2429
2430static inline zig_i128 zig_shlw_i128(zig_i128 lhs, uint8_t rhs, uint8_t bits) {
2431 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_shl_u128(zig_u128_bitCast_i128(lhs, bits), rhs), bits), bits);
2432}
2433
2434static inline zig_u128 zig_addw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2435 return zig_u128_truncate_u128(zig_add_u128(lhs, rhs), bits);
2436}
2437
2438static inline zig_i128 zig_addw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2439 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_add_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits);
2440}
2441
2442static inline zig_u128 zig_subw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2443 return zig_u128_truncate_u128(zig_sub_u128(lhs, rhs), bits);
2444}
2445
2446static inline zig_i128 zig_subw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2447 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_sub_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits);
2448}
2449
2450static inline zig_u128 zig_mulw_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2451 return zig_u128_truncate_u128(zig_mul_u128(lhs, rhs), bits);
2452}
2453
2454static inline zig_i128 zig_mulw_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2455 return zig_i128_truncate_i128(zig_i128_bitCast_u128(zig_mul_u128(zig_u128_bitCast_i128(lhs, bits), zig_u128_bitCast_i128(rhs, bits)), bits), bits);
2456}
2457
2458static inline zig_u128 zig_abs_i128(zig_i128 arg) {
2459 zig_u128 tmp = zig_u128_bitCast_i128(zig_shr_i128(arg, 127), UINT8_C(128));
2460 return zig_sub_u128(zig_xor_u128(zig_u128_bitCast_i128(arg, UINT8_C(128)), tmp), tmp);
2461}
2462
2463#if zig_has_int128
2464
2465static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2466#if zig_has_builtin(add_overflow)
2467 zig_u128 full_res;
2468 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
2469 *res = zig_u128_truncate_u128(full_res, bits);
2470 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);
2471#else
2472 *res = zig_addw_u128(lhs, rhs, bits);
2473 return *res < lhs;
2474#endif
2475}
2476
2477static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2478#if zig_has_builtin(add_overflow)
2479 zig_i128 full_res;
2480 bool overflow = __builtin_add_overflow(lhs, rhs, &full_res);
2481#else
2482 zig_i128 full_res = (zig_i128)((zig_u128)lhs + (zig_u128)rhs);
2483 bool overflow = ((full_res ^ lhs) & (full_res ^ rhs)) < 0;
2484#endif
2485 *res = zig_i128_truncate_i128(full_res, bits);
2486 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);
2487}
2488
2489static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2490#if zig_has_builtin(sub_overflow)
2491 zig_u128 full_res;
2492 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
2493 *res = zig_u128_truncate_u128(full_res, bits);
2494 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);
2495#else
2496 *res = zig_subw_u128(lhs, rhs, bits);
2497 return *res > lhs;
2498#endif
2499}
2500
2501static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2502#if zig_has_builtin(sub_overflow)
2503 zig_i128 full_res;
2504 bool overflow = __builtin_sub_overflow(lhs, rhs, &full_res);
2505#else
2506 zig_i128 full_res = (zig_i128)((zig_u128)lhs - (zig_u128)rhs);
2507 bool overflow = ((lhs ^ rhs) & (full_res ^ lhs)) < 0;
2508#endif
2509 *res = zig_i128_truncate_i128(full_res, bits);
2510 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);
2511}
2512
2513static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2514#if zig_has_builtin(mul_overflow)
2515 zig_u128 full_res;
2516 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
2517 *res = zig_u128_truncate_u128(full_res, bits);
2518 return overflow || full_res < zig_minInt_u(128, bits) || full_res > zig_maxInt_u(128, bits);
2519#else
2520 *res = zig_mulw_u128(lhs, rhs, bits);
2521 return rhs != zig_make_u128(0, 0) && lhs > zig_maxInt_u(128, bits) / rhs;
2522#endif
2523}
2524
2525static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2526 zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
2527#if zig_has_builtin(mul_overflow)
2528 zig_i128 full_res;
2529 bool overflow = __builtin_mul_overflow(lhs, rhs, &full_res);
2530#else
2531 int overflow_int;
2532 zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);
2533 bool overflow = overflow_int != 0;
2534#endif
2535 *res = zig_i128_truncate_i128(full_res, bits);
2536 return overflow || full_res < zig_minInt_i(128, bits) || full_res > zig_maxInt_i(128, bits);
2537}
2538
2539#else /* zig_has_int128 */
2540
2541static inline bool zig_addo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2542 if (bits <= UINT8_C(64)) {
2543 uint64_t lo;
2544 bool overflow = zig_addo_u64(&lo, zig_u64_intCast_u128(lhs), zig_u64_intCast_u128(rhs), bits);
2545 *res = zig_u128_intCast_u64(lo);
2546 return overflow;
2547 } else {
2548 uint64_t hi;
2549 bool overflow = zig_addo_u64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2550 return overflow ^ zig_addo_u64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2551 }
2552}
2553
2554static inline bool zig_addo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2555 if (bits <= UINT8_C(64)) {
2556 int64_t lo;
2557 bool overflow = zig_addo_i64(&lo, zig_i64_intCast_i128(lhs), zig_i64_intCast_i128(rhs), bits);
2558 *res = zig_i128_intCast_i64(lo);
2559 return overflow;
2560 } else {
2561 int64_t hi;
2562 bool overflow = zig_addo_i64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2563 return overflow ^ zig_addo_i64(&res->hi, hi, zig_addo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2564 }
2565}
2566
2567static inline bool zig_subo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2568 if (bits <= UINT8_C(64)) {
2569 uint64_t lo;
2570 bool overflow = zig_subo_u64(&lo, zig_u64_intCast_u128(lhs), zig_u64_intCast_u128(rhs), bits);
2571 *res = zig_u128_intCast_u64(lo);
2572 return overflow;
2573 } else {
2574 uint64_t hi;
2575 bool overflow = zig_subo_u64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2576 return overflow ^ zig_subo_u64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2577 }
2578}
2579
2580static inline bool zig_subo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2581 if (bits <= UINT8_C(64)) {
2582 int64_t lo;
2583 bool overflow = zig_subo_i64(&lo, zig_i64_intCast_i128(lhs), zig_i64_intCast_i128(rhs), bits);
2584 *res = zig_i128_intCast_i64(lo);
2585 return overflow;
2586 } else {
2587 int64_t hi;
2588 bool overflow = zig_subo_i64(&hi, lhs.hi, rhs.hi, bits - UINT8_C(64));
2589 return overflow ^ zig_subo_i64(&res->hi, hi, zig_subo_u64(&res->lo, lhs.lo, rhs.lo, UINT8_C(64)), bits - UINT8_C(64));
2590 }
2591}
2592
2593static inline bool zig_mulo_u128(zig_u128 *res, zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2594 *res = zig_mulw_u128(lhs, rhs, bits);
2595 return zig_cmp_u128(rhs, zig_make_u128(0, 0)) != INT32_C(0) &&
2596 zig_cmp_u128(lhs, zig_divTrunc_u128(zig_maxInt_u(128, bits), rhs)) > INT32_C(0);
2597}
2598
2599static inline bool zig_mulo_i128(zig_i128 *res, zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2600 zig_extern zig_i128 __muloti4(zig_i128 lhs, zig_i128 rhs, int *overflow);
2601 int overflow_int;
2602 zig_i128 full_res = __muloti4(lhs, rhs, &overflow_int);
2603 bool overflow = overflow_int != 0 ||
2604 zig_cmp_i128(full_res, zig_minInt_i(128, bits)) < INT32_C(0) ||
2605 zig_cmp_i128(full_res, zig_maxInt_i(128, bits)) > INT32_C(0);
2606 *res = zig_i128_truncate_i128(full_res, bits);
2607 return overflow;
2608}
2609
2610#endif /* zig_has_int128 */
2611
2612static inline bool zig_shlo_u128(zig_u128 *res, zig_u128 lhs, uint8_t rhs, uint8_t bits) {
2613 *res = zig_shlw_u128(lhs, rhs, bits);
2614 return zig_cmp_u128(lhs, zig_shr_u128(zig_maxInt_u(128, bits), rhs)) > INT32_C(0);
2615}
2616
2617static inline bool zig_shlo_i128(zig_i128 *res, zig_i128 lhs, uint8_t rhs, uint8_t bits) {
2618 *res = zig_shlw_i128(lhs, rhs, bits);
2619 zig_i128 mask = zig_i128_bitCast_u128(zig_shl_u128(zig_maxInt_u128, bits - rhs - UINT8_C(1)), bits);
2620 return zig_cmp_i128(zig_and_i128(lhs, mask), zig_make_i128(0, 0)) != INT32_C(0) &&
2621 zig_cmp_i128(zig_and_i128(lhs, mask), mask) != INT32_C(0);
2622}
2623
2624#define zig_int128_shls_builtins(rw) \
2625 static inline zig_u128 zig_shls_u128_u##rw(zig_u128 lhs, uint##rw##_t rhs, uint8_t bits) { \
2626 zig_u128 res; \
2627 if (rhs < bits && !zig_shlo_u128(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
2628 switch (zig_cmp_u128(lhs, zig_make_u128(UINT64_C(0), UINT64_C(0)))) { \
2629 case 0: return zig_minInt_u(128, bits); \
2630 case 1: return zig_maxInt_u(128, bits); \
2631 default: zig_unreachable(); \
2632 } \
2633 } \
2634\
2635 static inline zig_i128 zig_shls_i128_u##rw(zig_i128 lhs, uint##rw##_t rhs, uint8_t bits) { \
2636 zig_i128 res; \
2637 if (rhs < bits && !zig_shlo_i128(&res, lhs, zig_u8_intCast_u##rw(rhs), bits)) return res; \
2638 switch (zig_cmp_i128(lhs, zig_make_i128(INT64_C(0), UINT64_C(0)))) { \
2639 case -1: return zig_minInt_i(128, bits); \
2640 case 0: return zig_make_i128(INT64_C(0), UINT64_C(0)); \
2641 case 1: return zig_maxInt_i(128, bits); \
2642 default: zig_unreachable(); \
2643 } \
2644 }
2645zig_int128_shls_builtins(8)
2646zig_int128_shls_builtins(16)
2647zig_int128_shls_builtins(32)
2648zig_int128_shls_builtins(64)
2649
2650static inline zig_u128 zig_shls_u128_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2651 zig_u128 res;
2652 if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_u128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res;
2653 switch (zig_cmp_u128(lhs, zig_make_u128(0, 0))) {
2654 case INT32_C(0): return zig_make_u128(0, 0);
2655 case INT32_C(1): return zig_maxInt_u(128, bits);
2656 default: zig_unreachable();
2657 }
2658}
2659
2660static inline zig_i128 zig_shls_i128_u128(zig_i128 lhs, zig_u128 rhs, uint8_t bits) {
2661 zig_i128 res;
2662 if (zig_cmp_u128(rhs, zig_make_u128(0, bits)) < INT32_C(0) && !zig_shlo_i128(&res, lhs, (uint8_t)zig_lo_u128(rhs), bits)) return res;
2663 switch (zig_cmp_i128(lhs, zig_make_i128(0, 0))) {
2664 case -INT32_C(1): return zig_minInt_i(128, bits);
2665 case INT32_C(0): return zig_make_i128(0, 0);
2666 case INT32_C(1): return zig_maxInt_i(128, bits);
2667 default: zig_unreachable();
2668 }
2669}
2670
2671static inline zig_u128 zig_adds_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2672 zig_u128 res;
2673 return zig_addo_u128(&res, lhs, rhs, bits) ? zig_maxInt_u(128, bits) : res;
2674}
2675
2676static inline zig_i128 zig_adds_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2677 zig_i128 res;
2678 if (!zig_addo_i128(&res, lhs, rhs, bits)) return res;
2679 return zig_cmp_i128(res, zig_make_i128(0, 0)) >= INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);
2680}
2681
2682static inline zig_u128 zig_subs_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2683 zig_u128 res;
2684 return zig_subo_u128(&res, lhs, rhs, bits) ? zig_minInt_u(128, bits) : res;
2685}
2686
2687static inline zig_i128 zig_subs_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2688 zig_i128 res;
2689 if (!zig_subo_i128(&res, lhs, rhs, bits)) return res;
2690 return zig_cmp_i128(res, zig_make_i128(0, 0)) >= INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);
2691}
2692
2693static inline zig_u128 zig_muls_u128(zig_u128 lhs, zig_u128 rhs, uint8_t bits) {
2694 zig_u128 res;
2695 return zig_mulo_u128(&res, lhs, rhs, bits) ? zig_maxInt_u(128, bits) : res;
2696}
2697
2698static inline zig_i128 zig_muls_i128(zig_i128 lhs, zig_i128 rhs, uint8_t bits) {
2699 zig_i128 res;
2700 if (!zig_mulo_i128(&res, lhs, rhs, bits)) return res;
2701 return zig_cmp_i128(zig_xor_i128(lhs, rhs), zig_make_i128(0, 0)) < INT32_C(0) ? zig_minInt_i(128, bits) : zig_maxInt_i(128, bits);
2702}
2703
2704static inline uint8_t zig_clz_u128(zig_u128 arg, uint8_t bits) {
2705 if (bits <= UINT8_C(64)) return zig_clz_u64(zig_lo_u128(arg), bits);
2706 if (zig_hi_u128(arg) != 0) return zig_clz_u64(zig_hi_u128(arg), bits - UINT8_C(64));
2707 return zig_clz_u64(zig_lo_u128(arg), UINT8_C(64)) + (bits - UINT8_C(64));
2708}
2709
2710static inline uint8_t zig_clz_i128(zig_i128 arg, uint8_t bits) {
2711 return zig_clz_u128(zig_u128_bitCast_i128(arg, bits), bits);
2712}
2713
2714static inline uint8_t zig_ctz_u128(zig_u128 arg, uint8_t bits) {
2715 if (zig_lo_u128(arg) != 0) return zig_ctz_u64(zig_lo_u128(arg), UINT8_C(64));
2716 return zig_ctz_u64(zig_hi_u128(arg), bits - UINT8_C(64)) + UINT8_C(64);
2717}
2718
2719static inline uint8_t zig_ctz_i128(zig_i128 arg, uint8_t bits) {
2720 return zig_ctz_u128(zig_u128_bitCast_i128(arg, bits), bits);
2721}
2722
2723static inline uint8_t zig_popCount_u128(zig_u128 arg, uint8_t bits) {
2724 return (bits > UINT8_C(64) ? zig_popCount_u64(zig_hi_u128(arg), bits - UINT8_C(64)) : UINT8_C(0)) +
2725 zig_popCount_u64(zig_lo_u128(arg), UINT8_C(64));
2726}
2727
2728static inline uint8_t zig_popCount_i128(zig_i128 arg, uint8_t bits) {
2729 return zig_popCount_u128(zig_u128_bitCast_i128(arg, bits), bits);
2730}
2731
2732static inline zig_u128 zig_byteSwap_u128(zig_u128 arg, uint8_t bits) {
2733 zig_u128 full_res;
2734#if zig_has_builtin(bswap128)
2735 full_res = __builtin_bswap128(arg);
2736#else
2737 full_res = zig_make_u128(
2738 zig_byteSwap_u64(zig_lo_u128(arg), UINT8_C(64)),
2739 zig_byteSwap_u64(zig_hi_u128(arg), UINT8_C(64))
2740 );
2741#endif
2742 return zig_shr_u128(full_res, UINT8_C(128) - bits);
2743}
2744
2745static inline zig_i128 zig_byteSwap_i128(zig_i128 arg, uint8_t bits) {
2746 return zig_i128_bitCast_u128(zig_byteSwap_u128(zig_u128_bitCast_i128(arg, bits), bits), bits);
2747}
2748
2749static inline zig_u128 zig_bitReverse_u128(zig_u128 arg, uint8_t bits) {
2750 return zig_shr_u128(zig_make_u128(
2751 zig_bitReverse_u64(zig_lo_u128(arg), UINT8_C(64)),
2752 zig_bitReverse_u64(zig_hi_u128(arg), UINT8_C(64))
2753 ), UINT8_C(128) - bits);
2754}
2755
2756static inline zig_i128 zig_bitReverse_i128(zig_i128 arg, uint8_t bits) {
2757 return zig_i128_bitCast_u128(zig_bitReverse_u128(zig_u128_bitCast_i128(arg, bits), bits), bits);
2758}
2759
2760#if zig_has_int128
2761#define zig_switch_int128(operand) switch (operand)
2762#define zig_switch_prong_begin_int128()
2763#define zig_switch_case_int128(Type, operand, value) case value:
2764#define zig_switch_prong_end_int128()
2765#define zig_switch_default_int128() default:
2766#else // zig_has_int128
2767#define zig_switch_int128(operand)
2768#define zig_switch_prong_begin_int128() if (0
2769#define zig_switch_case_int128(Type, operand, value) || (zig_cmp_##Type(operand, value) == 0)
2770#define zig_switch_prong_end_int128() )
2771#define zig_switch_default_int128()
2772#endif // zig_has_int128
2773
2774/* ========================== Big Integer Support =========================== */
2775
2776static inline uint16_t zig_int_bytes(uint16_t bits) {
2777 uint16_t bytes = (bits - UINT16_C(1)) / CHAR_BIT + UINT16_C(1);
2778 uint16_t alignment = ZIG_TARGET_MAX_INT_ALIGNMENT;
2779
2780 while (alignment / 2 >= bytes) alignment /= 2;
2781 return (bytes + alignment - 1) / alignment * alignment;
2782}
2783
2784static inline void zig_minInt_big(void *res, bool is_signed, uint16_t bits) {
2785 uint8_t *res_bytes = res;
2786 uint16_t size = zig_int_bytes(bits);
2787 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3));
2788 uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1);
2789 uint8_t sign_byte;
2790 uint8_t fill_byte;
2791
2792 if (is_signed) {
2793 int8_t signed_sign_byte = zig_minInt_i(8, remainder_bits);
2794
2795 sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8));
2796 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8));
2797 } else {
2798 sign_byte = zig_minInt_u(8, remainder_bits);
2799 fill_byte = UINT8_C(0);
2800 }
2801
2802#if zig_little_endian
2803 memset(&res_bytes[0], zig_minInt_u8, byte_offset);
2804 res_bytes[byte_offset] = sign_byte;
2805 byte_offset += UINT16_C(1);
2806 memset(&res_bytes[byte_offset], fill_byte, size - byte_offset);
2807#else
2808 byte_offset = size - UINT16_C(1) - byte_offset;
2809 memset(&res_bytes[0], fill_byte, byte_offset);
2810 res_bytes[byte_offset] = sign_byte;
2811 byte_offset += UINT16_C(1);
2812 memset(&res_bytes[byte_offset], zig_minInt_u8, size - byte_offset);
2813#endif
2814}
2815
2816static inline void zig_maxInt_big(void *res, bool is_signed, uint16_t bits) {
2817 uint8_t *res_bytes = res;
2818 uint16_t size = zig_int_bytes(bits);
2819 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3));
2820 uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1);
2821 uint8_t sign_byte;
2822 uint8_t fill_byte;
2823
2824 if (is_signed) {
2825 int8_t signed_sign_byte = zig_maxInt_i(8, remainder_bits);
2826
2827 sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8));
2828 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8));
2829 } else {
2830 sign_byte = zig_maxInt_u(8, remainder_bits);
2831 fill_byte = UINT8_C(0);
2832 }
2833
2834#if zig_little_endian
2835 memset(&res_bytes[0], zig_maxInt_u8, byte_offset);
2836 res_bytes[byte_offset] = sign_byte;
2837 byte_offset += UINT16_C(1);
2838 memset(&res_bytes[byte_offset], fill_byte, size - byte_offset);
2839#else
2840 byte_offset = size - UINT16_C(1) - byte_offset;
2841 memset(&res_bytes[0], fill_byte, byte_offset);
2842 res_bytes[byte_offset] = sign_byte;
2843 byte_offset += UINT16_C(1);
2844 memset(&res_bytes[byte_offset], zig_maxInt_u8, size - byte_offset);
2845#endif
2846}
2847
2848static inline int8_t zig_signFill_big(const void *arg, bool is_signed, uint16_t bits) {
2849 const uint8_t *arg_bytes = arg;
2850 uint16_t byte_offset = 0;
2851
2852 if (!is_signed) return INT8_C(0);
2853#if zig_little_endian
2854 byte_offset = zig_int_bytes(bits) - 1;
2855#endif
2856 return zig_shr_i8(zig_i8_bitCast_u8(arg_bytes[byte_offset], UINT8_C(8)), UINT8_C(7));
2857}
2858
2859static inline void zig_big_intCast_big(void *res, const void *arg, bool res_is_signed, uint16_t res_bits, bool arg_is_signed, uint16_t arg_bits) {
2860 uint8_t *res_bytes = res;
2861 const uint8_t *arg_bytes = arg;
2862 uint16_t res_size = zig_int_bytes(res_bits);
2863 uint16_t arg_size = zig_int_bytes(arg_bits);
2864 uint16_t copy_size = zig_min_u16(res_size, arg_size);
2865 uint8_t sign_fill = zig_u8_bitCast_i8(zig_signFill_big(arg, arg_is_signed, arg_bits), UINT8_C(8));
2866
2867#if zig_little_endian
2868 memcpy(&res_bytes[0], &arg_bytes[0], copy_size);
2869 memset(&res_bytes[copy_size], sign_fill, res_size - copy_size);
2870#else
2871 memset(&res_bytes[0], sign_fill, res_size - copy_size);
2872 memcpy(&res_bytes[res_size - copy_size], &arg_bytes[arg_size - copy_size], copy_size);
2873#endif
2874}
2875
2876static inline void zig_big_truncate_big(void *res, const void *arg, bool res_is_signed, uint16_t res_bits, bool arg_is_signed, uint16_t arg_bits) {
2877 uint8_t *res_bytes = res;
2878 const uint8_t *arg_bytes = arg;
2879 uint16_t res_size = zig_int_bytes(res_bits);
2880
2881 if (res_is_signed != arg_is_signed) zig_unreachable();
2882 if (res_bits > arg_bits) zig_unreachable();
2883
2884 if (res_is_signed) {
2885 uint16_t arg_byte_offset = UINT16_C(0);
2886
2887#if zig_big_endian
2888 arg_byte_offset = zig_int_bytes(arg_bits) - res_size;
2889#endif
2890
2891 memcpy(&res_bytes[0], &arg_bytes[arg_byte_offset], res_size);
2892 } else {
2893 uint16_t res_byte_offset = zig_shr_u16(res_bits - UINT16_C(1), UINT8_C(3));
2894 uint16_t arg_byte_offset = res_byte_offset;
2895
2896#if zig_little_endian
2897 memcpy(&res_bytes[0], &arg_bytes[0], res_byte_offset);
2898#else
2899 res_byte_offset = res_size - UINT16_C(1) - res_byte_offset;
2900 arg_byte_offset = zig_int_bytes(arg_bits) - UINT16_C(1) - arg_byte_offset;
2901
2902 memset(&res_bytes[0], zig_minInt_u8, res_byte_offset);
2903#endif
2904
2905 res_bytes[res_byte_offset] = zig_u8_truncate_u8(
2906 arg_bytes[arg_byte_offset],
2907 zig_u8_truncate_u8(res_bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1)
2908 );
2909 res_byte_offset += UINT16_C(1);
2910 arg_byte_offset += UINT16_C(1);
2911
2912#if zig_little_endian
2913 memset(&res_bytes[res_byte_offset], zig_minInt_u8, res_size - res_byte_offset);
2914#else
2915 memcpy(&res_bytes[res_byte_offset], &arg_bytes[arg_byte_offset], res_size - res_byte_offset);
2916#endif
2917 }
2918}
2919
2920#define zig_big_casts(is, s, w, IntType) \
2921 static inline IntType zig_##s##w##_intCast_big(const void *arg, bool arg_is_signed, uint16_t arg_bits) { \
2922 IntType res; \
2923 zig_big_intCast_big(&res, arg, is, w, arg_is_signed, arg_bits); \
2924 return res; \
2925 } \
2926\
2927 static inline void zig_big_intCast_##s##w(void *res, IntType arg, bool res_is_signed, uint16_t res_bits) { \
2928 zig_big_intCast_big(res, &arg, res_is_signed, res_bits, is, w); \
2929 } \
2930\
2931 static inline IntType zig_##s##w##_truncate_big(const void *arg, uint8_t res_bits, bool arg_is_signed, uint16_t arg_bits) { \
2932 IntType res; \
2933 zig_big_truncate_big(&res, arg, is, res_bits, arg_is_signed, arg_bits); \
2934 return res; \
2935 } \
2936\
2937 static inline void zig_big_truncate_##s##w(void *res, IntType arg, bool res_is_signed, uint16_t res_bits) { \
2938 zig_big_truncate_big(res, &arg, res_is_signed, res_bits, is, w); \
2939 }
2940zig_big_casts(false, u, 8, uint8_t)
2941zig_big_casts(true , i, 8, int8_t)
2942zig_big_casts(false, u, 16, uint16_t)
2943zig_big_casts(true , i, 16, int16_t)
2944zig_big_casts(false, u, 32, uint32_t)
2945zig_big_casts(true , i, 32, int32_t)
2946zig_big_casts(false, u, 64, uint64_t)
2947zig_big_casts(true , i, 64, int64_t)
2948zig_big_casts(false, u, 128, zig_u128)
2949zig_big_casts(true , i, 128, zig_i128)
2950
2951static inline void zig_big_bitCast_big(void *res, const void *arg, bool res_is_signed, uint16_t bits) {
2952 uint8_t *res_bytes = res;
2953 const uint8_t *arg_bytes = arg;
2954 uint16_t size = zig_int_bytes(bits);
2955 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3));
2956 uint16_t remainder_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1);
2957 uint8_t sign_byte;
2958 uint8_t fill_byte;
2959
2960#if zig_big_endian
2961 byte_offset = size - UINT16_C(1) - byte_offset;
2962#endif
2963
2964 if (res_is_signed) {
2965 int8_t signed_sign_byte = zig_i8_bitCast_u8(arg_bytes[byte_offset], remainder_bits);
2966
2967 sign_byte = zig_u8_bitCast_i8(signed_sign_byte, UINT8_C(8));
2968 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(signed_sign_byte, UINT8_C(7)), UINT8_C(8));
2969 } else {
2970 sign_byte = zig_u8_bitCast_u8(arg_bytes[byte_offset], remainder_bits);
2971 fill_byte = UINT8_C(0);
2972 }
2973
2974#if zig_little_endian
2975 memcpy(&res_bytes[0], &arg_bytes[0], byte_offset);
2976 res_bytes[byte_offset] = sign_byte;
2977 byte_offset += UINT16_C(1);
2978 memset(&res_bytes[byte_offset], fill_byte, size - byte_offset);
2979#else
2980 memset(&res_bytes[0], fill_byte, byte_offset);
2981 res_bytes[byte_offset] = sign_byte;
2982 byte_offset += UINT16_C(1);
2983 memcpy(&res_bytes[byte_offset], &arg_bytes[byte_offset], size - byte_offset);
2984#endif
2985}
2986
2987static inline int32_t zig_cmp_big_u8(const void *lhs, uint8_t rhs, bool is_signed, uint16_t bits) {
2988 const uint8_t *lhs_bytes = lhs;
2989 uint16_t byte_offset = 0;
2990 bool do_signed = is_signed;
2991 uint16_t remaining_bytes = zig_int_bytes(bits);
2992
2993#if zig_little_endian
2994 byte_offset = remaining_bytes;
2995#endif
2996
2997 while (remaining_bytes >= 128 / CHAR_BIT) {
2998 uint8_t rhs_byte = remaining_bytes == 128 / CHAR_BIT ? rhs : UINT8_C(0);
2999 int32_t limb_cmp;
3000
3001#if zig_little_endian
3002 byte_offset -= 128 / CHAR_BIT;
3003#endif
3004
3005 if (do_signed) {
3006 zig_i128 lhs_limb;
3007 zig_i128 rhs_limb = zig_i128_intCast_u8(rhs_byte);
3008
3009 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3010 limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb);
3011 do_signed = false;
3012 } else {
3013 zig_u128 lhs_limb;
3014 zig_u128 rhs_limb = zig_u128_intCast_u8(rhs_byte);
3015
3016 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3017 limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb);
3018 }
3019
3020 if (limb_cmp != 0) return limb_cmp;
3021 remaining_bytes -= 128 / CHAR_BIT;
3022
3023#if zig_big_endian
3024 byte_offset += 128 / CHAR_BIT;
3025#endif
3026 }
3027
3028 while (remaining_bytes >= 64 / CHAR_BIT) {
3029 uint8_t rhs_byte = remaining_bytes == 64 / CHAR_BIT ? rhs : UINT8_C(0);
3030
3031#if zig_little_endian
3032 byte_offset -= 64 / CHAR_BIT;
3033#endif
3034
3035 if (do_signed) {
3036 int64_t lhs_limb;
3037 int64_t rhs_limb = zig_i64_intCast_u8(rhs_byte);
3038
3039 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3040 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3041 do_signed = false;
3042 } else {
3043 uint64_t lhs_limb;
3044 uint64_t rhs_limb = zig_u64_intCast_u8(rhs_byte);
3045
3046 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3047 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3048 }
3049
3050 remaining_bytes -= 64 / CHAR_BIT;
3051
3052#if zig_big_endian
3053 byte_offset += 64 / CHAR_BIT;
3054#endif
3055 }
3056
3057 while (remaining_bytes >= 32 / CHAR_BIT) {
3058 uint8_t rhs_byte = remaining_bytes == 32 / CHAR_BIT ? rhs : UINT8_C(0);
3059
3060#if zig_little_endian
3061 byte_offset -= 32 / CHAR_BIT;
3062#endif
3063
3064 if (do_signed) {
3065 int32_t lhs_limb;
3066 int32_t rhs_limb = zig_i32_intCast_u8(rhs_byte);
3067
3068 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3069 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3070 do_signed = false;
3071 } else {
3072 uint32_t lhs_limb;
3073 uint32_t rhs_limb = zig_u32_intCast_u8(rhs_byte);
3074
3075 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3076 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3077 }
3078
3079 remaining_bytes -= 32 / CHAR_BIT;
3080
3081#if zig_big_endian
3082 byte_offset += 32 / CHAR_BIT;
3083#endif
3084 }
3085
3086 while (remaining_bytes >= 16 / CHAR_BIT) {
3087 uint8_t rhs_byte = remaining_bytes == 16 / CHAR_BIT ? rhs : UINT8_C(0);
3088
3089#if zig_little_endian
3090 byte_offset -= 16 / CHAR_BIT;
3091#endif
3092
3093 if (do_signed) {
3094 int16_t lhs_limb;
3095 int16_t rhs_limb = zig_i16_intCast_u8(rhs_byte);
3096
3097 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3098 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3099 do_signed = false;
3100 } else {
3101 uint16_t lhs_limb;
3102 uint16_t rhs_limb = zig_u16_intCast_u8(rhs_byte);
3103
3104 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3105 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3106 }
3107
3108 remaining_bytes -= 16 / CHAR_BIT;
3109
3110#if zig_big_endian
3111 byte_offset += 16 / CHAR_BIT;
3112#endif
3113 }
3114
3115 while (remaining_bytes >= 8 / CHAR_BIT) {
3116 uint8_t rhs_byte = remaining_bytes == 16 / CHAR_BIT ? rhs : UINT8_C(0);
3117
3118#if zig_little_endian
3119 byte_offset -= 8 / CHAR_BIT;
3120#endif
3121
3122 if (do_signed) {
3123 int8_t lhs_limb;
3124 int16_t lhs_cmp_limb;
3125 int16_t rhs_cmp_limb = zig_i16_intCast_u8(rhs_byte);
3126
3127 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3128 lhs_cmp_limb = zig_i16_intCast_i8(lhs_limb);
3129 if (lhs_cmp_limb != rhs_cmp_limb) return (lhs_cmp_limb > rhs_cmp_limb) - (lhs_cmp_limb < rhs_cmp_limb);
3130 do_signed = false;
3131 } else {
3132 uint8_t lhs_limb;
3133 uint8_t rhs_limb = rhs_byte;
3134
3135 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3136 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3137 }
3138
3139 remaining_bytes -= 8 / CHAR_BIT;
3140
3141#if zig_big_endian
3142 byte_offset += 8 / CHAR_BIT;
3143#endif
3144 }
3145
3146 return 0;
3147}
3148
3149static inline int32_t zig_cmp_big(const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3150 const uint8_t *lhs_bytes = lhs;
3151 const uint8_t *rhs_bytes = rhs;
3152 uint16_t byte_offset = 0;
3153 bool do_signed = is_signed;
3154 uint16_t remaining_bytes = zig_int_bytes(bits);
3155
3156#if zig_little_endian
3157 byte_offset = remaining_bytes;
3158#endif
3159
3160 while (remaining_bytes >= 128 / CHAR_BIT) {
3161 int32_t limb_cmp;
3162
3163#if zig_little_endian
3164 byte_offset -= 128 / CHAR_BIT;
3165#endif
3166
3167 if (do_signed) {
3168 zig_i128 lhs_limb;
3169 zig_i128 rhs_limb;
3170
3171 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3172 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3173 limb_cmp = zig_cmp_i128(lhs_limb, rhs_limb);
3174 do_signed = false;
3175 } else {
3176 zig_u128 lhs_limb;
3177 zig_u128 rhs_limb;
3178
3179 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3180 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3181 limb_cmp = zig_cmp_u128(lhs_limb, rhs_limb);
3182 }
3183
3184 if (limb_cmp != 0) return limb_cmp;
3185 remaining_bytes -= 128 / CHAR_BIT;
3186
3187#if zig_big_endian
3188 byte_offset += 128 / CHAR_BIT;
3189#endif
3190 }
3191
3192 while (remaining_bytes >= 64 / CHAR_BIT) {
3193#if zig_little_endian
3194 byte_offset -= 64 / CHAR_BIT;
3195#endif
3196
3197 if (do_signed) {
3198 int64_t lhs_limb;
3199 int64_t rhs_limb;
3200
3201 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3202 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3203 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3204 do_signed = false;
3205 } else {
3206 uint64_t lhs_limb;
3207 uint64_t rhs_limb;
3208
3209 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3210 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3211 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3212 }
3213
3214 remaining_bytes -= 64 / CHAR_BIT;
3215
3216#if zig_big_endian
3217 byte_offset += 64 / CHAR_BIT;
3218#endif
3219 }
3220
3221 while (remaining_bytes >= 32 / CHAR_BIT) {
3222#if zig_little_endian
3223 byte_offset -= 32 / CHAR_BIT;
3224#endif
3225
3226 if (do_signed) {
3227 int32_t lhs_limb;
3228 int32_t rhs_limb;
3229
3230 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3231 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3232 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3233 do_signed = false;
3234 } else {
3235 uint32_t lhs_limb;
3236 uint32_t rhs_limb;
3237
3238 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3239 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3240 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3241 }
3242
3243 remaining_bytes -= 32 / CHAR_BIT;
3244
3245#if zig_big_endian
3246 byte_offset += 32 / CHAR_BIT;
3247#endif
3248 }
3249
3250 while (remaining_bytes >= 16 / CHAR_BIT) {
3251#if zig_little_endian
3252 byte_offset -= 16 / CHAR_BIT;
3253#endif
3254
3255 if (do_signed) {
3256 int16_t lhs_limb;
3257 int16_t rhs_limb;
3258
3259 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3260 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3261 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3262 do_signed = false;
3263 } else {
3264 uint16_t lhs_limb;
3265 uint16_t rhs_limb;
3266
3267 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3268 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3269 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3270 }
3271
3272 remaining_bytes -= 16 / CHAR_BIT;
3273
3274#if zig_big_endian
3275 byte_offset += 16 / CHAR_BIT;
3276#endif
3277 }
3278
3279 while (remaining_bytes >= 8 / CHAR_BIT) {
3280#if zig_little_endian
3281 byte_offset -= 8 / CHAR_BIT;
3282#endif
3283
3284 if (do_signed) {
3285 int8_t lhs_limb;
3286 int8_t rhs_limb;
3287
3288 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3289 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3290 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3291 do_signed = false;
3292 } else {
3293 uint8_t lhs_limb;
3294 uint8_t rhs_limb;
3295
3296 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3297 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3298 if (lhs_limb != rhs_limb) return (lhs_limb > rhs_limb) - (lhs_limb < rhs_limb);
3299 }
3300
3301 remaining_bytes -= 8 / CHAR_BIT;
3302
3303#if zig_big_endian
3304 byte_offset += 8 / CHAR_BIT;
3305#endif
3306 }
3307
3308 return 0;
3309}
3310
3311static inline void zig_not_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
3312 uint8_t *res_bytes = res;
3313 const uint8_t *arg_bytes = arg;
3314 uint16_t byte_offset = 0;
3315 uint16_t remaining_bytes = zig_int_bytes(bits);
3316 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3317
3318#if zig_big_endian
3319 byte_offset = remaining_bytes;
3320#endif
3321
3322 while (remaining_bytes >= 128 / CHAR_BIT) {
3323 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
3324
3325#if zig_big_endian
3326 byte_offset -= 128 / CHAR_BIT;
3327#endif
3328
3329 if (remaining_bytes != 128 / CHAR_BIT || is_signed) {
3330 zig_i128 res_limb;
3331 zig_i128 arg_limb;
3332
3333 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3334 res_limb = zig_not_i128(arg_limb, limb_bits);
3335 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3336 } else {
3337 zig_u128 res_limb;
3338 zig_u128 arg_limb;
3339
3340 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3341 res_limb = zig_not_u128(arg_limb, limb_bits);
3342 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3343 }
3344
3345 remaining_bytes -= 128 / CHAR_BIT;
3346
3347#if zig_little_endian
3348 byte_offset += 128 / CHAR_BIT;
3349#endif
3350 }
3351
3352 while (remaining_bytes >= 64 / CHAR_BIT) {
3353 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
3354
3355#if zig_big_endian
3356 byte_offset -= 64 / CHAR_BIT;
3357#endif
3358
3359 if (remaining_bytes != 64 / CHAR_BIT || is_signed) {
3360 int64_t res_limb;
3361 int64_t arg_limb;
3362
3363 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3364 res_limb = zig_not_i64(arg_limb, limb_bits);
3365 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3366 } else {
3367 uint64_t res_limb;
3368 uint64_t arg_limb;
3369
3370 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3371 res_limb = zig_not_u64(arg_limb, limb_bits);
3372 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3373 }
3374
3375 remaining_bytes -= 64 / CHAR_BIT;
3376
3377#if zig_little_endian
3378 byte_offset += 64 / CHAR_BIT;
3379#endif
3380 }
3381
3382 while (remaining_bytes >= 32 / CHAR_BIT) {
3383 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
3384
3385#if zig_big_endian
3386 byte_offset -= 32 / CHAR_BIT;
3387#endif
3388
3389 if (remaining_bytes != 32 / CHAR_BIT || is_signed) {
3390 int32_t res_limb;
3391 int32_t arg_limb;
3392
3393 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3394 res_limb = zig_not_i32(arg_limb, limb_bits);
3395 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3396 } else {
3397 uint32_t res_limb;
3398 uint32_t arg_limb;
3399
3400 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3401 res_limb = zig_not_u32(arg_limb, limb_bits);
3402 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3403 }
3404
3405 remaining_bytes -= 32 / CHAR_BIT;
3406
3407#if zig_little_endian
3408 byte_offset += 32 / CHAR_BIT;
3409#endif
3410 }
3411
3412 while (remaining_bytes >= 16 / CHAR_BIT) {
3413 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
3414
3415#if zig_big_endian
3416 byte_offset -= 16 / CHAR_BIT;
3417#endif
3418
3419 if (remaining_bytes != 16 / CHAR_BIT || is_signed) {
3420 int16_t res_limb;
3421 int16_t arg_limb;
3422
3423 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3424 res_limb = zig_not_i16(arg_limb, limb_bits);
3425 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3426 } else {
3427 uint16_t res_limb;
3428 uint16_t arg_limb;
3429
3430 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3431 res_limb = zig_not_u16(arg_limb, limb_bits);
3432 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3433 }
3434
3435 remaining_bytes -= 16 / CHAR_BIT;
3436
3437#if zig_little_endian
3438 byte_offset += 16 / CHAR_BIT;
3439#endif
3440 }
3441
3442 while (remaining_bytes >= 8 / CHAR_BIT) {
3443 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
3444
3445#if zig_big_endian
3446 byte_offset -= 8 / CHAR_BIT;
3447#endif
3448
3449 if (remaining_bytes != 8 / CHAR_BIT || is_signed) {
3450 int8_t res_limb;
3451 int8_t arg_limb;
3452
3453 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3454 res_limb = zig_not_i8(arg_limb, limb_bits);
3455 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3456 } else {
3457 uint8_t res_limb;
3458 uint8_t arg_limb;
3459
3460 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
3461 res_limb = zig_not_u8(arg_limb, limb_bits);
3462 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3463 }
3464
3465 remaining_bytes -= 8 / CHAR_BIT;
3466
3467#if zig_little_endian
3468 byte_offset += 8 / CHAR_BIT;
3469#endif
3470 }
3471}
3472
3473static inline void zig_and_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3474 uint8_t *res_bytes = res;
3475 const uint8_t *lhs_bytes = lhs;
3476 const uint8_t *rhs_bytes = rhs;
3477 uint16_t byte_offset = 0;
3478 uint16_t remaining_bytes = zig_int_bytes(bits);
3479 (void)is_signed;
3480
3481 while (remaining_bytes >= 128 / CHAR_BIT) {
3482 zig_u128 res_limb;
3483 zig_u128 lhs_limb;
3484 zig_u128 rhs_limb;
3485
3486 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3487 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3488 res_limb = zig_and_u128(lhs_limb, rhs_limb);
3489 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3490
3491 remaining_bytes -= 128 / CHAR_BIT;
3492 byte_offset += 128 / CHAR_BIT;
3493 }
3494
3495 while (remaining_bytes >= 64 / CHAR_BIT) {
3496 uint64_t res_limb;
3497 uint64_t lhs_limb;
3498 uint64_t rhs_limb;
3499
3500 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3501 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3502 res_limb = zig_and_u64(lhs_limb, rhs_limb);
3503 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3504
3505 remaining_bytes -= 64 / CHAR_BIT;
3506 byte_offset += 64 / CHAR_BIT;
3507 }
3508
3509 while (remaining_bytes >= 32 / CHAR_BIT) {
3510 uint32_t res_limb;
3511 uint32_t lhs_limb;
3512 uint32_t rhs_limb;
3513
3514 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3515 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3516 res_limb = zig_and_u32(lhs_limb, rhs_limb);
3517 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3518
3519 remaining_bytes -= 32 / CHAR_BIT;
3520 byte_offset += 32 / CHAR_BIT;
3521 }
3522
3523 while (remaining_bytes >= 16 / CHAR_BIT) {
3524 uint16_t res_limb;
3525 uint16_t lhs_limb;
3526 uint16_t rhs_limb;
3527
3528 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3529 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3530 res_limb = zig_and_u16(lhs_limb, rhs_limb);
3531 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3532
3533 remaining_bytes -= 16 / CHAR_BIT;
3534 byte_offset += 16 / CHAR_BIT;
3535 }
3536
3537 while (remaining_bytes >= 8 / CHAR_BIT) {
3538 uint8_t res_limb;
3539 uint8_t lhs_limb;
3540 uint8_t rhs_limb;
3541
3542 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3543 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3544 res_limb = zig_and_u8(lhs_limb, rhs_limb);
3545 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3546
3547 remaining_bytes -= 8 / CHAR_BIT;
3548 byte_offset += 8 / CHAR_BIT;
3549 }
3550}
3551
3552static inline void zig_or_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3553 uint8_t *res_bytes = res;
3554 const uint8_t *lhs_bytes = lhs;
3555 const uint8_t *rhs_bytes = rhs;
3556 uint16_t byte_offset = 0;
3557 uint16_t remaining_bytes = zig_int_bytes(bits);
3558 (void)is_signed;
3559
3560 while (remaining_bytes >= 128 / CHAR_BIT) {
3561 zig_u128 res_limb;
3562 zig_u128 lhs_limb;
3563 zig_u128 rhs_limb;
3564
3565 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3566 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3567 res_limb = zig_or_u128(lhs_limb, rhs_limb);
3568 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3569
3570 remaining_bytes -= 128 / CHAR_BIT;
3571 byte_offset += 128 / CHAR_BIT;
3572 }
3573
3574 while (remaining_bytes >= 64 / CHAR_BIT) {
3575 uint64_t res_limb;
3576 uint64_t lhs_limb;
3577 uint64_t rhs_limb;
3578
3579 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3580 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3581 res_limb = zig_or_u64(lhs_limb, rhs_limb);
3582 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3583
3584 remaining_bytes -= 64 / CHAR_BIT;
3585 byte_offset += 64 / CHAR_BIT;
3586 }
3587
3588 while (remaining_bytes >= 32 / CHAR_BIT) {
3589 uint32_t res_limb;
3590 uint32_t lhs_limb;
3591 uint32_t rhs_limb;
3592
3593 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3594 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3595 res_limb = zig_or_u32(lhs_limb, rhs_limb);
3596 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3597
3598 remaining_bytes -= 32 / CHAR_BIT;
3599 byte_offset += 32 / CHAR_BIT;
3600 }
3601
3602 while (remaining_bytes >= 16 / CHAR_BIT) {
3603 uint16_t res_limb;
3604 uint16_t lhs_limb;
3605 uint16_t rhs_limb;
3606
3607 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3608 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3609 res_limb = zig_or_u16(lhs_limb, rhs_limb);
3610 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3611
3612 remaining_bytes -= 16 / CHAR_BIT;
3613 byte_offset += 16 / CHAR_BIT;
3614 }
3615
3616 while (remaining_bytes >= 8 / CHAR_BIT) {
3617 uint8_t res_limb;
3618 uint8_t lhs_limb;
3619 uint8_t rhs_limb;
3620
3621 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3622 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3623 res_limb = zig_or_u8(lhs_limb, rhs_limb);
3624 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3625
3626 remaining_bytes -= 8 / CHAR_BIT;
3627 byte_offset += 8 / CHAR_BIT;
3628 }
3629}
3630
3631static inline void zig_xor_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
3632 uint8_t *res_bytes = res;
3633 const uint8_t *lhs_bytes = lhs;
3634 const uint8_t *rhs_bytes = rhs;
3635 uint16_t byte_offset = 0;
3636 uint16_t remaining_bytes = zig_int_bytes(bits);
3637 (void)is_signed;
3638
3639 while (remaining_bytes >= 128 / CHAR_BIT) {
3640 zig_u128 res_limb;
3641 zig_u128 lhs_limb;
3642 zig_u128 rhs_limb;
3643
3644 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3645 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3646 res_limb = zig_xor_u128(lhs_limb, rhs_limb);
3647 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3648
3649 remaining_bytes -= 128 / CHAR_BIT;
3650 byte_offset += 128 / CHAR_BIT;
3651 }
3652
3653 while (remaining_bytes >= 64 / CHAR_BIT) {
3654 uint64_t res_limb;
3655 uint64_t lhs_limb;
3656 uint64_t rhs_limb;
3657
3658 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3659 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3660 res_limb = zig_xor_u64(lhs_limb, rhs_limb);
3661 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3662
3663 remaining_bytes -= 64 / CHAR_BIT;
3664 byte_offset += 64 / CHAR_BIT;
3665 }
3666
3667 while (remaining_bytes >= 32 / CHAR_BIT) {
3668 uint32_t res_limb;
3669 uint32_t lhs_limb;
3670 uint32_t rhs_limb;
3671
3672 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3673 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3674 res_limb = zig_xor_u32(lhs_limb, rhs_limb);
3675 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3676
3677 remaining_bytes -= 32 / CHAR_BIT;
3678 byte_offset += 32 / CHAR_BIT;
3679 }
3680
3681 while (remaining_bytes >= 16 / CHAR_BIT) {
3682 uint16_t res_limb;
3683 uint16_t lhs_limb;
3684 uint16_t rhs_limb;
3685
3686 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3687 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3688 res_limb = zig_xor_u16(lhs_limb, rhs_limb);
3689 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3690
3691 remaining_bytes -= 16 / CHAR_BIT;
3692 byte_offset += 16 / CHAR_BIT;
3693 }
3694
3695 while (remaining_bytes >= 8 / CHAR_BIT) {
3696 uint8_t res_limb;
3697 uint8_t lhs_limb;
3698 uint8_t rhs_limb;
3699
3700 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
3701 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
3702 res_limb = zig_xor_u8(lhs_limb, rhs_limb);
3703 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3704
3705 remaining_bytes -= 8 / CHAR_BIT;
3706 byte_offset += 8 / CHAR_BIT;
3707 }
3708}
3709
3710static inline void zig_increment_big(void *res, bool is_signed, uint16_t bits) {
3711 uint8_t *res_bytes = res;
3712 uint16_t byte_offset = 0;
3713 uint16_t remaining_bytes = zig_int_bytes(bits);
3714 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3715
3716#if zig_big_endian
3717 byte_offset = remaining_bytes;
3718#endif
3719
3720 while (remaining_bytes >= 128 / CHAR_BIT) {
3721 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
3722
3723#if zig_big_endian
3724 byte_offset -= 128 / CHAR_BIT;
3725#endif
3726
3727 {
3728 zig_u128 res_limb;
3729 bool limb_overflow;
3730
3731 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3732 limb_overflow = zig_addo_u128(&res_limb, res_limb, zig_make_u128(UINT64_C(0), UINT64_C(1)), limb_bits);
3733 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3734 if (!limb_overflow) return;
3735 }
3736
3737 remaining_bytes -= 128 / CHAR_BIT;
3738
3739#if zig_little_endian
3740 byte_offset += 128 / CHAR_BIT;
3741#endif
3742 }
3743
3744 while (remaining_bytes >= 64 / CHAR_BIT) {
3745 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
3746
3747#if zig_big_endian
3748 byte_offset -= 64 / CHAR_BIT;
3749#endif
3750
3751 {
3752 uint64_t res_limb;
3753 bool limb_overflow;
3754
3755 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3756 limb_overflow = zig_addo_u64(&res_limb, res_limb, UINT64_C(1), limb_bits);
3757 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3758 if (!limb_overflow) return;
3759 }
3760
3761 remaining_bytes -= 64 / CHAR_BIT;
3762
3763#if zig_little_endian
3764 byte_offset += 64 / CHAR_BIT;
3765#endif
3766 }
3767
3768 while (remaining_bytes >= 32 / CHAR_BIT) {
3769 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
3770
3771#if zig_big_endian
3772 byte_offset -= 32 / CHAR_BIT;
3773#endif
3774
3775 {
3776 uint32_t res_limb;
3777 bool limb_overflow;
3778
3779 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3780 limb_overflow = zig_addo_u32(&res_limb, res_limb, UINT32_C(1), limb_bits);
3781 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3782 if (!limb_overflow) return;
3783 }
3784
3785 remaining_bytes -= 32 / CHAR_BIT;
3786
3787#if zig_little_endian
3788 byte_offset += 32 / CHAR_BIT;
3789#endif
3790 }
3791
3792 while (remaining_bytes >= 16 / CHAR_BIT) {
3793 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
3794
3795#if zig_big_endian
3796 byte_offset -= 16 / CHAR_BIT;
3797#endif
3798
3799 {
3800 uint16_t res_limb;
3801 bool limb_overflow;
3802
3803 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3804 limb_overflow = zig_addo_u16(&res_limb, res_limb, UINT16_C(1), limb_bits);
3805 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3806 if (!limb_overflow) return;
3807 }
3808
3809 remaining_bytes -= 16 / CHAR_BIT;
3810
3811#if zig_little_endian
3812 byte_offset += 16 / CHAR_BIT;
3813#endif
3814 }
3815
3816 while (remaining_bytes >= 8 / CHAR_BIT) {
3817 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
3818
3819#if zig_big_endian
3820 byte_offset -= 8 / CHAR_BIT;
3821#endif
3822
3823 {
3824 uint8_t res_limb;
3825 bool limb_overflow;
3826
3827 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3828 limb_overflow = zig_addo_u8(&res_limb, res_limb, UINT8_C(1), limb_bits);
3829 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3830 if (!limb_overflow) return;
3831 }
3832
3833 remaining_bytes -= 8 / CHAR_BIT;
3834
3835#if zig_little_endian
3836 byte_offset += 8 / CHAR_BIT;
3837#endif
3838 }
3839}
3840
3841static inline void zig_decrement_big(void *res, bool is_signed, uint16_t bits) {
3842 uint8_t *res_bytes = res;
3843 uint16_t byte_offset = 0;
3844 uint16_t remaining_bytes = zig_int_bytes(bits);
3845 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3846
3847#if zig_big_endian
3848 byte_offset = remaining_bytes;
3849#endif
3850
3851 while (remaining_bytes >= 128 / CHAR_BIT) {
3852 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
3853
3854#if zig_big_endian
3855 byte_offset -= 128 / CHAR_BIT;
3856#endif
3857
3858 {
3859 zig_u128 res_limb;
3860 bool limb_overflow;
3861
3862 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3863 limb_overflow = zig_subo_u128(&res_limb, res_limb, zig_make_u128(UINT64_C(0), UINT64_C(1)), limb_bits);
3864 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3865 if (!limb_overflow) return;
3866 }
3867
3868 remaining_bytes -= 128 / CHAR_BIT;
3869
3870#if zig_little_endian
3871 byte_offset += 128 / CHAR_BIT;
3872#endif
3873 }
3874
3875 while (remaining_bytes >= 64 / CHAR_BIT) {
3876 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
3877
3878#if zig_big_endian
3879 byte_offset -= 64 / CHAR_BIT;
3880#endif
3881
3882 {
3883 uint64_t res_limb;
3884 bool limb_overflow;
3885
3886 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3887 limb_overflow = zig_subo_u64(&res_limb, res_limb, UINT64_C(1), limb_bits);
3888 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3889 if (!limb_overflow) return;
3890 }
3891
3892 remaining_bytes -= 64 / CHAR_BIT;
3893
3894#if zig_little_endian
3895 byte_offset += 64 / CHAR_BIT;
3896#endif
3897 }
3898
3899 while (remaining_bytes >= 32 / CHAR_BIT) {
3900 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
3901
3902#if zig_big_endian
3903 byte_offset -= 32 / CHAR_BIT;
3904#endif
3905
3906 {
3907 uint32_t res_limb;
3908 bool limb_overflow;
3909
3910 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3911 limb_overflow = zig_subo_u32(&res_limb, res_limb, UINT32_C(1), limb_bits);
3912 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3913 if (!limb_overflow) return;
3914 }
3915
3916 remaining_bytes -= 32 / CHAR_BIT;
3917
3918#if zig_little_endian
3919 byte_offset += 32 / CHAR_BIT;
3920#endif
3921 }
3922
3923 while (remaining_bytes >= 16 / CHAR_BIT) {
3924 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
3925
3926#if zig_big_endian
3927 byte_offset -= 16 / CHAR_BIT;
3928#endif
3929
3930 {
3931 uint16_t res_limb;
3932 bool limb_overflow;
3933
3934 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3935 limb_overflow = zig_subo_u16(&res_limb, res_limb, UINT16_C(1), limb_bits);
3936 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3937 if (!limb_overflow) return;
3938 }
3939
3940 remaining_bytes -= 16 / CHAR_BIT;
3941
3942#if zig_little_endian
3943 byte_offset += 16 / CHAR_BIT;
3944#endif
3945 }
3946
3947 while (remaining_bytes >= 8 / CHAR_BIT) {
3948 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
3949
3950#if zig_big_endian
3951 byte_offset -= 8 / CHAR_BIT;
3952#endif
3953
3954 {
3955 uint8_t res_limb;
3956 bool limb_overflow;
3957
3958 memcpy(&res_limb, &res_bytes[byte_offset], sizeof(res_limb));
3959 limb_overflow = zig_subo_u8(&res_limb, res_limb, UINT8_C(1), limb_bits);
3960 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
3961 if (!limb_overflow) return;
3962 }
3963
3964 remaining_bytes -= 8 / CHAR_BIT;
3965
3966#if zig_little_endian
3967 byte_offset += 8 / CHAR_BIT;
3968#endif
3969 }
3970}
3971
3972static inline void zig_abs_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
3973 uint8_t *res_bytes = res;
3974 const uint8_t *arg_bytes = arg;
3975 uint16_t byte_offset = 0;
3976 uint16_t remaining_bytes = zig_int_bytes(bits);
3977 if (zig_signFill_big(arg, is_signed, bits) >= INT8_C(0)) {
3978 memcpy(res, arg, remaining_bytes);
3979 return;
3980 }
3981 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
3982 bool overflow = true;
3983
3984#if zig_big_endian
3985 byte_offset = remaining_bytes;
3986#endif
3987
3988 while (remaining_bytes >= 128 / CHAR_BIT) {
3989 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
3990
3991#if zig_big_endian
3992 byte_offset -= 128 / CHAR_BIT;
3993#endif
3994
3995 {
3996 zig_u128 res_limb;
3997 zig_u128 arg_limb;
3998
3999 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4000 overflow = zig_addo_u128(&res_limb, zig_not_u128(arg_limb, UINT8_C(128)), zig_make_u128(UINT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits);
4001 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4002 }
4003
4004 remaining_bytes -= 128 / CHAR_BIT;
4005
4006#if zig_little_endian
4007 byte_offset += 128 / CHAR_BIT;
4008#endif
4009 }
4010
4011 while (remaining_bytes >= 64 / CHAR_BIT) {
4012 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
4013
4014#if zig_big_endian
4015 byte_offset -= 64 / CHAR_BIT;
4016#endif
4017
4018 {
4019 uint64_t res_limb;
4020 uint64_t arg_limb;
4021
4022 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4023 overflow = zig_addo_u64(&res_limb, zig_not_u64(arg_limb, UINT8_C(64)), overflow ? UINT64_C(1) : UINT64_C(0), limb_bits);
4024 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4025 }
4026
4027 remaining_bytes -= 64 / CHAR_BIT;
4028
4029#if zig_little_endian
4030 byte_offset += 64 / CHAR_BIT;
4031#endif
4032 }
4033
4034 while (remaining_bytes >= 32 / CHAR_BIT) {
4035 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
4036
4037#if zig_big_endian
4038 byte_offset -= 32 / CHAR_BIT;
4039#endif
4040
4041 {
4042 uint32_t res_limb;
4043 uint32_t arg_limb;
4044
4045 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4046 overflow = zig_addo_u32(&res_limb, zig_not_u32(arg_limb, UINT8_C(32)), overflow ? UINT32_C(1) : UINT32_C(0), limb_bits);
4047 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4048 }
4049
4050 remaining_bytes -= 32 / CHAR_BIT;
4051
4052#if zig_little_endian
4053 byte_offset += 32 / CHAR_BIT;
4054#endif
4055 }
4056
4057 while (remaining_bytes >= 16 / CHAR_BIT) {
4058 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
4059
4060#if zig_big_endian
4061 byte_offset -= 16 / CHAR_BIT;
4062#endif
4063
4064 {
4065 uint16_t res_limb;
4066 uint16_t arg_limb;
4067
4068 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4069 overflow = zig_addo_u16(&res_limb, zig_not_u16(arg_limb, UINT8_C(16)), overflow ? UINT16_C(1) : UINT16_C(0), limb_bits);
4070 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4071 }
4072
4073 remaining_bytes -= 16 / CHAR_BIT;
4074
4075#if zig_little_endian
4076 byte_offset += 16 / CHAR_BIT;
4077#endif
4078 }
4079
4080 while (remaining_bytes >= 8 / CHAR_BIT) {
4081 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
4082
4083#if zig_big_endian
4084 byte_offset -= 8 / CHAR_BIT;
4085#endif
4086
4087 {
4088 uint8_t res_limb;
4089 uint8_t arg_limb;
4090
4091 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
4092 overflow = zig_addo_u8(&res_limb, zig_not_u8(arg_limb, UINT8_C(8)), overflow ? UINT8_C(1) : UINT8_C(0), limb_bits);
4093 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4094 }
4095
4096 remaining_bytes -= 8 / CHAR_BIT;
4097
4098#if zig_little_endian
4099 byte_offset += 8 / CHAR_BIT;
4100#endif
4101 }
4102}
4103
4104static inline void zig_min_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4105 memcpy(res, zig_cmp_big(lhs, rhs, is_signed, bits) < INT32_C(0) ? lhs : rhs, zig_int_bytes(bits));
4106}
4107
4108static inline void zig_max_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4109 memcpy(res, zig_cmp_big(lhs, rhs, is_signed, bits) >= INT32_C(0) ? lhs : rhs, zig_int_bytes(bits));
4110}
4111
4112static inline bool zig_addo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4113 uint8_t *res_bytes = res;
4114 const uint8_t *lhs_bytes = lhs;
4115 const uint8_t *rhs_bytes = rhs;
4116 uint16_t byte_offset = 0;
4117 uint16_t remaining_bytes = zig_int_bytes(bits);
4118 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
4119 bool overflow = false;
4120
4121#if zig_big_endian
4122 byte_offset = remaining_bytes;
4123#endif
4124
4125 while (remaining_bytes >= 128 / CHAR_BIT) {
4126 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
4127
4128#if zig_big_endian
4129 byte_offset -= 128 / CHAR_BIT;
4130#endif
4131
4132 if (remaining_bytes == 128 / CHAR_BIT && is_signed) {
4133 zig_i128 res_limb;
4134 zig_i128 tmp_limb;
4135 zig_i128 lhs_limb;
4136 zig_i128 rhs_limb;
4137 bool limb_overflow;
4138
4139 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4140 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4141 limb_overflow = zig_addo_i128(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4142 overflow = limb_overflow ^ zig_addo_i128(&res_limb, tmp_limb, zig_make_i128(INT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits);
4143 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4144 } else {
4145 zig_u128 res_limb;
4146 zig_u128 tmp_limb;
4147 zig_u128 lhs_limb;
4148 zig_u128 rhs_limb;
4149 bool limb_overflow;
4150
4151 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4152 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4153 limb_overflow = zig_addo_u128(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4154 overflow = limb_overflow ^ zig_addo_u128(&res_limb, tmp_limb, zig_make_u128(UINT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits);
4155 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4156 }
4157
4158 remaining_bytes -= 128 / CHAR_BIT;
4159
4160#if zig_little_endian
4161 byte_offset += 128 / CHAR_BIT;
4162#endif
4163 }
4164
4165 while (remaining_bytes >= 64 / CHAR_BIT) {
4166 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
4167
4168#if zig_big_endian
4169 byte_offset -= 64 / CHAR_BIT;
4170#endif
4171
4172 if (remaining_bytes == 64 / CHAR_BIT && is_signed) {
4173 int64_t res_limb;
4174 int64_t tmp_limb;
4175 int64_t lhs_limb;
4176 int64_t rhs_limb;
4177 bool limb_overflow;
4178
4179 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4180 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4181 limb_overflow = zig_addo_i64(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4182 overflow = limb_overflow ^ zig_addo_i64(&res_limb, tmp_limb, overflow ? INT64_C(1) : INT64_C(0), limb_bits);
4183 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4184 } else {
4185 uint64_t res_limb;
4186 uint64_t tmp_limb;
4187 uint64_t lhs_limb;
4188 uint64_t rhs_limb;
4189 bool limb_overflow;
4190
4191 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4192 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4193 limb_overflow = zig_addo_u64(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4194 overflow = limb_overflow ^ zig_addo_u64(&res_limb, tmp_limb, overflow ? UINT64_C(1) : UINT64_C(0), limb_bits);
4195 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4196 }
4197
4198 remaining_bytes -= 64 / CHAR_BIT;
4199
4200#if zig_little_endian
4201 byte_offset += 64 / CHAR_BIT;
4202#endif
4203 }
4204
4205 while (remaining_bytes >= 32 / CHAR_BIT) {
4206 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
4207
4208#if zig_big_endian
4209 byte_offset -= 32 / CHAR_BIT;
4210#endif
4211
4212 if (remaining_bytes == 32 / CHAR_BIT && is_signed) {
4213 int32_t res_limb;
4214 int32_t tmp_limb;
4215 int32_t lhs_limb;
4216 int32_t rhs_limb;
4217 bool limb_overflow;
4218
4219 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4220 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4221 limb_overflow = zig_addo_i32(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4222 overflow = limb_overflow ^ zig_addo_i32(&res_limb, tmp_limb, overflow ? INT32_C(1) : INT32_C(0), limb_bits);
4223 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4224 } else {
4225 uint32_t res_limb;
4226 uint32_t tmp_limb;
4227 uint32_t lhs_limb;
4228 uint32_t rhs_limb;
4229 bool limb_overflow;
4230
4231 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4232 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4233 limb_overflow = zig_addo_u32(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4234 overflow = limb_overflow ^ zig_addo_u32(&res_limb, tmp_limb, overflow ? UINT32_C(1) : UINT32_C(0), limb_bits);
4235 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4236 }
4237
4238 remaining_bytes -= 32 / CHAR_BIT;
4239
4240#if zig_little_endian
4241 byte_offset += 32 / CHAR_BIT;
4242#endif
4243 }
4244
4245 while (remaining_bytes >= 16 / CHAR_BIT) {
4246 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
4247
4248#if zig_big_endian
4249 byte_offset -= 16 / CHAR_BIT;
4250#endif
4251
4252 if (remaining_bytes == 16 / CHAR_BIT && is_signed) {
4253 int16_t res_limb;
4254 int16_t tmp_limb;
4255 int16_t lhs_limb;
4256 int16_t rhs_limb;
4257 bool limb_overflow;
4258
4259 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4260 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4261 limb_overflow = zig_addo_i16(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4262 overflow = limb_overflow ^ zig_addo_i16(&res_limb, tmp_limb, overflow ? INT16_C(1) : INT16_C(0), limb_bits);
4263 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4264 } else {
4265 uint16_t res_limb;
4266 uint16_t tmp_limb;
4267 uint16_t lhs_limb;
4268 uint16_t rhs_limb;
4269 bool limb_overflow;
4270
4271 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4272 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4273 limb_overflow = zig_addo_u16(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4274 overflow = limb_overflow ^ zig_addo_u16(&res_limb, tmp_limb, overflow ? UINT16_C(1) : UINT16_C(0), limb_bits);
4275 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4276 }
4277
4278 remaining_bytes -= 16 / CHAR_BIT;
4279
4280#if zig_little_endian
4281 byte_offset += 16 / CHAR_BIT;
4282#endif
4283 }
4284
4285 while (remaining_bytes >= 8 / CHAR_BIT) {
4286 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
4287
4288#if zig_big_endian
4289 byte_offset -= 8 / CHAR_BIT;
4290#endif
4291
4292 if (remaining_bytes == 8 / CHAR_BIT && is_signed) {
4293 int8_t res_limb;
4294 int8_t tmp_limb;
4295 int8_t lhs_limb;
4296 int8_t rhs_limb;
4297 bool limb_overflow;
4298
4299 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4300 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4301 limb_overflow = zig_addo_i8(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4302 overflow = limb_overflow ^ zig_addo_i8(&res_limb, tmp_limb, overflow ? INT8_C(1) : INT8_C(0), limb_bits);
4303 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4304 } else {
4305 uint8_t res_limb;
4306 uint8_t tmp_limb;
4307 uint8_t lhs_limb;
4308 uint8_t rhs_limb;
4309 bool limb_overflow;
4310
4311 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4312 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4313 limb_overflow = zig_addo_u8(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4314 overflow = limb_overflow ^ zig_addo_u8(&res_limb, tmp_limb, overflow ? UINT8_C(1) : UINT8_C(0), limb_bits);
4315 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4316 }
4317
4318 remaining_bytes -= 8 / CHAR_BIT;
4319
4320#if zig_little_endian
4321 byte_offset += 8 / CHAR_BIT;
4322#endif
4323 }
4324
4325 return overflow;
4326}
4327
4328static inline bool zig_subo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4329 uint8_t *res_bytes = res;
4330 const uint8_t *lhs_bytes = lhs;
4331 const uint8_t *rhs_bytes = rhs;
4332 uint16_t byte_offset = 0;
4333 uint16_t remaining_bytes = zig_int_bytes(bits);
4334 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
4335 bool overflow = false;
4336
4337#if zig_big_endian
4338 byte_offset = remaining_bytes;
4339#endif
4340
4341 while (remaining_bytes >= 128 / CHAR_BIT) {
4342 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
4343
4344#if zig_big_endian
4345 byte_offset -= 128 / CHAR_BIT;
4346#endif
4347
4348 if (remaining_bytes == 128 / CHAR_BIT && is_signed) {
4349 zig_i128 res_limb;
4350 zig_i128 tmp_limb;
4351 zig_i128 lhs_limb;
4352 zig_i128 rhs_limb;
4353 bool limb_overflow;
4354
4355 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4356 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4357 limb_overflow = zig_subo_i128(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4358 overflow = limb_overflow ^ zig_subo_i128(&res_limb, tmp_limb, zig_make_i128(INT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits);
4359 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4360 } else {
4361 zig_u128 res_limb;
4362 zig_u128 tmp_limb;
4363 zig_u128 lhs_limb;
4364 zig_u128 rhs_limb;
4365 bool limb_overflow;
4366
4367 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4368 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4369 limb_overflow = zig_subo_u128(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4370 overflow = limb_overflow ^ zig_subo_u128(&res_limb, tmp_limb, zig_make_u128(UINT64_C(0), overflow ? UINT64_C(1) : UINT64_C(0)), limb_bits);
4371 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4372 }
4373
4374 remaining_bytes -= 128 / CHAR_BIT;
4375
4376#if zig_little_endian
4377 byte_offset += 128 / CHAR_BIT;
4378#endif
4379 }
4380
4381 while (remaining_bytes >= 64 / CHAR_BIT) {
4382 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
4383
4384#if zig_big_endian
4385 byte_offset -= 64 / CHAR_BIT;
4386#endif
4387
4388 if (remaining_bytes == 64 / CHAR_BIT && is_signed) {
4389 int64_t res_limb;
4390 int64_t tmp_limb;
4391 int64_t lhs_limb;
4392 int64_t rhs_limb;
4393 bool limb_overflow;
4394
4395 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4396 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4397 limb_overflow = zig_subo_i64(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4398 overflow = limb_overflow ^ zig_subo_i64(&res_limb, tmp_limb, overflow ? INT64_C(1) : INT64_C(0), limb_bits);
4399 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4400 } else {
4401 uint64_t res_limb;
4402 uint64_t tmp_limb;
4403 uint64_t lhs_limb;
4404 uint64_t rhs_limb;
4405 bool limb_overflow;
4406
4407 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4408 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4409 limb_overflow = zig_subo_u64(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4410 overflow = limb_overflow ^ zig_subo_u64(&res_limb, tmp_limb, overflow ? UINT64_C(1) : UINT64_C(0), limb_bits);
4411 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4412 }
4413
4414 remaining_bytes -= 64 / CHAR_BIT;
4415
4416#if zig_little_endian
4417 byte_offset += 64 / CHAR_BIT;
4418#endif
4419 }
4420
4421 while (remaining_bytes >= 32 / CHAR_BIT) {
4422 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
4423
4424#if zig_big_endian
4425 byte_offset -= 32 / CHAR_BIT;
4426#endif
4427
4428 if (remaining_bytes == 32 / CHAR_BIT && is_signed) {
4429 int32_t res_limb;
4430 int32_t tmp_limb;
4431 int32_t lhs_limb;
4432 int32_t rhs_limb;
4433 bool limb_overflow;
4434
4435 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4436 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4437 limb_overflow = zig_subo_i32(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4438 overflow = limb_overflow ^ zig_subo_i32(&res_limb, tmp_limb, overflow ? INT32_C(1) : INT32_C(0), limb_bits);
4439 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4440 } else {
4441 uint32_t res_limb;
4442 uint32_t tmp_limb;
4443 uint32_t lhs_limb;
4444 uint32_t rhs_limb;
4445 bool limb_overflow;
4446
4447 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4448 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4449 limb_overflow = zig_subo_u32(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4450 overflow = limb_overflow ^ zig_subo_u32(&res_limb, tmp_limb, overflow ? UINT32_C(1) : UINT32_C(0), limb_bits);
4451 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4452 }
4453
4454 remaining_bytes -= 32 / CHAR_BIT;
4455
4456#if zig_little_endian
4457 byte_offset += 32 / CHAR_BIT;
4458#endif
4459 }
4460
4461 while (remaining_bytes >= 16 / CHAR_BIT) {
4462 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
4463
4464#if zig_big_endian
4465 byte_offset -= 16 / CHAR_BIT;
4466#endif
4467
4468 if (remaining_bytes == 16 / CHAR_BIT && is_signed) {
4469 int16_t res_limb;
4470 int16_t tmp_limb;
4471 int16_t lhs_limb;
4472 int16_t rhs_limb;
4473 bool limb_overflow;
4474
4475 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4476 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4477 limb_overflow = zig_subo_i16(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4478 overflow = limb_overflow ^ zig_subo_i16(&res_limb, tmp_limb, overflow ? INT16_C(1) : INT16_C(0), limb_bits);
4479 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4480 } else {
4481 uint16_t res_limb;
4482 uint16_t tmp_limb;
4483 uint16_t lhs_limb;
4484 uint16_t rhs_limb;
4485 bool limb_overflow;
4486
4487 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4488 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4489 limb_overflow = zig_subo_u16(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4490 overflow = limb_overflow ^ zig_subo_u16(&res_limb, tmp_limb, overflow ? UINT16_C(1) : UINT16_C(0), limb_bits);
4491 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4492 }
4493
4494 remaining_bytes -= 16 / CHAR_BIT;
4495
4496#if zig_little_endian
4497 byte_offset += 16 / CHAR_BIT;
4498#endif
4499 }
4500
4501 while (remaining_bytes >= 8 / CHAR_BIT) {
4502 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
4503
4504#if zig_big_endian
4505 byte_offset -= 8 / CHAR_BIT;
4506#endif
4507
4508 if (remaining_bytes == 8 / CHAR_BIT && is_signed) {
4509 int8_t res_limb;
4510 int8_t tmp_limb;
4511 int8_t lhs_limb;
4512 int8_t rhs_limb;
4513 bool limb_overflow;
4514
4515 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4516 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4517 limb_overflow = zig_subo_i8(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4518 overflow = limb_overflow ^ zig_subo_i8(&res_limb, tmp_limb, overflow ? INT8_C(1) : INT8_C(0), limb_bits);
4519 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4520 } else {
4521 uint8_t res_limb;
4522 uint8_t tmp_limb;
4523 uint8_t lhs_limb;
4524 uint8_t rhs_limb;
4525 bool limb_overflow;
4526
4527 memcpy(&lhs_limb, &lhs_bytes[byte_offset], sizeof(lhs_limb));
4528 memcpy(&rhs_limb, &rhs_bytes[byte_offset], sizeof(rhs_limb));
4529 limb_overflow = zig_subo_u8(&tmp_limb, lhs_limb, rhs_limb, limb_bits);
4530 overflow = limb_overflow ^ zig_subo_u8(&res_limb, tmp_limb, overflow ? UINT8_C(1) : UINT8_C(0), limb_bits);
4531 memcpy(&res_bytes[byte_offset], &res_limb, sizeof(res_limb));
4532 }
4533
4534 remaining_bytes -= 8 / CHAR_BIT;
4535
4536#if zig_little_endian
4537 byte_offset += 8 / CHAR_BIT;
4538#endif
4539 }
4540
4541 return overflow;
4542}
4543
4544static inline void zig_add_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4545 if (zig_addo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow
4546}
4547
4548static inline void zig_addw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4549 (void)zig_addo_big(res, lhs, rhs, is_signed, bits);
4550}
4551
4552static inline void zig_adds_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4553 int8_t sat_sign = zig_signFill_big(lhs, is_signed, bits);
4554
4555 if (!zig_addo_big(res, lhs, rhs, is_signed, bits)) return;
4556 switch (sat_sign) {
4557 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits);
4558 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits);
4559 }
4560}
4561
4562static inline void zig_sub_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4563 if (zig_subo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow
4564}
4565
4566static inline void zig_subw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4567 (void)zig_subo_big(res, lhs, rhs, is_signed, bits);
4568}
4569
4570static inline void zig_subs_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4571 int8_t sat_sign = is_signed ? zig_signFill_big(lhs, is_signed, bits) : -INT8_C(1);
4572
4573 if (!zig_subo_big(res, lhs, rhs, is_signed, bits)) return;
4574 switch (sat_sign) {
4575 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits);
4576 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits);
4577 }
4578}
4579
4580static inline bool zig_mulo_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4581 uint8_t *res_bytes = res;
4582 const uint8_t *lhs_bytes = lhs;
4583 const uint8_t *rhs_bytes = rhs;
4584 uint16_t size = zig_int_bytes(bits);
4585 uint16_t sign_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4586 uint8_t lhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(lhs, is_signed, bits), UINT8_C(8));
4587 uint8_t rhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(rhs, is_signed, bits), UINT8_C(8));
4588 uint16_t lhs_byte_offset = sign_byte_offset;
4589 uint16_t lhs_end_byte_offset = UINT16_C(0);
4590 bool overflow = false;
4591
4592#if zig_big_endian
4593 lhs_byte_offset = size - lhs_byte_offset;
4594 lhs_end_byte_offset = size - lhs_end_byte_offset;
4595#endif
4596
4597 while (lhs_byte_offset != lhs_end_byte_offset) {
4598 uint16_t rhs_byte_offset = UINT16_C(0);
4599 uint16_t end_byte_offset = sign_byte_offset;
4600 uint16_t res_byte_offset;
4601 uint16_t lhs_byte;
4602 uint8_t res_byte = UINT8_C(0);
4603 uint16_t mul_res = UINT16_C(0);
4604 uint8_t carry = UINT8_C(0);
4605
4606#if zig_little_endian
4607 lhs_byte_offset -= UINT16_C(1);
4608#else
4609 rhs_byte_offset = size - rhs_byte_offset;
4610 end_byte_offset = size - end_byte_offset;
4611#endif
4612
4613 lhs_byte = zig_u16_intCast_u8(lhs_bytes[lhs_byte_offset]) ^ lhs_sign_fill;
4614
4615#if zig_big_endian
4616 lhs_byte_offset += UINT16_C(1);
4617#endif
4618
4619 res_byte_offset = lhs_byte_offset;
4620
4621 while (res_byte_offset != end_byte_offset) {
4622 bool res_byte_initialized = res_byte_offset != lhs_byte_offset;
4623
4624#if zig_big_endian
4625 rhs_byte_offset -= UINT16_C(1);
4626 res_byte_offset -= UINT16_C(1);
4627#endif
4628
4629 if (res_byte_initialized) res_byte = res_bytes[res_byte_offset];
4630 carry = zig_addo_u8(&res_byte, res_byte, carry, UINT8_C(8));
4631 carry += zig_addo_u8(&res_byte, res_byte, zig_u8_intCast_u16(
4632 zig_shr_u16(mul_res, UINT8_C(8))
4633 ), UINT8_C(8));
4634 mul_res = lhs_byte * zig_u16_intCast_u8(rhs_bytes[rhs_byte_offset] ^ rhs_sign_fill);
4635 carry += zig_addo_u8(&res_bytes[res_byte_offset], res_byte, zig_u8_truncate_u16(
4636 mul_res,
4637 UINT8_C(8)
4638 ), UINT8_C(8));
4639
4640#if zig_little_endian
4641 rhs_byte_offset += UINT16_C(1);
4642 res_byte_offset += UINT16_C(1);
4643#endif
4644 }
4645
4646 while (rhs_byte_offset != end_byte_offset) {
4647#if zig_big_endian
4648 rhs_byte_offset -= UINT16_C(1);
4649#endif
4650
4651 carry = zig_addo_u8(
4652 &res_byte,
4653 zig_u8_intCast_u16(zig_shr_u16(mul_res, UINT8_C(8))),
4654 carry,
4655 UINT8_C(8)
4656 );
4657 mul_res = lhs_byte * zig_u16_intCast_u8(rhs_bytes[rhs_byte_offset] ^ rhs_sign_fill);
4658 carry += zig_addo_u8(&res_byte, res_byte, zig_u8_truncate_u16(
4659 mul_res,
4660 UINT8_C(8)
4661 ), UINT8_C(8));
4662 overflow |= res_byte != UINT8_C(0);
4663
4664#if zig_little_endian
4665 rhs_byte_offset += UINT16_C(1);
4666#endif
4667 }
4668
4669 overflow |= zig_shr_u16(mul_res, UINT8_C(8)) != UINT16_C(0);
4670 overflow |= carry != UINT8_C(0);
4671 }
4672
4673#if zig_little_endian
4674 sign_byte_offset -= UINT64_C(1);
4675#else
4676 sign_byte_offset = size - sign_byte_offset;
4677#endif
4678
4679 if (lhs_sign_fill != rhs_sign_fill) {
4680 uint16_t byte_offset = UINT16_C(0);
4681 uint16_t end_byte_offset = sign_byte_offset;
4682 uint8_t res_byte;
4683 int8_t signed_res_byte;
4684 uint8_t carry = UINT8_C(0);
4685
4686#if zig_big_endian
4687 byte_offset = size - byte_offset;
4688 end_byte_offset += UINT16_C(1);
4689#endif
4690
4691 while (byte_offset != end_byte_offset) {
4692#if zig_big_endian
4693 byte_offset -= UINT16_C(1);
4694#endif
4695
4696 carry = zig_subo_u8(&res_byte, UINT8_C(0), carry, UINT8_C(8));
4697 carry += zig_subo_u8(&res_byte, res_byte, res_bytes[byte_offset], UINT8_C(8));
4698 carry += zig_subo_u8(
4699 &res_bytes[byte_offset],
4700 res_byte,
4701 (lhs_sign_fill == UINT8_C(0) ? lhs_bytes : rhs_bytes)[byte_offset],
4702 UINT8_C(8)
4703 );
4704
4705#if zig_little_endian
4706 byte_offset += UINT16_C(1);
4707#endif
4708 }
4709
4710#if zig_big_endian
4711 byte_offset -= UINT16_C(1);
4712#endif
4713
4714 signed_res_byte = zig_i8_bitCast_u8(res_bytes[byte_offset], UINT8_C(8));
4715 overflow |= signed_res_byte < INT8_C(0);
4716 overflow |= zig_subo_i8(&signed_res_byte, INT8_C(0), signed_res_byte, UINT8_C(8));
4717 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_intCast_u8(carry), UINT8_C(8));
4718 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8(
4719 (lhs_sign_fill == UINT8_C(0) ? lhs_bytes : rhs_bytes)[byte_offset],
4720 UINT8_C(8)
4721 ), UINT8_C(8));
4722 res_bytes[byte_offset] = zig_i8_bitCast_u8(signed_res_byte, UINT8_C(8));
4723 } else if (lhs_sign_fill != UINT8_C(0)) {
4724 uint16_t byte_offset = UINT16_C(0);
4725 uint16_t end_byte_offset = sign_byte_offset;
4726 uint8_t res_byte;
4727 int8_t signed_res_byte;
4728 uint8_t carry = UINT8_C(1);
4729
4730#if zig_big_endian
4731 byte_offset = size - byte_offset;
4732 end_byte_offset += UINT16_C(1);
4733#endif
4734
4735 while (byte_offset != end_byte_offset) {
4736#if zig_big_endian
4737 byte_offset -= UINT16_C(1);
4738#endif
4739
4740 carry = zig_subo_u8(&res_byte, res_bytes[byte_offset], carry, UINT8_C(8));
4741 carry += zig_subo_u8(&res_byte, res_byte, lhs_bytes[byte_offset], UINT8_C(8));
4742 carry += zig_subo_u8(&res_bytes[byte_offset], res_byte, rhs_bytes[byte_offset], UINT8_C(8));
4743
4744#if zig_little_endian
4745 byte_offset += UINT16_C(1);
4746#endif
4747 }
4748
4749#if zig_big_endian
4750 byte_offset -= UINT16_C(1);
4751#endif
4752
4753 signed_res_byte = zig_i8_bitCast_u8(res_bytes[byte_offset], UINT8_C(8));
4754 overflow |= signed_res_byte < INT8_C(0);
4755 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_intCast_u8(carry), UINT8_C(8));
4756 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8(
4757 lhs_bytes[byte_offset],
4758 UINT8_C(8)
4759 ), UINT8_C(8));
4760 overflow |= zig_subo_i8(&signed_res_byte, signed_res_byte, zig_i8_bitCast_u8(
4761 rhs_bytes[byte_offset],
4762 UINT8_C(8)
4763 ), UINT8_C(8));
4764 res_bytes[byte_offset] = zig_i8_bitCast_u8(signed_res_byte, UINT8_C(8));
4765 } else if (is_signed) {
4766 int8_t signed_res_byte = zig_i8_bitCast_u8(res_bytes[sign_byte_offset], UINT8_C(8));
4767
4768 overflow |= signed_res_byte < INT8_C(0);
4769 }
4770
4771 {
4772 uint8_t truncate_bits = zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4773 uint8_t fill_byte = UINT8_C(0);
4774
4775 if (is_signed) {
4776 int8_t sign_byte = zig_i8_bitCast_u8(res_bytes[sign_byte_offset], UINT8_C(8));
4777 int8_t truncated = zig_i8_truncate_i8(sign_byte, truncate_bits);
4778
4779 overflow |= sign_byte != truncated;
4780 res_bytes[sign_byte_offset] = zig_u8_bitCast_i8(truncated, UINT8_C(8));
4781 fill_byte = zig_u8_bitCast_i8(zig_shr_i8(truncated, UINT8_C(7)), UINT8_C(8));
4782 } else {
4783 uint8_t sign_byte = res_bytes[sign_byte_offset];
4784 uint8_t truncated = zig_u8_truncate_u8(sign_byte, truncate_bits);
4785
4786 overflow |= sign_byte != truncated;
4787 res_bytes[sign_byte_offset] = truncated;
4788 }
4789
4790#if zig_little_endian
4791 sign_byte_offset += UINT16_C(1);
4792 memset(&res_bytes[sign_byte_offset], fill_byte, size - sign_byte_offset);
4793#else
4794 memset(&res_bytes[0], fill_byte, sign_byte_offset);
4795#endif
4796 }
4797
4798 return overflow;
4799}
4800
4801static inline void zig_mul_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4802 if (zig_mulo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: integer overflow
4803}
4804
4805static inline void zig_mulw_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4806 (void)zig_mulo_big(res, lhs, rhs, is_signed, bits);
4807}
4808
4809static inline void zig_muls_big(void *res, const void *lhs, const void *rhs, bool is_signed, uint16_t bits) {
4810 int8_t sat_sign = zig_signFill_big(lhs, is_signed, bits) ^ zig_signFill_big(rhs, is_signed, bits);
4811
4812 if (!zig_mulo_big(res, lhs, rhs, is_signed, bits)) return;
4813 switch (sat_sign) {
4814 case -INT8_C(1): return zig_minInt_big(res, is_signed, bits);
4815 case INT8_C(0): return zig_maxInt_big(res, is_signed, bits);
4816 }
4817}
4818
4819static inline void zig_divTrunc_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4820 if (is_signed) {
4821 zig_extern void __divei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4822 __divei5(res, lhs, rhs, temp, bits);
4823 } else {
4824 zig_extern void __udivei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4825 __udivei5(res, lhs, rhs, temp, bits);
4826 }
4827}
4828
4829static inline void zig_rem_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4830 if (is_signed) {
4831 zig_extern void __modei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4832 __modei5(res, lhs, rhs, temp, bits);
4833 } else {
4834 zig_extern void __umodei5(uint32_t *res, const uint32_t *lhs, const uint32_t *rhs, uint32_t *temp, uintptr_t bits);
4835 __umodei5(res, lhs, rhs, temp, bits);
4836 }
4837}
4838
4839static inline void zig_divFloor_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4840 bool decrement = false;
4841
4842 if (is_signed) {
4843 zig_rem_big(res, lhs, rhs, temp, is_signed, bits);
4844 decrement = zig_u32_bitCast_i32(zig_xor_i32(
4845 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits),
4846 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32)
4847 ), UINT8_C(32)) > zig_u32_bitCast_i32(zig_minInt_i32, UINT8_C(32));
4848 }
4849 zig_divTrunc_big(res, lhs, rhs, temp, is_signed, bits);
4850 if (decrement) zig_decrement_big(res, is_signed, bits);
4851}
4852
4853static inline void zig_divCeil_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4854 bool increment = false;
4855
4856 zig_rem_big(res, lhs, rhs, temp, is_signed, bits);
4857 increment = zig_xor_i32(
4858 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits),
4859 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32)
4860 ) > INT32_C(0);
4861 zig_divTrunc_big(res, lhs, rhs, temp, is_signed, bits);
4862 if (increment) zig_increment_big(res, is_signed, bits);
4863}
4864
4865static inline void zig_mod_big(void *res, const void *lhs, const void *rhs, void *temp, bool is_signed, uint16_t bits) {
4866 bool fixup = false;
4867
4868 zig_rem_big(res, lhs, rhs, temp, is_signed, bits);
4869 if (is_signed && zig_u32_bitCast_i32(zig_xor_i32(
4870 zig_cmp_big_u8(res, UINT8_C(0), is_signed, bits),
4871 zig_and_i32(zig_i32_intCast_i8(zig_signFill_big(rhs, is_signed, bits)), zig_minInt_i32)
4872 ), UINT8_C(32)) > zig_u32_bitCast_i32(zig_minInt_i32, UINT8_C(32))) zig_add_big(res, res, rhs, is_signed, bits);
4873}
4874
4875static inline void zig_shr_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
4876 uint8_t *res_bytes = res;
4877 const uint8_t *lhs_bytes = lhs;
4878 uint16_t size = zig_int_bytes(bits);
4879 uint16_t res_byte_offset = UINT16_C(0);
4880 uint16_t lhs_byte_offset = zig_shr_u16(rhs, UINT8_C(3));
4881 uint16_t end_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4882 uint8_t lhs_prev_byte;
4883 uint8_t byte_shift = zig_u8_truncate_u16(rhs, UINT8_C(3));
4884
4885#if zig_big_endian
4886 res_byte_offset = size - res_byte_offset;
4887 lhs_byte_offset = size - lhs_byte_offset;
4888 end_byte_offset = size - end_byte_offset;
4889#endif
4890
4891 {
4892#if zig_big_endian
4893 lhs_byte_offset -= UINT16_C(1);
4894#endif
4895
4896 lhs_prev_byte = lhs_bytes[lhs_byte_offset];
4897
4898#if zig_little_endian
4899 lhs_byte_offset += UINT16_C(1);
4900#endif
4901 }
4902
4903 while (lhs_byte_offset != end_byte_offset) {
4904#if zig_big_endian
4905 res_byte_offset -= UINT16_C(1);
4906 lhs_byte_offset -= UINT16_C(1);
4907#endif
4908
4909 {
4910 uint8_t lhs_byte = lhs_bytes[lhs_byte_offset];
4911
4912 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16(
4913 zig_shl_u16(zig_u16_intCast_u8(lhs_byte), UINT8_C(8)),
4914 zig_u16_intCast_u8(lhs_prev_byte)
4915 ), byte_shift));
4916 lhs_prev_byte = lhs_byte;
4917 }
4918
4919#if zig_little_endian
4920 res_byte_offset += UINT16_C(1);
4921 lhs_byte_offset += UINT16_C(1);
4922#endif
4923 }
4924
4925 {
4926 uint8_t lhs_sign_fill = UINT8_C(0);
4927
4928#if zig_big_endian
4929 res_byte_offset -= UINT16_C(1);
4930#endif
4931
4932 if (is_signed) {
4933 int8_t signed_byte = zig_i8_bitCast_u8(lhs_prev_byte, UINT8_C(8));
4934
4935 res_bytes[res_byte_offset] = zig_shr_i8(signed_byte, byte_shift);
4936 lhs_sign_fill = zig_u8_bitCast_i8(zig_shr_i8(signed_byte, UINT8_C(7)), UINT8_C(8));
4937 } else {
4938 res_bytes[res_byte_offset] = zig_shr_u8(lhs_prev_byte, byte_shift);
4939 }
4940
4941#if zig_little_endian
4942 res_byte_offset += UINT16_C(1);
4943 memset(&res_bytes[res_byte_offset], lhs_sign_fill, size - res_byte_offset);
4944#else
4945 memset(&res_bytes[0], lhs_sign_fill, res_byte_offset);
4946#endif
4947 }
4948}
4949
4950static inline bool zig_shlo_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
4951 uint8_t *res_bytes = res;
4952 const uint8_t *lhs_bytes = lhs;
4953 uint8_t lhs_sign_fill = zig_u8_bitCast_i8(zig_signFill_big(lhs, is_signed, bits), UINT8_C(8));
4954 uint16_t size = zig_int_bytes(bits);
4955 uint16_t res_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
4956 uint16_t lhs_byte_offset = UINT16_C(0);
4957 uint16_t end_byte_offset = res_byte_offset - UINT16_C(1) - zig_shr_u16(rhs, UINT8_C(3));
4958 uint8_t lhs_prev_byte = lhs_sign_fill;
4959 uint8_t byte_shift = UINT8_C(8) - zig_u8_truncate_u16(rhs, UINT8_C(3));
4960 bool overflow = false;
4961
4962#if zig_little_endian
4963 lhs_byte_offset = size - lhs_byte_offset;
4964#else
4965 res_byte_offset = size - res_byte_offset;
4966 end_byte_offset = size - end_byte_offset;
4967#endif
4968
4969 while (lhs_byte_offset != end_byte_offset) {
4970#if zig_little_endian
4971 lhs_byte_offset -= UINT16_C(1);
4972#endif
4973
4974 overflow |= lhs_prev_byte != lhs_sign_fill;
4975 lhs_prev_byte = lhs_bytes[lhs_byte_offset];
4976
4977#if zig_big_endian
4978 lhs_byte_offset += UINT16_C(1);
4979#endif
4980 }
4981
4982#if zig_little_endian
4983 end_byte_offset = UINT16_C(0);
4984#else
4985 end_byte_offset = size;
4986#endif
4987
4988 {
4989 bool lhs_more_bytes = lhs_byte_offset != end_byte_offset;
4990
4991#if zig_little_endian
4992 if (lhs_more_bytes) lhs_byte_offset -= UINT16_C(1);
4993#endif
4994
4995 {
4996 uint8_t lhs_byte = UINT8_C(0);
4997
4998 if (lhs_more_bytes) lhs_byte = lhs_bytes[lhs_byte_offset];
4999
5000 if (is_signed) {
5001 int16_t shifted = zig_shr_i16(zig_or_i16(
5002 zig_shl_i16(zig_i16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5003 zig_i16_intCast_u8(lhs_byte)
5004 ), byte_shift);
5005 int8_t truncated = zig_i8_truncate_i16(
5006 shifted,
5007 zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1)
5008 );
5009 uint8_t fill = zig_u8_bitCast_i8(zig_shr_i8(truncated, UINT8_C(7)), UINT8_C(8));
5010
5011 overflow |= zig_i16_intCast_i8(truncated) != shifted;
5012#if zig_little_endian
5013 memset(&res_bytes[res_byte_offset], fill, size - res_byte_offset);
5014 res_byte_offset -= UINT16_C(1);
5015#else
5016 memset(&res_bytes[0], fill, res_byte_offset);
5017#endif
5018 res_bytes[res_byte_offset] = zig_u8_bitCast_i8(truncated, UINT8_C(8));
5019 } else {
5020 uint16_t shifted = zig_shr_u16(zig_or_u16(
5021 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5022 zig_u16_intCast_u8(lhs_byte)
5023 ), byte_shift);
5024 uint8_t truncated = zig_u8_truncate_u16(
5025 shifted,
5026 zig_u8_truncate_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT8_C(1)
5027 );
5028
5029 overflow |= zig_u16_intCast_u8(truncated) != shifted;
5030#if zig_little_endian
5031 memset(&res_bytes[res_byte_offset], zig_minInt_u8, size - res_byte_offset);
5032 res_byte_offset -= UINT16_C(1);
5033#else
5034 memset(&res_bytes[0], zig_minInt_u8, res_byte_offset);
5035#endif
5036 res_bytes[res_byte_offset] = truncated;
5037 }
5038
5039 lhs_prev_byte = lhs_byte;
5040 }
5041
5042#if zig_big_endian
5043 res_byte_offset += UINT16_C(1);
5044 if (lhs_more_bytes) lhs_byte_offset += UINT16_C(1);
5045#endif
5046 }
5047
5048 while (lhs_byte_offset != end_byte_offset) {
5049#if zig_little_endian
5050 res_byte_offset -= UINT16_C(1);
5051 lhs_byte_offset -= UINT16_C(1);
5052#endif
5053
5054 {
5055 uint8_t lhs_byte = lhs_bytes[lhs_byte_offset];
5056
5057 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16(
5058 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5059 zig_u16_intCast_u8(lhs_byte)
5060 ), byte_shift));
5061 lhs_prev_byte = lhs_byte;
5062 }
5063
5064#if zig_big_endian
5065 res_byte_offset += UINT16_C(1);
5066 lhs_byte_offset += UINT16_C(1);
5067#endif
5068 }
5069
5070 {
5071#if zig_little_endian
5072 res_byte_offset -= UINT16_C(1);
5073#endif
5074
5075 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(
5076 zig_shl_u16(zig_u16_intCast_u8(lhs_prev_byte), UINT8_C(8)),
5077 byte_shift
5078 ));
5079
5080#if zig_big_endian
5081 res_byte_offset += UINT16_C(1);
5082#endif
5083 }
5084
5085#if zig_little_endian
5086 memset(&res_bytes[0], zig_minInt_u8, res_byte_offset);
5087#else
5088 memset(&res_bytes[res_byte_offset], zig_minInt_u8, size - res_byte_offset);
5089#endif
5090
5091 return overflow;
5092}
5093
5094static inline void zig_shl_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
5095 if (zig_shlo_big(res, lhs, rhs, is_signed, bits)) zig_trap(); // panic: left shift overflowed bits
5096}
5097
5098static inline void zig_shlw_big(void *res, const void *lhs, uint16_t rhs, bool is_signed, uint16_t bits) {
5099 (void)zig_shlo_big(res, lhs, rhs, is_signed, bits);
5100}
5101
5102#define zig_big_shls_builtin(w) \
5103 static inline uint##w##_t zig_shls_u##w##_big(uint##w##_t lhs, const void *rhs, \
5104 uint8_t lhs_bits, bool rhs_is_signed, uint16_t rhs_bits) { \
5105 uint##w##_t res; \
5106 const uint8_t *rhs_bytes = rhs; \
5107 if (zig_cmp_big_u8(rhs, lhs_bits, rhs_is_signed, rhs_bits) < INT32_C(0) && \
5108 !zig_shlo_u##w(&res, lhs, rhs_bytes[0], lhs_bits)) return res; \
5109 return lhs == INT##w##_C(0) ? zig_minInt_u(w, lhs_bits) : zig_maxInt_u(w, lhs_bits); \
5110 } \
5111\
5112 static inline int##w##_t zig_shls_i##w##_big(int##w##_t lhs, const void *rhs, \
5113 uint8_t lhs_bits, bool rhs_is_signed, uint16_t rhs_bits) { \
5114 int##w##_t res; \
5115 const uint8_t *rhs_bytes = rhs; \
5116 if (zig_cmp_big_u8(rhs, lhs_bits, rhs_is_signed, rhs_bits) < INT32_C(0) && \
5117 !zig_shlo_i##w(&res, lhs, rhs_bytes[0], lhs_bits)) return res; \
5118 return lhs == INT##w##_C(0) ? INT##w##_C(0) : \
5119 lhs < INT##w##_C(0) ? zig_minInt_i(w, lhs_bits) : zig_maxInt_i(w, lhs_bits); \
5120 } \
5121\
5122 static inline void zig_shls_big_u##w(void *res, const void *lhs, uint##w##_t rhs, bool is_signed, uint16_t bits) { \
5123 const uint8_t *lhs_bytes = lhs; \
5124 if (rhs < bits && !zig_shlo_big(res, lhs, zig_u16_intCast_u##w(rhs), is_signed, bits)) return; \
5125 switch (zig_cmp_big_u8(lhs, UINT8_C(0), is_signed, bits)) { \
5126 case -INT32_C(1): return zig_minInt_big(res, is_signed, bits); \
5127 case INT32_C(0): return zig_minInt_big(res, false, bits); \
5128 case INT32_C(1): return zig_maxInt_big(res, is_signed, bits); \
5129 default: zig_unreachable(); \
5130 } \
5131 }
5132zig_big_shls_builtin(8)
5133zig_big_shls_builtin(16)
5134zig_big_shls_builtin(32)
5135zig_big_shls_builtin(64)
5136
5137static inline void zig_byteSwap_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
5138 uint8_t *res_bytes = res;
5139 const uint8_t *arg_bytes = arg;
5140 uint16_t res_byte_offset = UINT16_C(0);
5141 uint16_t arg_byte_offset = bits / CHAR_BIT;
5142 uint16_t end_byte_offset = UINT16_C(1);
5143 uint16_t size = zig_int_bytes(bits);
5144
5145#if zig_big_endian
5146 res_byte_offset = size - res_byte_offset;
5147 arg_byte_offset = size - arg_byte_offset;
5148 end_byte_offset = size - end_byte_offset;
5149#endif
5150
5151 while (arg_byte_offset != end_byte_offset) {
5152#if zig_little_endian
5153 arg_byte_offset -= UINT16_C(1);
5154#else
5155 res_byte_offset -= UINT16_C(1);
5156#endif
5157
5158 res_bytes[res_byte_offset] = arg_bytes[arg_byte_offset];
5159
5160#if zig_little_endian
5161 res_byte_offset += UINT16_C(1);
5162#else
5163 arg_byte_offset += UINT16_C(1);
5164#endif
5165 }
5166
5167 {
5168#if zig_little_endian
5169 arg_byte_offset -= UINT16_C(1);
5170#else
5171 res_byte_offset -= UINT16_C(1);
5172#endif
5173
5174 {
5175 uint8_t byte = arg_bytes[arg_byte_offset];
5176 uint8_t fill = is_signed
5177 ? zig_u8_bitCast_i8(zig_shr_i8(zig_i8_bitCast_u8(byte, UINT8_C(8)), UINT8_C(7)), UINT8_C(8))
5178 : UINT8_C(0);
5179
5180 res_bytes[res_byte_offset] = byte;
5181
5182#if zig_little_endian
5183 res_byte_offset += UINT16_C(1);
5184 memset(&res_bytes[res_byte_offset], fill, size - res_byte_offset);
5185#else
5186 memset(&res_bytes[0], fill, res_byte_offset);
5187#endif
5188 }
5189 }
5190}
5191
5192static inline void zig_bitReverse_big(void *res, const void *arg, bool is_signed, uint16_t bits) {
5193 uint8_t *res_bytes = res;
5194 const uint8_t *arg_bytes = arg;
5195 uint16_t size = zig_int_bytes(bits);
5196 uint16_t res_byte_offset = UINT16_C(0);
5197 uint16_t arg_byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
5198 uint16_t end_byte_offset = UINT16_C(0);
5199 uint8_t arg_prev_byte;
5200 uint8_t byte_shift = zig_u8_intCast_u16(zig_subw_u16(UINT16_C(0), bits, UINT8_C(3)));
5201
5202#if zig_big_endian
5203 res_byte_offset = size - res_byte_offset;
5204 arg_byte_offset = size - arg_byte_offset;
5205 end_byte_offset = size - end_byte_offset;
5206#endif
5207
5208 {
5209#if zig_little_endian
5210 arg_byte_offset -= UINT16_C(1);
5211#endif
5212
5213 arg_prev_byte = zig_bitReverse_u8(arg_bytes[arg_byte_offset], UINT8_C(8));
5214
5215#if zig_big_endian
5216 arg_byte_offset += UINT16_C(1);
5217#endif
5218 }
5219
5220 while (arg_byte_offset != end_byte_offset) {
5221#if zig_big_endian
5222 res_byte_offset -= UINT16_C(1);
5223#else
5224 arg_byte_offset -= UINT16_C(1);
5225#endif
5226
5227 {
5228 uint8_t arg_byte = zig_bitReverse_u8(arg_bytes[arg_byte_offset], UINT8_C(8));
5229
5230 res_bytes[res_byte_offset] = zig_u8_intCast_u16(zig_shr_u16(zig_or_u16(
5231 zig_shl_u16(zig_u16_intCast_u8(arg_byte), UINT8_C(8)),
5232 zig_u16_intCast_u8(arg_prev_byte)
5233 ), byte_shift));
5234 arg_prev_byte = arg_byte;
5235 }
5236
5237#if zig_little_endian
5238 res_byte_offset += UINT16_C(1);
5239#else
5240 arg_byte_offset += UINT16_C(1);
5241#endif
5242 }
5243
5244 {
5245 uint8_t arg_sign_fill = UINT8_C(0);
5246
5247#if zig_big_endian
5248 res_byte_offset -= UINT16_C(1);
5249#endif
5250
5251 if (is_signed) {
5252 int8_t signed_byte = zig_i8_bitCast_u8(arg_prev_byte, UINT8_C(8));
5253
5254 res_bytes[res_byte_offset] = zig_shr_i8(signed_byte, byte_shift);
5255 arg_sign_fill = zig_u8_bitCast_i8(zig_shr_i8(signed_byte, UINT8_C(7)), UINT8_C(8));
5256 } else {
5257 res_bytes[res_byte_offset] = zig_shr_u8(arg_prev_byte, byte_shift);
5258 }
5259
5260#if zig_little_endian
5261 res_byte_offset += UINT16_C(1);
5262 memset(&res_bytes[res_byte_offset], arg_sign_fill, size - res_byte_offset);
5263#else
5264 memset(&res_bytes[0], arg_sign_fill, res_byte_offset);
5265#endif
5266 }
5267}
5268
5269static inline uint16_t zig_popCount_big(const void *arg, bool is_signed, uint16_t bits) {
5270 const uint8_t *arg_bytes = arg;
5271 uint16_t byte_offset = 0;
5272 uint16_t remaining_bytes = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
5273 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
5274 uint16_t total_pc = 0;
5275 (void)is_signed;
5276
5277#if zig_big_endian
5278 byte_offset = zig_int_bytes(bits);
5279#endif
5280
5281 while (remaining_bytes >= 128 / CHAR_BIT) {
5282 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
5283
5284#if zig_big_endian
5285 byte_offset -= 128 / CHAR_BIT;
5286#endif
5287
5288 {
5289 zig_u128 arg_limb;
5290
5291 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5292 total_pc += zig_popCount_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits);
5293 }
5294
5295 remaining_bytes -= 128 / CHAR_BIT;
5296
5297#if zig_little_endian
5298 byte_offset += 128 / CHAR_BIT;
5299#endif
5300 }
5301
5302 while (remaining_bytes >= 64 / CHAR_BIT) {
5303 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
5304
5305#if zig_big_endian
5306 byte_offset -= 64 / CHAR_BIT;
5307#endif
5308
5309 {
5310 uint64_t arg_limb;
5311
5312 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5313 total_pc += zig_popCount_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits);
5314 }
5315
5316 remaining_bytes -= 64 / CHAR_BIT;
5317
5318#if zig_little_endian
5319 byte_offset += 64 / CHAR_BIT;
5320#endif
5321 }
5322
5323 while (remaining_bytes >= 32 / CHAR_BIT) {
5324 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
5325
5326#if zig_big_endian
5327 byte_offset -= 32 / CHAR_BIT;
5328#endif
5329
5330 {
5331 uint32_t arg_limb;
5332
5333 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5334 total_pc += zig_popCount_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits);
5335 }
5336
5337 remaining_bytes -= 32 / CHAR_BIT;
5338
5339#if zig_little_endian
5340 byte_offset += 32 / CHAR_BIT;
5341#endif
5342 }
5343
5344 while (remaining_bytes >= 16 / CHAR_BIT) {
5345 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
5346
5347#if zig_big_endian
5348 byte_offset -= 16 / CHAR_BIT;
5349#endif
5350
5351 {
5352 uint16_t arg_limb;
5353
5354 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5355 total_pc += zig_popCount_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits);
5356 }
5357
5358 remaining_bytes -= 16 / CHAR_BIT;
5359
5360#if zig_little_endian
5361 byte_offset += 16 / CHAR_BIT;
5362#endif
5363 }
5364
5365 while (remaining_bytes >= 8 / CHAR_BIT) {
5366 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
5367
5368#if zig_big_endian
5369 byte_offset -= 8 / CHAR_BIT;
5370#endif
5371
5372 {
5373 uint8_t arg_limb;
5374
5375 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5376 total_pc += zig_popCount_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits);
5377 }
5378
5379 remaining_bytes -= 8 / CHAR_BIT;
5380
5381#if zig_little_endian
5382 byte_offset += 8 / CHAR_BIT;
5383#endif
5384 }
5385
5386 return total_pc;
5387}
5388
5389static inline uint16_t zig_ctz_big(const void *arg, bool is_signed, uint16_t bits) {
5390 const uint8_t *arg_bytes = arg;
5391 uint16_t byte_offset = UINT16_C(0);
5392 uint16_t remaining_bytes = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
5393 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
5394 uint16_t total_tz = UINT16_C(0);
5395 uint16_t limb_tz;
5396 (void)is_signed;
5397
5398#if zig_big_endian
5399 byte_offset = zig_int_bytes(bits);
5400#endif
5401
5402 while (remaining_bytes >= 128 / CHAR_BIT) {
5403 uint8_t limb_bits = 128 - (remaining_bytes == 128 / CHAR_BIT ? top_bits : 0);
5404
5405#if zig_big_endian
5406 byte_offset -= 128 / CHAR_BIT;
5407#endif
5408
5409 {
5410 zig_u128 arg_limb;
5411
5412 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5413 limb_tz = zig_ctz_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits);
5414 }
5415
5416 total_tz += limb_tz;
5417 if (limb_tz < limb_bits) return total_tz;
5418 remaining_bytes -= 128 / CHAR_BIT;
5419
5420#if zig_little_endian
5421 byte_offset += 128 / CHAR_BIT;
5422#endif
5423 }
5424
5425 while (remaining_bytes >= 64 / CHAR_BIT) {
5426 uint8_t limb_bits = 64 - (remaining_bytes == 64 / CHAR_BIT ? top_bits : 0);
5427
5428#if zig_big_endian
5429 byte_offset -= 64 / CHAR_BIT;
5430#endif
5431
5432 {
5433 uint64_t arg_limb;
5434
5435 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5436 limb_tz = zig_ctz_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits);
5437 }
5438
5439 total_tz += limb_tz;
5440 if (limb_tz < limb_bits) return total_tz;
5441 remaining_bytes -= 64 / CHAR_BIT;
5442
5443#if zig_little_endian
5444 byte_offset += 64 / CHAR_BIT;
5445#endif
5446 }
5447
5448 while (remaining_bytes >= 32 / CHAR_BIT) {
5449 uint8_t limb_bits = 32 - (remaining_bytes == 32 / CHAR_BIT ? top_bits : 0);
5450
5451#if zig_big_endian
5452 byte_offset -= 32 / CHAR_BIT;
5453#endif
5454
5455 {
5456 uint32_t arg_limb;
5457
5458 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5459 limb_tz = zig_ctz_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits);
5460 }
5461
5462 total_tz += limb_tz;
5463 if (limb_tz < limb_bits) return total_tz;
5464 remaining_bytes -= 32 / CHAR_BIT;
5465
5466#if zig_little_endian
5467 byte_offset += 32 / CHAR_BIT;
5468#endif
5469 }
5470
5471 while (remaining_bytes >= 16 / CHAR_BIT) {
5472 uint8_t limb_bits = 16 - (remaining_bytes == 16 / CHAR_BIT ? top_bits : 0);
5473
5474#if zig_big_endian
5475 byte_offset -= 16 / CHAR_BIT;
5476#endif
5477
5478 {
5479 uint16_t arg_limb;
5480
5481 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5482 limb_tz = zig_ctz_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits);
5483 }
5484
5485 total_tz += limb_tz;
5486 if (limb_tz < limb_bits) return total_tz;
5487 remaining_bytes -= 16 / CHAR_BIT;
5488
5489#if zig_little_endian
5490 byte_offset += 16 / CHAR_BIT;
5491#endif
5492 }
5493
5494 while (remaining_bytes >= 8 / CHAR_BIT) {
5495 uint8_t limb_bits = 8 - (remaining_bytes == 8 / CHAR_BIT ? top_bits : 0);
5496
5497#if zig_big_endian
5498 byte_offset -= 8 / CHAR_BIT;
5499#endif
5500
5501 {
5502 uint8_t arg_limb;
5503
5504 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5505 limb_tz = zig_ctz_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits);
5506 }
5507
5508 total_tz += limb_tz;
5509 if (limb_tz < limb_bits) return total_tz;
5510 remaining_bytes -= 8 / CHAR_BIT;
5511
5512#if zig_little_endian
5513 byte_offset += 8 / CHAR_BIT;
5514#endif
5515 }
5516
5517 return total_tz;
5518}
5519
5520static inline uint16_t zig_clz_big(const void *arg, bool is_signed, uint16_t bits) {
5521 const uint8_t *arg_bytes = arg;
5522 uint16_t byte_offset = zig_shr_u16(bits - UINT16_C(1), UINT8_C(3)) + UINT16_C(1);
5523 uint16_t remaining_bytes = byte_offset;
5524 uint8_t top_bits = zig_u8_intCast_u16(remaining_bytes * CHAR_BIT - bits);
5525 bool sign_limb = true;
5526 uint16_t total_lz = UINT16_C(0);
5527 uint16_t limb_lz;
5528 (void)is_signed;
5529
5530#if zig_big_endian
5531 byte_offset = zig_int_bytes(bits) - remaining_bytes;
5532#endif
5533
5534 while (remaining_bytes >= 128 / CHAR_BIT) {
5535 uint8_t limb_bits = UINT8_C(128) - (sign_limb ? top_bits : UINT8_C(0));
5536
5537#if zig_little_endian
5538 byte_offset -= 128 / CHAR_BIT;
5539#endif
5540
5541 {
5542 zig_u128 arg_limb;
5543
5544 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5545 limb_lz = zig_clz_u128(zig_u128_truncate_u128(arg_limb, limb_bits), limb_bits);
5546 }
5547
5548 total_lz += limb_lz;
5549 if (limb_lz < limb_bits) return total_lz;
5550 sign_limb = false;
5551 remaining_bytes -= 128 / CHAR_BIT;
5552
5553#if zig_big_endian
5554 byte_offset += 128 / CHAR_BIT;
5555#endif
5556 }
5557
5558 while (remaining_bytes >= 64 / CHAR_BIT) {
5559 uint8_t limb_bits = UINT8_C(64) - (sign_limb ? top_bits : UINT8_C(0));
5560
5561#if zig_little_endian
5562 byte_offset -= 64 / CHAR_BIT;
5563#endif
5564
5565 {
5566 uint64_t arg_limb;
5567
5568 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5569 limb_lz = zig_clz_u64(zig_u64_truncate_u64(arg_limb, limb_bits), limb_bits);
5570 }
5571
5572 total_lz += limb_lz;
5573 if (limb_lz < limb_bits) return total_lz;
5574 sign_limb = false;
5575 remaining_bytes -= 64 / CHAR_BIT;
5576
5577#if zig_big_endian
5578 byte_offset += 64 / CHAR_BIT;
5579#endif
5580 }
5581
5582 while (remaining_bytes >= 32 / CHAR_BIT) {
5583 uint8_t limb_bits = UINT8_C(32) - (sign_limb ? top_bits : UINT8_C(0));
5584
5585#if zig_little_endian
5586 byte_offset -= 32 / CHAR_BIT;
5587#endif
5588
5589 {
5590 uint32_t arg_limb;
5591
5592 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5593 limb_lz = zig_clz_u32(zig_u32_truncate_u32(arg_limb, limb_bits), limb_bits);
5594 }
5595
5596 total_lz += limb_lz;
5597 if (limb_lz < limb_bits) return total_lz;
5598 sign_limb = false;
5599 remaining_bytes -= 32 / CHAR_BIT;
5600
5601#if zig_big_endian
5602 byte_offset += 32 / CHAR_BIT;
5603#endif
5604 }
5605
5606 while (remaining_bytes >= 16 / CHAR_BIT) {
5607 uint8_t limb_bits = UINT8_C(16) - (sign_limb ? top_bits : UINT8_C(0));
5608
5609#if zig_little_endian
5610 byte_offset -= 16 / CHAR_BIT;
5611#endif
5612
5613 {
5614 uint16_t arg_limb;
5615
5616 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5617 limb_lz = zig_clz_u16(zig_u16_truncate_u16(arg_limb, limb_bits), limb_bits);
5618 }
5619
5620 total_lz += limb_lz;
5621 if (limb_lz < limb_bits) return total_lz;
5622 sign_limb = false;
5623 remaining_bytes -= 16 / CHAR_BIT;
5624
5625#if zig_big_endian
5626 byte_offset += 16 / CHAR_BIT;
5627#endif
5628 }
5629
5630 while (remaining_bytes >= 8 / CHAR_BIT) {
5631 uint8_t limb_bits = UINT8_C(8) - (sign_limb ? top_bits : UINT8_C(0));
5632
5633#if zig_little_endian
5634 byte_offset -= 8 / CHAR_BIT;
5635#endif
5636
5637 {
5638 uint8_t arg_limb;
5639
5640 memcpy(&arg_limb, &arg_bytes[byte_offset], sizeof(arg_limb));
5641 limb_lz = zig_clz_u8(zig_u8_truncate_u8(arg_limb, limb_bits), limb_bits);
5642 }
5643
5644 total_lz += limb_lz;
5645 if (limb_lz < limb_bits) return total_lz;
5646 sign_limb = false;
5647 remaining_bytes -= 8 / CHAR_BIT;
5648
5649#if zig_big_endian
5650 byte_offset += 8 / CHAR_BIT;
5651#endif
5652 }
5653
5654 return total_lz;
5655}
5656
5657/* ========================= Floating Point Support ========================= */
5658
5659#ifndef __STDC_WANT_IEC_60559_TYPES_EXT__
5660#define __STDC_WANT_IEC_60559_TYPES_EXT__
5661#endif
5662
5663#include <float.h>
5664
5665#if defined(zig_msvc)
5666float __cdecl nanf(char const* input);
5667double __cdecl nan(char const* input);
5668long double __cdecl nanl(char const* input);
5669
5670#define zig_msvc_flt_inf ((double)(1e+300 * 1e+300))
5671#define zig_msvc_flt_inff ((float)(1e+300 * 1e+300))
5672#define zig_msvc_flt_infl ((long double)(1e+300 * 1e+300))
5673#define zig_msvc_flt_nan ((double)(zig_msvc_flt_inf * 0.f))
5674#define zig_msvc_flt_nanf ((float)(zig_msvc_flt_inf * 0.f))
5675#define zig_msvc_flt_nanl ((long double)(zig_msvc_flt_inf * 0.f))
5676#define __builtin_nan(str) nan(str)
5677#define __builtin_nanf(str) nanf(str)
5678#define __builtin_nanl(str) nanl(str)
5679#define __builtin_inf() zig_msvc_flt_inf
5680#define __builtin_inff() zig_msvc_flt_inff
5681#define __builtin_infl() zig_msvc_flt_infl
5682#endif
5683
5684#if (zig_has_builtin(nan) && zig_has_builtin(nans) && zig_has_builtin(inf)) || defined(zig_gcc)
5685#define zig_make_special_f16(sign, name, arg, repr) sign zig_make_f16 (__builtin_##name, )(arg)
5686#define zig_make_special_f32(sign, name, arg, repr) sign zig_make_f32 (__builtin_##name, )(arg)
5687#define zig_make_special_f64(sign, name, arg, repr) sign zig_make_f64 (__builtin_##name, )(arg)
5688#define zig_make_special_f80(sign, name, arg, repr) sign zig_make_f80 (__builtin_##name, )(arg)
5689#define zig_make_special_f128(sign, name, arg, repr) sign zig_make_f128(__builtin_##name, )(arg)
5690#else
5691#define zig_make_special_f16(sign, name, arg, repr) zig_f16_bitCast_u16 (repr)
5692#define zig_make_special_f32(sign, name, arg, repr) zig_f32_bitCast_u32 (repr)
5693#define zig_make_special_f64(sign, name, arg, repr) zig_f64_bitCast_u64 (repr)
5694#define zig_make_special_f80(sign, name, arg, repr) zig_f80_bitCast_u128(repr)
5695#define zig_make_special_f128(sign, name, arg, repr) zig_f128_bitCast_u128(repr)
5696#endif
5697
5698#define zig_has_f16 1
5699#define zig_libc_name_f16(name) __##name##h
5700#define zig_init_special_f16(sign, name, arg, repr) zig_make_special_f16(sign, name, arg, repr)
5701#if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT_MANT_DIG == 11
5702typedef float zig_f16;
5703#define zig_make_f16(fp, repr) fp##f
5704#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && DBL_MANT_DIG == 11
5705typedef double zig_f16;
5706#define zig_make_f16(fp, repr) fp
5707#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && LDBL_MANT_DIG == 11
5708typedef long double zig_f16;
5709#define zig_make_f16(fp, repr) fp##l
5710#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && FLT16_MANT_DIG == 11 && (zig_has_builtin(inff16) || defined(zig_gcc))
5711typedef _Float16 zig_f16;
5712#define zig_make_f16(fp, repr) fp##f16
5713#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F16_ABI) && defined(__SIZEOF_FP16__)
5714typedef __fp16 zig_f16;
5715#define zig_make_f16(fp, repr) fp##f16
5716#else
5717#undef zig_has_f16
5718#define zig_has_f16 0
5719#define zig_repr_f16 u16
5720typedef uint16_t zig_f16;
5721#define zig_make_f16(fp, repr) repr
5722#undef zig_make_special_f16
5723#define zig_make_special_f16(sign, name, arg, repr) repr
5724#undef zig_init_special_f16
5725#define zig_init_special_f16(sign, name, arg, repr) repr
5726#endif
5727
5728#define zig_has_f32 1
5729#define zig_libc_name_f32(name) name##f
5730#if defined(zig_msvc)
5731#define zig_init_special_f32(sign, name, arg, repr) sign zig_make_f32(zig_msvc_flt_##name, )
5732#else
5733#define zig_init_special_f32(sign, name, arg, repr) zig_make_special_f32(sign, name, arg, repr)
5734#endif
5735#if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT_MANT_DIG == 24
5736typedef float zig_f32;
5737#define zig_make_f32(fp, repr) fp##f
5738#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && DBL_MANT_DIG == 24
5739typedef double zig_f32;
5740#define zig_make_f32(fp, repr) fp
5741#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && LDBL_MANT_DIG == 24
5742typedef long double zig_f32;
5743#define zig_make_f32(fp, repr) fp##l
5744#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F32_ABI) && FLT32_MANT_DIG == 24
5745typedef _Float32 zig_f32;
5746#define zig_make_f32(fp, repr) fp##f32
5747#else
5748#undef zig_has_f32
5749#define zig_has_f32 0
5750#define zig_repr_f32 u32
5751typedef uint32_t zig_f32;
5752#define zig_make_f32(fp, repr) repr
5753#undef zig_make_special_f32
5754#define zig_make_special_f32(sign, name, arg, repr) repr
5755#undef zig_init_special_f32
5756#define zig_init_special_f32(sign, name, arg, repr) repr
5757#endif
5758
5759#define zig_has_f64 1
5760#define zig_libc_name_f64(name) name
5761
5762#if defined(zig_msvc)
5763#define zig_init_special_f64(sign, name, arg, repr) sign zig_make_f64(zig_msvc_flt_##name, )
5764#else
5765#define zig_init_special_f64(sign, name, arg, repr) zig_make_special_f64(sign, name, arg, repr)
5766#endif
5767#if !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT_MANT_DIG == 53
5768typedef float zig_f64;
5769#define zig_make_f64(fp, repr) fp##f
5770#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && DBL_MANT_DIG == 53
5771typedef double zig_f64;
5772#define zig_make_f64(fp, repr) fp
5773#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && LDBL_MANT_DIG == 53
5774typedef long double zig_f64;
5775#define zig_make_f64(fp, repr) fp##l
5776#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT64_MANT_DIG == 53
5777typedef _Float64 zig_f64;
5778#define zig_make_f64(fp, repr) fp##f64
5779#elif !defined(ZIG_TARGET_SOFT_COMPILER_RT_F64_ABI) && FLT32X_MANT_DIG == 53
5780typedef _Float32x zig_f64;
5781#define zig_make_f64(fp, repr) fp##f32x
5782#else
5783#undef zig_has_f64
5784#define zig_has_f64 0
5785#define zig_repr_f64 u64
5786typedef uint64_t zig_f64;
5787#define zig_make_f64(fp, repr) repr
5788#undef zig_make_special_f64
5789#define zig_make_special_f64(sign, name, arg, repr) repr
5790#undef zig_init_special_f64
5791#define zig_init_special_f64(sign, name, arg, repr) repr
5792#endif
5793
5794#define zig_has_f80 1
5795#define zig_libc_name_f80(name) __##name##x
5796#define zig_init_special_f80(sign, name, arg, repr) zig_make_special_f80(sign, name, arg, repr)
5797#ifdef ZIG_TARGET_SOFT_COMPILER_RT_F80_ABI
5798#undef zig_has_f80
5799typedef struct { uint64_t mantissa; uint16_t exponent; } zig_f80;
5800#define zig_init_repr_f80(mantissa, exponent) { .mant##issa = mantissa, .expo##nent = exponent }
5801#define zig_make_repr_f80(mantissa, exponent) (zig_f80)zig_init_repr_f80(mantissa, exponent)
5802#define zig_mantissa_repr_f80(arg) (arg).mantissa
5803#define zig_exponent_repr_f80(arg) (arg).exponent
5804#elif FLT_MANT_DIG == 64
5805typedef float zig_f80;
5806#define zig_make_f80(fp, repr) fp##f
5807#elif DBL_MANT_DIG == 64
5808typedef double zig_f80;
5809#define zig_make_f80(fp, repr) fp
5810#elif LDBL_MANT_DIG == 64
5811typedef long double zig_f80;
5812#define zig_make_f80(fp, repr) fp##l
5813#elif FLT80_MANT_DIG == 64
5814typedef _Float80 zig_f80;
5815#define zig_make_f80(fp, repr) fp##f80
5816#elif FLT64X_MANT_DIG == 64
5817typedef _Float64x zig_f80;
5818#define zig_make_f80(fp, repr) fp##f64x
5819#elif defined(__SIZEOF_FLOAT80__)
5820typedef __float80 zig_f80;
5821#define zig_make_f80(fp, repr) fp##l
5822#else
5823#undef zig_has_f80
5824typedef zig_u128 zig_f80;
5825#define zig_init_repr_f80(mantissa, exponent) zig_init_u128(exponent, mantissa)
5826#define zig_make_repr_f80(mantissa, exponent) zig_make_u128(exponent, mantissa)
5827#define zig_mantissa_repr_f80(arg) zig_lo_u128(arg)
5828#define zig_exponent_repr_f80(arg) (uint16_t)zig_hi_u128(arg)
5829#endif
5830#ifndef zig_has_f80
5831#define zig_has_f80 0
5832#define zig_make_f80(fp, repr) repr
5833#ifndef zig_make_repr_f80
5834#define zig_make_repr_f80(mantissa, exponent) (zig_f80)zig_init_repr_f80(mantissa, exponent)
5835#endif
5836#undef zig_make_special_f80
5837#define zig_make_special_f80(sign, name, arg, repr) repr
5838#undef zig_init_special_f80
5839#define zig_init_special_f80(sign, name, arg, repr) repr
5840#endif
5841
5842#define zig_has_f128 1
5843#define zig_libc_name_f128(name) name##f128
5844#define zig_init_special_f128(sign, name, arg, repr) zig_make_special_f128(sign, name, arg, repr)
5845#ifdef ZIG_TARGET_SOFT_COMPILER_RT_F128_ABI
5846#undef zig_has_f128
5847#if zig_little_endian
5848typedef struct { uint64_t lo, hi; } zig_f128;
5849#else
5850typedef struct { uint64_t hi, lo; } zig_f128;
5851#endif
5852#define zig_init_repr_f128(hi, lo) { .h##i = hi, .l##o = lo }
5853#define zig_lo_repr_f128(arg) (arg).lo
5854#define zig_hi_repr_f128(arg) (arg).hi
5855#elif FLT_MANT_DIG == 113
5856typedef float zig_f128;
5857#define zig_make_f128(fp, repr) fp##f
5858#elif DBL_MANT_DIG == 113
5859typedef double zig_f128;
5860#define zig_make_f128(fp, repr) fp
5861#elif LDBL_MANT_DIG == 113
5862typedef long double zig_f128;
5863#define zig_make_f128(fp, repr) fp##l
5864#elif FLT128_MANT_DIG == 113
5865typedef _Float128 zig_f128;
5866#define zig_make_f128(fp, repr) fp##f128
5867#elif FLT64X_MANT_DIG == 113
5868typedef _Float64x zig_f128;
5869#define zig_make_f128(fp, repr) fp##f64x
5870#elif defined(__SIZEOF_FLOAT128__)
5871typedef __float128 zig_f128;
5872#define zig_make_f128(fp, repr) fp##q
5873#undef zig_make_special_f128
5874#define zig_make_special_f128(sign, name, arg, repr) sign __builtin_##name##f128(arg)
5875#else
5876#undef zig_has_f128
5877#if defined(zig_x86_64) && defined(ZIG_TARGET_ABI_MSVC)
5878#if defined(zig_msvc) && !defined(__clang__)
5879#include <emmintrin.h>
5880typedef __m128i zig_f128;
5881#define zig_init_repr_f128(hi, lo) { .m128i_u64 = { lo, hi } }
5882#define zig_lo_repr_f128(arg) (arg).m128i_u64[0]
5883#define zig_hi_repr_f128(arg) (arg).m128i_u64[1]
5884#else
5885typedef __attribute__((__vector_size__(2 * sizeof(uint64_t)))) uint64_t zig_f128;
5886#define zig_init_repr_f128(hi, lo) { lo, hi }
5887#define zig_lo_repr_f128(arg) (arg)[0]
5888#define zig_hi_repr_f128(arg) (arg)[1]
5889#endif
5890#else
5891typedef zig_u128 zig_f128;
5892#define zig_init_repr_f128(hi, lo) zig_init_u128(hi, lo)
5893#define zig_make_repr_f128(hi, lo) zig_make_u128(hi, lo)
5894#define zig_lo_repr_f128(arg) zig_lo_u128(arg)
5895#define zig_hi_repr_f128(arg) zig_hi_u128(arg)
5896#endif
5897#endif
5898#ifndef zig_has_f128
5899#define zig_has_f128 0
5900#define zig_make_f128(fp, repr) repr
5901#ifndef zig_make_repr_f128
5902#define zig_make_repr_f128(hi, lo) (zig_f128)zig_init_repr_f128(hi, lo)
5903#endif
5904#undef zig_make_special_f128
5905#define zig_make_special_f128(sign, name, arg, repr) repr
5906#undef zig_init_special_f128
5907#define zig_init_special_f128(sign, name, arg, repr) repr
5908#endif
5909
5910#if !defined(zig_msvc) && defined(ZIG_TARGET_ABI_MSVC)
5911/* Emulate msvc abi on a gnu compiler */
5912typedef zig_f64 zig_c_longdouble;
5913#elif defined(zig_msvc) && !defined(ZIG_TARGET_ABI_MSVC)
5914/* Emulate gnu abi on an msvc compiler */
5915typedef zig_f128 zig_c_longdouble;
5916#else
5917/* Target and compiler abi match */
5918typedef long double zig_c_longdouble;
5919#endif
5920
5921#if __AVR__
5922typedef signed char zig_FloatCompareResult;
5923#elif defined(zig_aarch64)
5924typedef signed int zig_FloatCompareResult;
5925#elif __SIZEOF_LONG__ >= __SIZEOF_POINTER__
5926typedef signed long zig_FloatCompareResult;
5927#else
5928typedef signed long long zig_FloatCompareResult;
5929#endif
5930
5931#define zig_bitCast_float(w, iw, UnsignedReprType, SignedReprType) \
5932 static inline zig_f##w zig_f##w##_bitCast_u##iw(UnsignedReprType arg) { \
5933 zig_f##w res; \
5934 memcpy(&res, &arg, sizeof(zig_f##w)); \
5935 return res; \
5936 } \
5937 static inline zig_f##w zig_f##w##_bitCast_i##iw(SignedReprType arg) { \
5938 zig_f##w res; \
5939 memcpy(&res, &arg, sizeof(zig_f##w)); \
5940 return res; \
5941 } \
5942 static inline UnsignedReprType zig_u##iw##_bitCast_f##w(zig_f##w arg) { \
5943 UnsignedReprType res; \
5944 memcpy(&res, &arg, sizeof(zig_f##w)); \
5945 return zig_u##iw##_truncate_u##iw(res, w); \
5946 } \
5947 static inline SignedReprType zig_i##iw##_bitCast_f##w(zig_f##w arg) { \
5948 SignedReprType res; \
5949 memcpy(&res, &arg, sizeof(zig_f##w)); \
5950 return zig_i##iw##_truncate_i##iw(res, w); \
5951 }
5952zig_bitCast_float(16, 16, uint16_t, int16_t)
5953zig_bitCast_float(32, 32, uint32_t, int32_t)
5954zig_bitCast_float(64, 64, uint64_t, int64_t)
5955#if zig_has_f80
5956zig_bitCast_float(80, 128, zig_u128, zig_i128)
5957#else
5958static inline zig_f80 zig_f80_bitCast_u128(zig_u128 arg) {
5959 return zig_make_repr_f80(zig_lo_u128(arg), (uint16_t)zig_hi_u128(arg));
5960}
5961static inline zig_f80 zig_f80_bitCast_i128(zig_i128 arg) {
5962 return zig_make_repr_f80(zig_lo_i128(arg), (uint16_t)zig_hi_i128(arg));
5963}
5964static inline zig_u128 zig_u128_bitCast_f80(zig_f80 arg) {
5965 return zig_make_u128(zig_exponent_repr_f80(arg), zig_mantissa_repr_f80(arg));
5966}
5967static inline zig_i128 zig_i128_bitCast_f80(zig_f80 arg) {
5968 return zig_make_i128((int16_t)zig_exponent_repr_f80(arg), zig_mantissa_repr_f80(arg));
5969}
5970#endif
5971static inline zig_f80 zig_f80_bitCast_big(const void *arg) {
5972 return zig_f80_bitCast_u128(zig_u128_truncate_big(arg, UINT8_C(80), false, UINT16_C(80)));
5973}
5974static inline void zig_big_bitCast_f80(void *res, zig_f80 arg, bool res_is_signed, uint16_t res_bits) {
5975 if (res_is_signed) {
5976 zig_big_truncate_i128(res, zig_i128_bitCast_f80(arg), res_is_signed, res_bits);
5977 } else {
5978 zig_big_truncate_u128(res, zig_u128_bitCast_f80(arg), res_is_signed, res_bits);
5979 }
5980}
5981#if zig_has_f128
5982zig_bitCast_float(128, 128, zig_u128, zig_i128)
5983#else
5984static inline zig_f128 zig_f128_bitCast_u128(zig_u128 arg) {
5985 return zig_make_repr_f128(zig_hi_u128(arg), zig_lo_u128(arg));
5986}
5987static inline zig_f128 zig_f128_bitCast_i128(zig_i128 arg) {
5988 return zig_make_repr_f128((uint64_t)zig_hi_i128(arg), zig_lo_i128(arg));
5989}
5990static inline zig_u128 zig_u128_bitCast_f128(zig_f128 arg) {
5991 return zig_make_u128(zig_hi_repr_f128(arg), zig_lo_repr_f128(arg));
5992}
5993static inline zig_i128 zig_i128_bitCast_f128(zig_f128 arg) {
5994 return zig_make_i128((int64_t)zig_hi_repr_f128(arg), zig_lo_repr_f128(arg));
5995}
5996#endif
5997
5998#define zig_convert_float_00(ResType, operation, ArgType, version) \
5999 zig_extern ResType zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
6000 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(ArgType arg); \
6001 return zig_expand_concat(zig_expand_concat(zig_expand_concat(__##operation, \
6002 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType), version)(arg)
6003#define zig_convert_float_01(ResType, operation, ArgType, version) \
6004 zig_convert_float_00(ResType, operation, ArgType, version)
6005#define zig_convert_float_10(ResType, operation, ArgType, version) \
6006 zig_convert_float_00(ResType, operation, ArgType, version)
6007#define zig_convert_float_11(ResType, operation, ArgType, version) \
6008 return (ResType)arg
6009#define zig_convert_float(res_when, ResType, operation, arg_when, ArgType, version) \
6010 static inline ResType zig_expand_concat(zig_expand_concat(zig_##operation, \
6011 zig_compiler_rt_abbrev_##ArgType), zig_compiler_rt_abbrev_##ResType)(ArgType arg) { \
6012 zig_expand_concat(zig_expand_concat(zig_convert_float_, zig_has_##res_when), \
6013 zig_has_##arg_when)(ResType, operation, ArgType, version); \
6014 }
6015
6016#define zig_convert_floats(SmallType, BigType) \
6017 zig_convert_float(SmallType, zig_##SmallType, trunc, BigType, zig_##BigType, 2) \
6018 zig_convert_float(BigType, zig_##BigType, extend, SmallType, zig_##SmallType, 2)
6019zig_convert_floats(f16, f32)
6020zig_convert_floats(f16, f64)
6021zig_convert_floats(f16, f80)
6022zig_convert_floats(f16, f128)
6023zig_convert_floats(f32, f64)
6024zig_convert_floats(f32, f80)
6025zig_convert_floats(f32, f128)
6026zig_convert_floats(f64, f80)
6027zig_convert_floats(f64, f128)
6028zig_convert_floats(f80, f128)
6029
6030#define zig_float_negate_builtin_0(w, sb) \
6031 zig_expand_concat(zig_xor_, zig_repr_f##w)(arg, zig_make_f##w(-0x0.0p0, sb))
6032#define zig_float_negate_builtin_1(w, sb) -arg
6033#define zig_float_negate_builtin(w, sb) \
6034 static inline zig_f##w zig_neg_f##w(zig_f##w arg) { \
6035 return zig_expand_concat(zig_float_negate_builtin_, zig_has_f##w)(w, sb); \
6036 }
6037zig_float_negate_builtin(16, UINT16_C(1) << 15)
6038zig_float_negate_builtin(32, UINT32_C(1) << 31)
6039zig_float_negate_builtin(64, UINT64_C(1) << 63)
6040
6041#undef zig_float_negate_builtin_0
6042#define zig_float_negate_builtin_0(w, sb) \
6043 zig_make_repr_f##w(zig_mantissa_repr_f##w(arg), zig_xor_u16(zig_exponent_repr_f##w(arg), sb))
6044zig_float_negate_builtin(80, UINT16_C(1) << 15)
6045
6046#undef zig_float_negate_builtin_0
6047#define zig_float_negate_builtin_0(w, sb) \
6048 zig_make_repr_f##w(zig_xor_u64(zig_hi_repr_f##w(arg), sb), zig_lo_repr_f##w(arg))
6049zig_float_negate_builtin(128, UINT64_C(1) << 63)
6050
6051#define zig_float_less_builtin_0(Type, operation) \
6052 zig_extern zig_FloatCompareResult zig_expand_concat(zig_expand_concat(__##operation, \
6053 zig_compiler_rt_abbrev_zig_##Type), 2)(zig_##Type, zig_##Type); \
6054 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
6055 return (int32_t)zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_zig_##Type), 2)(lhs, rhs); \
6056 }
6057#define zig_float_less_builtin_1(Type, operation) \
6058 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
6059 return (!(lhs <= rhs) - (lhs < rhs)); \
6060 }
6061
6062#define zig_float_greater_builtin_0(Type, operation) \
6063 zig_float_less_builtin_0(Type, operation)
6064#define zig_float_greater_builtin_1(Type, operation) \
6065 static inline int32_t zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
6066 return ((lhs > rhs) - !(lhs >= rhs)); \
6067 }
6068
6069#define zig_float_binary_builtin_0(Type, operation, operator) \
6070 zig_extern zig_##Type zig_expand_concat(zig_expand_concat(__##operation, \
6071 zig_compiler_rt_abbrev_zig_##Type), 3)(zig_##Type, zig_##Type); \
6072 static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
6073 return zig_expand_concat(zig_expand_concat(__##operation, zig_compiler_rt_abbrev_zig_##Type), 3)(lhs, rhs); \
6074 }
6075#define zig_float_binary_builtin_1(Type, operation, operator) \
6076 static inline zig_##Type zig_##operation##_##Type(zig_##Type lhs, zig_##Type rhs) { \
6077 return lhs operator rhs; \
6078 }
6079
6080#define zig_float_builtins(w) \
6081 zig_common_float_builtins(w) \
6082 zig_convert_float(f##w, zig_f##w, float, int128, zig_i128, ) \
6083 zig_convert_float(f##w, zig_f##w, floatun, int128, zig_u128, )
6084#define zig_common_float_builtins(w) \
6085 zig_convert_float(always, int32_t, fix, f##w, zig_f##w, ) \
6086 zig_convert_float(always, int64_t, fix, f##w, zig_f##w, ) \
6087 zig_convert_float(int128, zig_i128, fix, f##w, zig_f##w, ) \
6088 zig_convert_float(always, uint32_t, fixuns, f##w, zig_f##w, ) \
6089 zig_convert_float(always, uint64_t, fixuns, f##w, zig_f##w, ) \
6090 zig_convert_float(int128, zig_u128, fixuns, f##w, zig_f##w, ) \
6091 zig_convert_float(f##w, zig_f##w, float, always, int32_t, ) \
6092 zig_convert_float(f##w, zig_f##w, float, always, int64_t, ) \
6093 zig_convert_float(f##w, zig_f##w, floatun, always, uint32_t, ) \
6094 zig_convert_float(f##w, zig_f##w, floatun, always, uint64_t, ) \
6095\
6096 static inline void zig_expand_concat(zig_expand_concat(zig_fix, \
6097 zig_compiler_rt_abbrev_zig_f##w), ei)(void *res, zig_f##w arg, uint16_t bits) { \
6098 zig_extern void zig_expand_concat(zig_expand_concat(__fix, \
6099 zig_compiler_rt_abbrev_zig_f##w), ei)(uint8_t *res, uintptr_t bits, zig_f##w arg); \
6100 zig_expand_concat(zig_expand_concat(__fix, \
6101 zig_compiler_rt_abbrev_zig_f##w), ei)(res, bits, arg); \
6102 } \
6103\
6104 static inline void zig_expand_concat(zig_expand_concat(zig_fixuns, \
6105 zig_compiler_rt_abbrev_zig_f##w), ei)(void *res, zig_f##w arg, uint16_t bits) { \
6106 zig_extern void zig_expand_concat(zig_expand_concat(__fixuns, \
6107 zig_compiler_rt_abbrev_zig_f##w), ei)(uint8_t *res, uintptr_t bits, zig_f##w arg); \
6108 zig_expand_concat(zig_expand_concat(__fixuns, \
6109 zig_compiler_rt_abbrev_zig_f##w), ei)(res, bits, arg); \
6110 } \
6111\
6112 static inline zig_f##w zig_expand_concat(zig_floatei, \
6113 zig_compiler_rt_abbrev_zig_f##w)(void *res, uint16_t bits) { \
6114 zig_extern zig_f##w zig_expand_concat(__floatei, \
6115 zig_compiler_rt_abbrev_zig_f##w)(const uint8_t *arg, uintptr_t bits); \
6116 return zig_expand_concat(__floatei, zig_compiler_rt_abbrev_zig_f##w)(res, bits); \
6117 } \
6118\
6119 static inline zig_f##w zig_expand_concat(zig_floatunei, \
6120 zig_compiler_rt_abbrev_zig_f##w)(void *res, uint16_t bits) { \
6121 zig_extern zig_f##w zig_expand_concat(__floatunei, \
6122 zig_compiler_rt_abbrev_zig_f##w)(const uint8_t *arg, uintptr_t bits); \
6123 return zig_expand_concat(__floatunei, zig_compiler_rt_abbrev_zig_f##w)(res, bits); \
6124 } \
6125\
6126 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, cmp) \
6127 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, ne) \
6128 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, eq) \
6129 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, lt) \
6130 zig_expand_concat(zig_float_less_builtin_, zig_has_f##w)(f##w, le) \
6131 zig_expand_concat(zig_float_greater_builtin_, zig_has_f##w)(f##w, gt) \
6132 zig_expand_concat(zig_float_greater_builtin_, zig_has_f##w)(f##w, ge) \
6133 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, add, +) \
6134 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, sub, -) \
6135 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, mul, *) \
6136 zig_expand_concat(zig_float_binary_builtin_, zig_has_f##w)(f##w, div, /) \
6137 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(sqrt)))(zig_f##w, zig_sqrt_f##w, zig_libc_name_f##w(sqrt), (zig_f##w x), (x)) \
6138 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(sin)))(zig_f##w, zig_sin_f##w, zig_libc_name_f##w(sin), (zig_f##w x), (x)) \
6139 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(cos)))(zig_f##w, zig_cos_f##w, zig_libc_name_f##w(cos), (zig_f##w x), (x)) \
6140 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(tan)))(zig_f##w, zig_tan_f##w, zig_libc_name_f##w(tan), (zig_f##w x), (x)) \
6141 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(exp)))(zig_f##w, zig_exp_f##w, zig_libc_name_f##w(exp), (zig_f##w x), (x)) \
6142 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(exp2)))(zig_f##w, zig_exp2_f##w, zig_libc_name_f##w(exp2), (zig_f##w x), (x)) \
6143 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(log)))(zig_f##w, zig_log_f##w, zig_libc_name_f##w(log), (zig_f##w x), (x)) \
6144 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(log2)))(zig_f##w, zig_log2_f##w, zig_libc_name_f##w(log2), (zig_f##w x), (x)) \
6145 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(log10)))(zig_f##w, zig_log10_f##w, zig_libc_name_f##w(log10), (zig_f##w x), (x)) \
6146 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fabs)))(zig_f##w, zig_abs_f##w, zig_libc_name_f##w(fabs), (zig_f##w x), (x)) \
6147 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(floor)))(zig_f##w, zig_floor_f##w, zig_libc_name_f##w(floor), (zig_f##w x), (x)) \
6148 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(ceil)))(zig_f##w, zig_ceil_f##w, zig_libc_name_f##w(ceil), (zig_f##w x), (x)) \
6149 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(round)))(zig_f##w, zig_round_f##w, zig_libc_name_f##w(round), (zig_f##w x), (x)) \
6150 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(trunc)))(zig_f##w, zig_trunc_f##w, zig_libc_name_f##w(trunc), (zig_f##w x), (x)) \
6151 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmod)))(zig_f##w, zig_fmod_f##w, zig_libc_name_f##w(fmod), (zig_f##w x, zig_f##w y), (x, y)) \
6152 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmin)))(zig_f##w, zig_min_f##w, zig_libc_name_f##w(fmin), (zig_f##w x, zig_f##w y), (x, y)) \
6153 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fmax)))(zig_f##w, zig_max_f##w, zig_libc_name_f##w(fmax), (zig_f##w x, zig_f##w y), (x, y)) \
6154 zig_expand_concat(zig_expand_import_, zig_expand_has_builtin(zig_libc_name_f##w(fma)))(zig_f##w, zig_fma_f##w, zig_libc_name_f##w(fma), (zig_f##w x, zig_f##w y, zig_f##w z), (x, y, z)) \
6155\
6156 static inline zig_f##w zig_divTrunc_f##w(zig_f##w lhs, zig_f##w rhs) { \
6157 return zig_trunc_f##w(zig_div_f##w(lhs, rhs)); \
6158 } \
6159\
6160 static inline zig_f##w zig_divFloor_f##w(zig_f##w lhs, zig_f##w rhs) { \
6161 return zig_floor_f##w(zig_div_f##w(lhs, rhs)); \
6162 } \
6163\
6164 static inline zig_f##w zig_divCeil_f##w(zig_f##w lhs, zig_f##w rhs) { \
6165 return zig_ceil_f##w(zig_div_f##w(lhs, rhs)); \
6166 } \
6167\
6168 static inline zig_f##w zig_mod_f##w(zig_f##w lhs, zig_f##w rhs) { \
6169 return zig_sub_f##w(lhs, zig_mul_f##w(zig_divFloor_f##w(lhs, rhs), rhs)); \
6170 }
6171zig_float_builtins(16)
6172zig_float_builtins(32)
6173zig_float_builtins(64)
6174zig_float_builtins(80)
6175#if defined(zig_x86_32)
6176zig_common_float_builtins(128)
6177static inline zig_f128 zig_floattitf(zig_i128 arg) {
6178 extern zig_f128 __floattitf(zig_f128 arg);
6179 return __floattitf(zig_f128_bitCast_i128(arg));
6180}
6181static inline zig_f128 zig_floatuntitf(zig_u128 arg) {
6182 extern zig_f128 __floatuntitf(zig_f128 arg);
6183 return __floatuntitf(zig_f128_bitCast_u128(arg));
6184}
6185#elif defined(zig_x86_64) && defined(zig_windows)
6186zig_common_float_builtins(128)
6187static inline zig_f128 zig_floattitf(zig_i128 arg) {
6188 extern zig_f128 __floattitf(zig_i128 arg);
6189 return __floattitf(arg);
6190}
6191static inline zig_f128 zig_floatuntitf(zig_u128 arg) {
6192 extern zig_f128 __floatuntitf(uint64_t arg_lo, uint64_t arg_hi);
6193 return __floatuntitf(zig_lo_u128(arg), zig_hi_u128(arg));
6194}
6195#else
6196zig_float_builtins(128)
6197#endif
6198
6199/* ============================ Atomics Support ============================= */
6200
6201/* Note that atomics should be implemented as macros because most
6202 compilers silently discard runtime atomic order information. */
6203
6204/* Define fallback implementations first that can later be undef'd on compilers with builtin support. */
6205/* Note that zig_atomicrmw_expected is needed to handle aliasing between res and arg. */
6206#define zig_atomicrmw_xchg_float(res, obj, arg, order, Type, ReprType) do { \
6207 zig_##Type zig_atomicrmw_expected; \
6208 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
6209 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, zig_memory_order_relaxed, Type, ReprType)); \
6210 res = zig_atomicrmw_expected; \
6211} while (0)
6212#define zig_atomicrmw_add_float(res, obj, arg, order, Type, ReprType) do { \
6213 zig_##Type zig_atomicrmw_expected; \
6214 zig_##Type zig_atomicrmw_desired; \
6215 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
6216 do { \
6217 zig_atomicrmw_desired = zig_add_##Type(zig_atomicrmw_expected, arg); \
6218 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
6219 res = zig_atomicrmw_expected; \
6220} while (0)
6221#define zig_atomicrmw_sub_float(res, obj, arg, order, Type, ReprType) do { \
6222 zig_##Type zig_atomicrmw_expected; \
6223 zig_##Type zig_atomicrmw_desired; \
6224 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
6225 do { \
6226 zig_atomicrmw_desired = zig_sub_##Type(zig_atomicrmw_expected, arg); \
6227 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
6228 res = zig_atomicrmw_expected; \
6229} while (0)
6230#define zig_atomicrmw_min_float(res, obj, arg, order, Type, ReprType) do { \
6231 zig_##Type zig_atomicrmw_expected; \
6232 zig_##Type zig_atomicrmw_desired; \
6233 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
6234 do { \
6235 zig_atomicrmw_desired = zig_min_##Type(zig_atomicrmw_expected, arg); \
6236 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
6237 res = zig_atomicrmw_expected; \
6238} while (0)
6239#define zig_atomicrmw_max_float(res, obj, arg, order, Type, ReprType) do { \
6240 zig_##Type zig_atomicrmw_expected; \
6241 zig_##Type zig_atomicrmw_desired; \
6242 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
6243 do { \
6244 zig_atomicrmw_desired = zig_max_##Type(zig_atomicrmw_expected, arg); \
6245 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
6246 res = zig_atomicrmw_expected; \
6247} while (0)
6248
6249#define zig_atomicrmw_xchg_int128(res, obj, arg, order, Type, ReprType) do { \
6250 zig_##Type zig_atomicrmw_expected; \
6251 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
6252 while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, arg, order, zig_memory_order_relaxed, Type, ReprType)); \
6253 res = zig_atomicrmw_expected; \
6254} while (0)
6255#define zig_atomicrmw_add_int128(res, obj, arg, order, Type, ReprType) do { \
6256 zig_##Type zig_atomicrmw_expected; \
6257 zig_##Type zig_atomicrmw_desired; \
6258 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
6259 do { \
6260 zig_atomicrmw_desired = zig_add_##Type(zig_atomicrmw_expected, arg); \
6261 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
6262 res = zig_atomicrmw_expected; \
6263} while (0)
6264#define zig_atomicrmw_sub_int128(res, obj, arg, order, Type, ReprType) do { \
6265 zig_##Type zig_atomicrmw_expected; \
6266 zig_##Type zig_atomicrmw_desired; \
6267 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
6268 do { \
6269 zig_atomicrmw_desired = zig_sub_##Type(zig_atomicrmw_expected, arg); \
6270 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
6271 res = zig_atomicrmw_expected; \
6272} while (0)
6273#define zig_atomicrmw_and_int128(res, obj, arg, order, Type, ReprType) do { \
6274 zig_##Type zig_atomicrmw_expected; \
6275 zig_##Type zig_atomicrmw_desired; \
6276 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
6277 do { \
6278 zig_atomicrmw_desired = zig_and_##Type(zig_atomicrmw_expected, arg); \
6279 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
6280 res = zig_atomicrmw_expected; \
6281} while (0)
6282#define zig_atomicrmw_nand_int128(res, obj, arg, order, Type, ReprType) do { \
6283 zig_##Type zig_atomicrmw_expected; \
6284 zig_##Type zig_atomicrmw_desired; \
6285 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
6286 do { \
6287 zig_atomicrmw_desired = zig_not_##Type(zig_and_##Type(zig_atomicrmw_expected, arg), 128); \
6288 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
6289 res = zig_atomicrmw_expected; \
6290} while (0)
6291#define zig_atomicrmw_or_int128(res, obj, arg, order, Type, ReprType) do { \
6292 zig_##Type zig_atomicrmw_expected; \
6293 zig_##Type zig_atomicrmw_desired; \
6294 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
6295 do { \
6296 zig_atomicrmw_desired = zig_or_##Type(zig_atomicrmw_expected, arg); \
6297 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
6298 res = zig_atomicrmw_expected; \
6299} while (0)
6300#define zig_atomicrmw_xor_int128(res, obj, arg, order, Type, ReprType) do { \
6301 zig_##Type zig_atomicrmw_expected; \
6302 zig_##Type zig_atomicrmw_desired; \
6303 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
6304 do { \
6305 zig_atomicrmw_desired = zig_xor_##Type(zig_atomicrmw_expected, arg); \
6306 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
6307 res = zig_atomicrmw_expected; \
6308} while (0)
6309#define zig_atomicrmw_min_int128(res, obj, arg, order, Type, ReprType) do { \
6310 zig_##Type zig_atomicrmw_expected; \
6311 zig_##Type zig_atomicrmw_desired; \
6312 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
6313 do { \
6314 zig_atomicrmw_desired = zig_min_##Type(zig_atomicrmw_expected, arg); \
6315 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
6316 res = zig_atomicrmw_expected; \
6317} while (0)
6318#define zig_atomicrmw_max_int128(res, obj, arg, order, Type, ReprType) do { \
6319 zig_##Type zig_atomicrmw_expected; \
6320 zig_##Type zig_atomicrmw_desired; \
6321 zig_atomic_load(zig_atomicrmw_expected, obj, zig_memory_order_relaxed, Type, ReprType); \
6322 do { \
6323 zig_atomicrmw_desired = zig_max_##Type(zig_atomicrmw_expected, arg); \
6324 } while (!zig_cmpxchg_weak(obj, zig_atomicrmw_expected, zig_atomicrmw_desired, order, zig_memory_order_relaxed, Type, ReprType)); \
6325 res = zig_atomicrmw_expected; \
6326} while (0)
6327
6328#if (__STDC_VERSION__ >= 201112L && !defined(__STDC_NO_ATOMICS__)) || (zig_has_include(<stdatomic.h>) && !defined(zig_msvc))
6329#define zig_c11_atomics
6330#endif
6331
6332#if defined(zig_c11_atomics)
6333#include <stdatomic.h>
6334typedef enum memory_order zig_memory_order;
6335#define zig_memory_order_relaxed memory_order_relaxed
6336#define zig_memory_order_acquire memory_order_acquire
6337#define zig_memory_order_release memory_order_release
6338#define zig_memory_order_acq_rel memory_order_acq_rel
6339#define zig_memory_order_seq_cst memory_order_seq_cst
6340#define zig_atomic(Type) _Atomic(Type)
6341#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_strong_explicit(obj, &(expected), desired, succ, fail)
6342#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) atomic_compare_exchange_weak_explicit (obj, &(expected), desired, succ, fail)
6343#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) res = atomic_exchange_explicit (obj, arg, order)
6344#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = atomic_fetch_add_explicit (obj, arg, order)
6345#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = atomic_fetch_sub_explicit (obj, arg, order)
6346#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = atomic_fetch_or_explicit (obj, arg, order)
6347#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = atomic_fetch_xor_explicit (obj, arg, order)
6348#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = atomic_fetch_and_explicit (obj, arg, order)
6349#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_nand(obj, arg, order)
6350#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_min (obj, arg, order)
6351#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_max (obj, arg, order)
6352#define zig_atomic_store( obj, arg, order, Type, ReprType) atomic_store_explicit (obj, arg, order)
6353#define zig_atomic_load(res, obj, order, Type, ReprType) res = atomic_load_explicit (obj, order)
6354#undef zig_atomicrmw_xchg_float
6355#define zig_atomicrmw_xchg_float zig_atomicrmw_xchg
6356#undef zig_atomicrmw_add_float
6357#define zig_atomicrmw_add_float zig_atomicrmw_add
6358#undef zig_atomicrmw_sub_float
6359#define zig_atomicrmw_sub_float zig_atomicrmw_sub
6360#elif defined(zig_gnuc)
6361typedef int zig_memory_order;
6362#define zig_memory_order_relaxed __ATOMIC_RELAXED
6363#define zig_memory_order_acquire __ATOMIC_ACQUIRE
6364#define zig_memory_order_release __ATOMIC_RELEASE
6365#define zig_memory_order_acq_rel __ATOMIC_ACQ_REL
6366#define zig_memory_order_seq_cst __ATOMIC_SEQ_CST
6367#define zig_atomic(Type) Type
6368#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, (ReprType *)&(expected), (ReprType *)&(desired), false, succ, fail)
6369#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) __atomic_compare_exchange(obj, (ReprType *)&(expected), (ReprType *)&(desired), true, succ, fail)
6370#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) __atomic_exchange(obj, (ReprType *)&(arg), &(res), order)
6371#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_add (obj, arg, order)
6372#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_sub (obj, arg, order)
6373#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_or (obj, arg, order)
6374#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_xor (obj, arg, order)
6375#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_and (obj, arg, order)
6376#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_nand(obj, arg, order)
6377#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_min (obj, arg, order)
6378#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = __atomic_fetch_max (obj, arg, order)
6379#define zig_atomic_store( obj, arg, order, Type, ReprType) __atomic_store (obj, (ReprType *)&(arg), order)
6380#define zig_atomic_load(res, obj, order, Type, ReprType) __atomic_load (obj, &(res), order)
6381#undef zig_atomicrmw_xchg_float
6382#define zig_atomicrmw_xchg_float zig_atomicrmw_xchg
6383#elif defined(zig_msvc) && defined(zig_x86)
6384#define zig_memory_order_relaxed 0
6385#define zig_memory_order_acquire 2
6386#define zig_memory_order_release 3
6387#define zig_memory_order_acq_rel 4
6388#define zig_memory_order_seq_cst 5
6389#define zig_atomic(Type) Type
6390#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_msvc_cmpxchg_##Type(obj, &(expected), desired)
6391#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) zig_cmpxchg_strong(obj, expected, desired, succ, fail, Type, ReprType)
6392#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_xchg_##Type(obj, arg)
6393#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_add_ ##Type(obj, arg)
6394#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_sub_ ##Type(obj, arg)
6395#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_or_ ##Type(obj, arg)
6396#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_xor_ ##Type(obj, arg)
6397#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_and_ ##Type(obj, arg)
6398#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_nand_##Type(obj, arg)
6399#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_min_ ##Type(obj, arg)
6400#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) res = zig_msvc_atomicrmw_max_ ##Type(obj, arg)
6401#define zig_atomic_store( obj, arg, order, Type, ReprType) zig_msvc_atomic_store_ ##Type(obj, arg)
6402#define zig_atomic_load(res, obj, order, Type, ReprType) res = zig_msvc_atomic_load_ ##order##_##Type(obj)
6403/* TODO: zig_msvc && (zig_thumb || zig_aarch64) */
6404#else
6405#define zig_memory_order_relaxed 0
6406#define zig_memory_order_acquire 2
6407#define zig_memory_order_release 3
6408#define zig_memory_order_acq_rel 4
6409#define zig_memory_order_seq_cst 5
6410#define zig_atomic(Type) Type
6411#define zig_cmpxchg_strong( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable
6412#define zig_cmpxchg_weak( obj, expected, desired, succ, fail, Type, ReprType) zig_atomics_unavailable
6413#define zig_atomicrmw_xchg(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
6414#define zig_atomicrmw_add(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
6415#define zig_atomicrmw_sub(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
6416#define zig_atomicrmw_or(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
6417#define zig_atomicrmw_xor(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
6418#define zig_atomicrmw_and(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
6419#define zig_atomicrmw_nand(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
6420#define zig_atomicrmw_min(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
6421#define zig_atomicrmw_max(res, obj, arg, order, Type, ReprType) zig_atomics_unavailable
6422#define zig_atomic_store( obj, arg, order, Type, ReprType) zig_atomics_unavailable
6423#define zig_atomic_load(res, obj, order, Type, ReprType) zig_atomics_unavailable
6424#endif
6425
6426#if !defined(zig_c11_atomics) && defined(zig_msvc) && defined(zig_x86)
6427
6428/* TODO: zig_msvc_atomic_load should load 32 bit without interlocked on x86, and load 64 bit without interlocked on x64 */
6429
6430#define zig_msvc_atomics(ZigType, Type, SigType, suffix, iso_suffix) \
6431 static inline bool zig_msvc_cmpxchg_##ZigType(Type volatile* obj, Type* expected, Type desired) { \
6432 Type comparand = *expected; \
6433 Type initial = _InterlockedCompareExchange##suffix((SigType volatile*)obj, (SigType)desired, (SigType)comparand); \
6434 bool exchanged = initial == comparand; \
6435 if (!exchanged) { \
6436 *expected = initial; \
6437 } \
6438 return exchanged; \
6439 } \
6440 static inline Type zig_msvc_atomicrmw_xchg_##ZigType(Type volatile* obj, Type value) { \
6441 return _InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \
6442 } \
6443 static inline Type zig_msvc_atomicrmw_add_##ZigType(Type volatile* obj, Type value) { \
6444 return _InterlockedExchangeAdd##suffix((SigType volatile*)obj, (SigType)value); \
6445 } \
6446 static inline Type zig_msvc_atomicrmw_sub_##ZigType(Type volatile* obj, Type value) { \
6447 bool success = false; \
6448 Type new; \
6449 Type prev; \
6450 while (!success) { \
6451 prev = *obj; \
6452 new = prev - value; \
6453 success = zig_msvc_cmpxchg_##ZigType(obj, &prev, new); \
6454 } \
6455 return prev; \
6456 } \
6457 static inline Type zig_msvc_atomicrmw_or_##ZigType(Type volatile* obj, Type value) { \
6458 return _InterlockedOr##suffix((SigType volatile*)obj, (SigType)value); \
6459 } \
6460 static inline Type zig_msvc_atomicrmw_xor_##ZigType(Type volatile* obj, Type value) { \
6461 return _InterlockedXor##suffix((SigType volatile*)obj, (SigType)value); \
6462 } \
6463 static inline Type zig_msvc_atomicrmw_and_##ZigType(Type volatile* obj, Type value) { \
6464 return _InterlockedAnd##suffix((SigType volatile*)obj, (SigType)value); \
6465 } \
6466 static inline Type zig_msvc_atomicrmw_nand_##ZigType(Type volatile* obj, Type value) { \
6467 bool success = false; \
6468 Type new; \
6469 Type prev; \
6470 while (!success) { \
6471 prev = *obj; \
6472 new = ~(prev & value); \
6473 success = zig_msvc_cmpxchg_##ZigType(obj, &prev, new); \
6474 } \
6475 return prev; \
6476 } \
6477 static inline Type zig_msvc_atomicrmw_min_##ZigType(Type volatile* obj, Type value) { \
6478 bool success = false; \
6479 Type new; \
6480 Type prev; \
6481 while (!success) { \
6482 prev = *obj; \
6483 new = value < prev ? value : prev; \
6484 success = zig_msvc_cmpxchg_##ZigType(obj, &prev, new); \
6485 } \
6486 return prev; \
6487 } \
6488 static inline Type zig_msvc_atomicrmw_max_##ZigType(Type volatile* obj, Type value) { \
6489 bool success = false; \
6490 Type new; \
6491 Type prev; \
6492 while (!success) { \
6493 prev = *obj; \
6494 new = value > prev ? value : prev; \
6495 success = zig_msvc_cmpxchg_##ZigType(obj, &prev, new); \
6496 } \
6497 return prev; \
6498 } \
6499 static inline void zig_msvc_atomic_store_##ZigType(Type volatile* obj, Type value) { \
6500 (void)_InterlockedExchange##suffix((SigType volatile*)obj, (SigType)value); \
6501 } \
6502 static inline Type zig_msvc_atomic_load_zig_memory_order_relaxed_##ZigType(Type volatile* obj) { \
6503 return __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
6504 } \
6505 static inline Type zig_msvc_atomic_load_zig_memory_order_acquire_##ZigType(Type volatile* obj) { \
6506 Type value = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
6507 _ReadWriteBarrier(); \
6508 return value; \
6509 } \
6510 static inline Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##ZigType(Type volatile* obj) { \
6511 Type value = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
6512 _ReadWriteBarrier(); \
6513 return value; \
6514 }
6515
6516zig_msvc_atomics( u8, uint8_t, char, 8, 8)
6517zig_msvc_atomics( i8, int8_t, char, 8, 8)
6518zig_msvc_atomics(u16, uint16_t, short, 16, 16)
6519zig_msvc_atomics(i16, int16_t, short, 16, 16)
6520zig_msvc_atomics(u32, uint32_t, long, , 32)
6521zig_msvc_atomics(i32, int32_t, long, , 32)
6522
6523#if defined(zig_x86_64)
6524zig_msvc_atomics(u64, uint64_t, __int64, 64, 64)
6525zig_msvc_atomics(i64, int64_t, __int64, 64, 64)
6526#endif
6527
6528#define zig_msvc_flt_atomics(Type, SigType, suffix, iso_suffix) \
6529 static inline bool zig_msvc_cmpxchg_##Type(zig_##Type volatile* obj, zig_##Type* expected, zig_##Type desired) { \
6530 SigType exchange; \
6531 SigType comparand; \
6532 SigType initial; \
6533 bool success; \
6534 memcpy(&comparand, expected, sizeof(comparand)); \
6535 memcpy(&exchange, &desired, sizeof(exchange)); \
6536 initial = _InterlockedCompareExchange##suffix((SigType volatile*)obj, exchange, comparand); \
6537 success = initial == comparand; \
6538 if (!success) memcpy(expected, &initial, sizeof(*expected)); \
6539 return success; \
6540 } \
6541 static inline void zig_msvc_atomic_store_##Type(zig_##Type volatile* obj, zig_##Type arg) { \
6542 SigType value; \
6543 memcpy(&value, &arg, sizeof(value)); \
6544 (void)_InterlockedExchange##suffix((SigType volatile*)obj, value); \
6545 } \
6546 static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_relaxed_##Type(zig_##Type volatile* obj) { \
6547 zig_##Type result; \
6548 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
6549 memcpy(&result, &initial, sizeof(result)); \
6550 return result; \
6551 } \
6552 static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_acquire_##Type(zig_##Type volatile* obj) { \
6553 zig_##Type result; \
6554 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
6555 _ReadWriteBarrier(); \
6556 memcpy(&result, &initial, sizeof(result)); \
6557 return result; \
6558 } \
6559 static inline zig_##Type zig_msvc_atomic_load_zig_memory_order_seq_cst_##Type(zig_##Type volatile* obj) { \
6560 zig_##Type result; \
6561 SigType initial = __iso_volatile_load##iso_suffix((SigType volatile*)obj); \
6562 _ReadWriteBarrier(); \
6563 memcpy(&result, &initial, sizeof(result)); \
6564 return result; \
6565 }
6566
6567zig_msvc_flt_atomics(f32, long, , 32)
6568#if defined(zig_x86_64)
6569zig_msvc_flt_atomics(f64, int64_t, 64, 64)
6570#endif
6571
6572#if defined(zig_x86_32)
6573static inline void zig_msvc_atomic_barrier() {
6574 int32_t barrier;
6575 __asm {
6576 xchg barrier, eax
6577 }
6578}
6579
6580static inline void* zig_msvc_atomicrmw_xchg_p32(void volatile* obj, void* arg) {
6581 return _InterlockedExchangePointer(obj, arg);
6582}
6583
6584static inline void zig_msvc_atomic_store_p32(void volatile* obj, void* arg) {
6585 (void)_InterlockedExchangePointer(obj, arg);
6586}
6587
6588static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p32(void volatile* obj) {
6589 return (void*)__iso_volatile_load32(obj);
6590}
6591
6592static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p32(void volatile* obj) {
6593 void* value = (void*)__iso_volatile_load32(obj);
6594 _ReadWriteBarrier();
6595 return value;
6596}
6597
6598static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p32(void volatile* obj) {
6599 return zig_msvc_atomic_load_zig_memory_order_acquire_p32(obj);
6600}
6601
6602static inline bool zig_msvc_cmpxchg_p32(void volatile* obj, void* expected, void* desired) {
6603 void* comparand = *(void**)expected;
6604 void* initial = _InterlockedCompareExchangePointer(obj, desired, comparand);
6605 bool success = initial == comparand;
6606 if (!success) *(void**)expected = initial;
6607 return success;
6608}
6609#else /* zig_x86_32 */
6610static inline void* zig_msvc_atomicrmw_xchg_p64(void volatile* obj, void* arg) {
6611 return _InterlockedExchangePointer(obj, arg);
6612}
6613
6614static inline void zig_msvc_atomic_store_p64(void volatile* obj, void* arg) {
6615 (void)_InterlockedExchangePointer(obj, arg);
6616}
6617
6618static inline void* zig_msvc_atomic_load_zig_memory_order_relaxed_p64(void volatile* obj) {
6619 return (void*)__iso_volatile_load64(obj);
6620}
6621
6622static inline void* zig_msvc_atomic_load_zig_memory_order_acquire_p64(void volatile* obj) {
6623 void* value = (void*)__iso_volatile_load64(obj);
6624 _ReadWriteBarrier();
6625 return value;
6626}
6627
6628static inline void* zig_msvc_atomic_load_zig_memory_order_seq_cst_p64(void volatile* obj) {
6629 return zig_msvc_atomic_load_zig_memory_order_acquire_p64(obj);
6630}
6631
6632static inline bool zig_msvc_cmpxchg_p64(void volatile* obj, void* expected, void* desired) {
6633 void* comparand = *(void**)expected;
6634 void* initial = _InterlockedCompareExchangePointer(obj, desired, comparand);
6635 bool success = initial == comparand;
6636 if (!success) *(void**)expected = initial;
6637 return success;
6638}
6639
6640static inline bool zig_msvc_cmpxchg_u128(zig_u128 volatile* obj, zig_u128* expected, zig_u128 desired) {
6641 return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_u128(desired), (__int64)zig_lo_u128(desired), (__int64*)expected);
6642}
6643
6644static inline zig_u128 zig_msvc_atomic_load_u128(zig_u128 volatile* obj) {
6645 zig_u128 expected = zig_make_u128(UINT64_C(0), UINT64_C(0));
6646 (void)zig_cmpxchg_strong(obj, expected, expected, zig_memory_order_seq_cst, zig_memory_order_seq_cst, u128, zig_u128);
6647 return expected;
6648}
6649
6650static inline void zig_msvc_atomic_store_u128(zig_u128 volatile* obj, zig_u128 arg) {
6651 zig_u128 expected = zig_make_u128(UINT64_C(0), UINT64_C(0));
6652 while (!zig_cmpxchg_weak(obj, expected, arg, zig_memory_order_seq_cst, zig_memory_order_seq_cst, u128, zig_u128));
6653}
6654
6655static inline bool zig_msvc_cmpxchg_i128(zig_i128 volatile* obj, zig_i128* expected, zig_i128 desired) {
6656 return _InterlockedCompareExchange128((__int64 volatile*)obj, (__int64)zig_hi_i128(desired), (__int64)zig_lo_i128(desired), (__int64*)expected);
6657}
6658
6659static inline zig_i128 zig_msvc_atomic_load_i128(zig_i128 volatile* obj) {
6660 zig_i128 expected = zig_make_i128(INT64_C(0), UINT64_C(0));
6661 (void)zig_cmpxchg_strong(obj, expected, expected, zig_memory_order_seq_cst, zig_memory_order_seq_cst, i128, zig_i128);
6662 return expected;
6663}
6664
6665static inline void zig_msvc_atomic_store_i128(zig_i128 volatile* obj, zig_i128 arg) {
6666 zig_i128 expected = zig_make_i128(INT64_C(0), UINT64_C(0));
6667 while (!zig_cmpxchg_weak(obj, expected, arg, zig_memory_order_seq_cst, zig_memory_order_seq_cst, i128, zig_i128));
6668}
6669
6670#endif /* zig_x86_32 */
6671
6672#endif /* !zig_c11_atomics && zig_msvc && zig_x86 */
6673
6674/* ======================== Special Case Intrinsics ========================= */
6675
6676#if defined(zig_msvc)
6677#include <intrin.h>
6678#endif
6679
6680static inline void* zig_e_zig_windows_teb(void) zig_mangled(zig_e_zig_windows_teb, "zig_windows_teb");
6681static inline void* zig_e_zig_windows_peb(void) zig_mangled(zig_e_zig_windows_peb, "zig_windows_peb");
6682
6683#if defined(zig_thumb)
6684
6685static inline void* zig_e_zig_windows_teb(void) {
6686 void* teb = 0;
6687#if defined(zig_msvc)
6688 teb = (void*)_MoveFromCoprocessor(15, 0, 13, 0, 2);
6689#elif defined(zig_gnuc_asm)
6690 __asm__ ("mrc p15, 0, %[ptr], c13, c0, 2" : [ptr] "=r" (teb));
6691#endif
6692 return teb;
6693}
6694
6695#elif defined(zig_aarch64)
6696
6697static inline void* zig_e_zig_windows_teb(void) {
6698 void* teb = 0;
6699#if defined(zig_msvc)
6700 teb = (void*)__readx18qword(0x0);
6701#elif defined(zig_gnuc_asm)
6702 __asm__ ("mov %[ptr], x18" : [ptr] "=r" (teb));
6703#endif
6704 return teb;
6705}
6706
6707#elif defined(zig_x86_32)
6708
6709static inline void* zig_e_zig_windows_teb(void) {
6710 void* teb = 0;
6711#if defined(zig_msvc)
6712 teb = (void*)__readfsdword(0x18);
6713#elif defined(zig_gnuc_asm)
6714 __asm__ ("movl %%fs:0x18, %[ptr]" : [ptr] "=r" (teb));
6715#endif
6716 return teb;
6717}
6718
6719static inline void* zig_e_zig_windows_peb(void) {
6720 void* peb = 0;
6721#if defined(zig_msvc)
6722 peb = (void*)__readfsdword(0x30);
6723#elif defined(zig_gnuc_asm)
6724 __asm__ ("movl %%fs:0x30, %[ptr]" : [ptr] "=r" (peb));
6725#endif
6726 return peb;
6727}
6728
6729#elif defined(zig_x86_64)
6730
6731static inline void* zig_e_zig_windows_teb(void) {
6732 void* teb = 0;
6733#if defined(zig_msvc)
6734 teb = (void*)__readgsqword(0x30);
6735#elif defined(zig_gnuc_asm)
6736 __asm__ ("movq %%gs:0x30, %[ptr]" : [ptr] "=r" (teb));
6737#endif
6738 return teb;
6739}
6740
6741static inline void* zig_e_zig_windows_peb(void) {
6742 void* peb = 0;
6743#if defined(zig_msvc)
6744 peb = (void*)__readgsqword(0x60);
6745#elif defined(zig_gnuc_asm)
6746 __asm__ ("movq %%gs:0x60, %[ptr]" : [ptr] "=r" (peb));
6747#endif
6748 return peb;
6749}
6750
6751#endif
6752
6753#if defined(zig_loongarch)
6754
6755static inline void zig_e_zig_loongarch_cpucfg(uint32_t word, uint32_t* result) zig_mangled(zig_e_zig_loongarch_cpucfg, "zig_loongarch_cpucfg");
6756
6757static inline void zig_e_zig_loongarch_cpucfg(uint32_t word, uint32_t* result) {
6758#if defined(zig_gnuc_asm)
6759 __asm__("cpucfg %[result], %[word]" : [result] "=r" (*result) : [word] "r" (word));
6760#else
6761 *result = 0;
6762#endif
6763}
6764
6765#elif defined(zig_x86) && !defined(zig_x86_16)
6766
6767static inline void zig_e_zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) zig_mangled(zig_e_zig_x86_cpuid, "zig_x86_cpuid");
6768static inline uint32_t zig_e_zig_x86_get_xcr0(void) zig_mangled(zig_e_zig_x86_get_xcr0, "zig_x86_get_xcr0");
6769
6770static inline void zig_e_zig_x86_cpuid(uint32_t leaf_id, uint32_t subid, uint32_t* eax, uint32_t* ebx, uint32_t* ecx, uint32_t* edx) {
6771#if defined(zig_msvc)
6772 int cpu_info[4];
6773 __cpuidex(cpu_info, leaf_id, subid);
6774 *eax = (uint32_t)cpu_info[0];
6775 *ebx = (uint32_t)cpu_info[1];
6776 *ecx = (uint32_t)cpu_info[2];
6777 *edx = (uint32_t)cpu_info[3];
6778#elif defined(zig_gnuc_asm)
6779 __asm__("cpuid" : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx) : "a" (leaf_id), "c" (subid));
6780#else
6781 *eax = 0;
6782 *ebx = 0;
6783 *ecx = 0;
6784 *edx = 0;
6785#endif
6786}
6787
6788static inline uint32_t zig_e_zig_x86_get_xcr0(void) {
6789#if defined(zig_msvc)
6790 return (uint32_t)_xgetbv(0);
6791#elif defined(zig_gnuc_asm)
6792 uint32_t eax;
6793 uint32_t edx;
6794 __asm__("xgetbv" : "=a" (eax), "=d" (edx) : "c" (0));
6795 return eax;
6796#else
6797 *eax = 0;
6798 *ebx = 0;
6799 *ecx = 0;
6800 *edx = 0;
6801#endif
6802}
6803
6804#endif