2 * Copyright (C) 2024 Mikulas Patocka
4 * This file is part of Ajla.
6 * Ajla is free software: you can redistribute it and/or modify it under the
7 * terms of the GNU General Public License as published by the Free Software
8 * Foundation, either version 3 of the License, or (at your option) any later
11 * Ajla is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * Ajla. If not, see <https://www.gnu.org/licenses/>.
22 #ifdef HAVE_INTTYPES_H
28 #ifdef HAVE_INT_T_U_INT_T
30 typedef u_int8_t
uint8_t;
31 typedef u_int16_t
uint16_t;
32 typedef u_int32_t
uint32_t;
36 typedef signed char int8_t;
37 typedef unsigned char uint8_t;
39 #if SIZEOF_UNSIGNED_SHORT == 2
40 typedef signed short int16_t;
41 typedef unsigned short uint16_t;
46 #if SIZEOF_UNSIGNED == 4
47 typedef signed int32_t;
48 typedef unsigned uint32_t;
49 #elif SIZEOF_UNSIGNED_LONG == 4
50 typedef signed long int32_t;
51 typedef unsigned long uint32_t;
58 #if defined(SIZEOF_UNSIGNED) && defined(SIZEOF_VOID_P) && SIZEOF_UNSIGNED && SIZEOF_UNSIGNED == SIZEOF_VOID_P
60 typedef unsigned uintptr_t;
61 #elif defined(SIZEOF_UNSIGNED_LONG) && defined(SIZEOF_VOID_P) && SIZEOF_UNSIGNED_LONG && SIZEOF_UNSIGNED_LONG == SIZEOF_VOID_P
62 typedef long intptr_t;
63 typedef unsigned long uintptr_t;
64 #elif defined(SIZEOF_UNSIGNED_LONG_LONG) && defined(SIZEOF_VOID_P) && SIZEOF_UNSIGNED_LONG_LONG && SIZEOF_UNSIGNED_LONG_LONG == SIZEOF_VOID_P
65 typedef long long intptr_t;
66 typedef unsigned long long uintptr_t;
68 typedef long intptr_t;
69 typedef unsigned long uintptr_t;
73 #ifndef HAVE_INT64_T_UINT64_T
74 #ifdef HAVE_INT64_T_U_INT64_T
75 typedef u_int64_t
uint64_t;
76 #define HAVE_INT64_T_UINT64_T 1
77 #elif defined(SIZEOF_UNSIGNED_LONG) && SIZEOF_UNSIGNED_LONG == 8
78 typedef signed long int64_t;
79 typedef unsigned long uint64_t;
80 #define HAVE_INT64_T_UINT64_T 1
81 #elif defined(SIZEOF_UNSIGNED_LONG_LONG) && SIZEOF_UNSIGNED_LONG_LONG == 8
82 typedef signed long long int64_t;
83 typedef unsigned long long uint64_t;
84 #define HAVE_INT64_T_UINT64_T 1
85 #elif defined(_MSC_VER) || defined(__BORLANDC__)
86 typedef signed __int64
int64_t;
87 typedef unsigned __int64
uint64_t;
88 #define HAVE_INT64_T_UINT64_T 1
92 #ifdef HAVE_INT64_T_UINT64_T
93 typedef int64_t intmax_t;
94 typedef uint64_t uintmax_t;
96 typedef long intmax_t;
97 typedef unsigned long uintmax_t;
103 #if defined(SIZEOF_UNSIGNED___INT128) && SIZEOF_UNSIGNED___INT128 > 8
104 typedef __int128 intbig_t
;
105 typedef unsigned __int128 uintbig_t
;
107 typedef intmax_t intbig_t
;
108 typedef uintmax_t uintbig_t
;
145 #ifdef HAVE_LONG_LONG
146 #define PRIdMAX "lld"
153 #ifdef HAVE_LONG_LONG
154 #define PRIuMAX "llu"
161 #ifdef HAVE_LONG_LONG
162 #define PRIxMAX "llx"
169 #ifdef HAVE_LONG_LONG
170 #define PRIXMAX "llX"
177 #ifdef HAVE_STDBOOL_H
180 #ifndef __bool_true_false_are_defined
186 #ifndef HAVE_SOCKLEN_T
187 #define socklen_t int
190 #ifndef HAVE_SIG_ATOMIC_T
191 #define sig_atomic_t int
194 #ifdef HAVE_C11_ATOMICS
196 #include <stdatomic.h>
198 #define atomic_type _Atomic
199 #define load_relaxed(p) atomic_load_explicit(p, memory_order_relaxed)
200 #define store_relaxed(p, v) atomic_store_explicit(p, v, memory_order_relaxed)
202 #define atomic_type volatile
203 #define load_relaxed(p) (*(p))
204 #define store_relaxed(p, v) (*(p) = (v))
208 #if defined(SIZEOF_VOID_P) && SIZEOF_VOID_P > 0
209 #if SIZEOF_VOID_P >= 8
212 #elif defined(__INITIAL_POINTER_SIZE)
213 #if __INITIAL_POINTER_SIZE >= 64
216 #elif defined(_LP64) || defined(__LP64__) || defined(_WIN64)
221 #ifndef UNUSUAL_UNKNOWN_ENDIAN
222 #if defined(CONFIG_LITTLE_ENDIAN)
223 #define C_LITTLE_ENDIAN
224 #elif defined(CONFIG_BIG_ENDIAN)
226 #elif defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
227 #define C_LITTLE_ENDIAN
228 #elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
234 #define extern_const const
237 #define stringify_internal(arg) #arg
238 #define stringify(arg) stringify_internal(arg)
239 #define file_line __FILE__ ":" stringify(__LINE__)
243 * The defined() operator in macro expansion is not portable.
245 #if defined(__GNUC__) && defined(__GNUC_MINOR__)
246 #define DEFINED___GNUC____GNUC_MINOR__ 1
248 #define DEFINED___GNUC____GNUC_MINOR__ 0
251 #if defined(__GNUC_PATCHLEVEL__)
252 #define DEFINED___GNUC_PATCHLEVEL__ 1
254 #define DEFINED___GNUC_PATCHLEVEL__ 0
257 #define GNUC_ATLEAST(x, y, z) \
258 (DEFINED___GNUC____GNUC_MINOR__ && \
260 (__GNUC__ == (x) && \
261 (__GNUC_MINOR__ > (y) || \
262 (__GNUC_MINOR__ == (y) && \
263 (!DEFINED___GNUC_PATCHLEVEL__ || \
264 __GNUC_PATCHLEVEL__ >= (z) \
272 #if defined(__clang__) && defined(__clang_major__) && defined(__clang_minor__)
273 #define DEFINED___CLANG____CLANG_MAJOR____CLANG_MINOR__ 1
275 #define DEFINED___CLANG____CLANG_MAJOR____CLANG_MINOR__ 0
278 #if defined(__clang_patchlevel__)
279 #define DEFINED___CLANG_PATCHLEVEL__ 1
281 #define DEFINED___CLANG_PATCHLEVEL__ 0
284 #define CLANG_ATLEAST(x, y, z) \
285 (DEFINED___CLANG____CLANG_MAJOR____CLANG_MINOR__ && \
286 (__clang_major__ > (x) || \
287 (__clang_major__ == (x) && \
288 (__clang_minor__ > (y) || \
289 (__clang_minor__ == (y) && \
290 (!DEFINED___CLANG_PATCHLEVEL__ || \
291 __clang_patchlevel__ >= (z) \
299 #if defined(__GNUC__) && !(defined(__clang__) || defined(__llvm__) || defined(__ICC) || defined(__OPEN64__) || defined(__PATHSCALE__) || defined(__PGI) || defined(__PGIC__))
300 #define HAVE_REAL_GNUC
303 #if GNUC_ATLEAST(2,0,0)
304 #define return_address __builtin_return_address(0)
307 #if GNUC_ATLEAST(2,0,0)
308 #define is_constant(expression) __builtin_constant_p(expression)
310 #define is_constant(expression) (false)
313 #if defined(__GNUC__) && defined(__GNUC_MINOR__) && __GNUC__ == 2 && __GNUC_MINOR__ <= 7
315 * Verify that the __attribute__ directive is properly placed. GCC 2 has more
316 * strict attribute placing rules than gcc 3 and following versions.
318 * egcs crashes on empty __attribute__ directive
320 #define attr_nothing __attribute__(())
325 #if GNUC_ATLEAST(2,0,0)
326 #define attr_unaligned __attribute__((packed))
329 #if GNUC_ATLEAST(2,0,0) && !defined(__MINGW32__)
330 #define attr_printf(x, y) __attribute__((format(printf, x, y)))
332 #define attr_printf(x, y)
335 #if defined(HAVE_STDNORETURN_H) && !defined(__cplusplus) && !defined(__ICC)
336 #include <stdnoreturn.h>
337 #define attr_noreturn noreturn void
338 #elif GNUC_ATLEAST(2,5,0)
339 #define attr_noreturn void __attribute__((noreturn))
340 #elif defined(_MSC_VER) && _MSC_VER >= 1600 /* not sure */
341 #define attr_noreturn void __declspec(noreturn)
343 #define attr_noreturn void
346 #if GNUC_ATLEAST(2,7,0)
347 #define attr_unused __attribute__((__unused__))
349 #define attr_unused attr_nothing
352 #if GNUC_ATLEAST(2,96,0)
353 #define likely(x) (__builtin_expect((int)(x), 1))
354 #define unlikely(x) (__builtin_expect((int)(x), 0))
356 #define likely(x) ((int)(x))
357 #define unlikely(x) ((int)(x))
360 #if GNUC_ATLEAST(3,0,0) && !defined(__DJGPP__) /* not sure */
361 #define attr_aligned(x) __attribute__((__aligned__(x)))
362 #elif defined(_MSC_VER) && _MSC_VER >= 1600 /* not sure */
363 #define attr_aligned(x) __declspec(align(x))
365 #define attr_aligned(x) attr_nothing
368 #if GNUC_ATLEAST(3,1,0)
369 #define attr_noinline __attribute__((__noinline__))
370 #elif defined(_MSC_VER) && _MSC_VER >= 1600 /* not sure */
371 #define attr_noinline __declspec(noinline)
373 #define attr_noinline
376 #if GNUC_ATLEAST(3,1,0)
377 #define attr_always_inline inline __attribute__((__always_inline__))
378 #elif defined(_MSC_VER) && _MSC_VER >= 1600 /* not sure */
379 #define attr_always_inline __forceinline
381 #define attr_always_inline inline
384 #if defined(HAVE_REAL_GNUC) && !defined(UNUSUAL)
388 #if GNUC_ATLEAST(3,4,0)
389 #define attr_w __attribute__((__warn_unused_result__))
391 #define attr_w attr_nothing
394 #if GNUC_ATLEAST(4,3,0)
395 #define attr_cold __attribute__((__noinline__,__cold__))
396 #define attr_hot __attribute__((/*__hot__*/))
397 #elif GNUC_ATLEAST(3,1,0)
398 #define attr_cold __attribute__((__noinline__))
399 #define attr_hot attr_nothing
401 #define attr_cold attr_nothing
402 #define attr_hot attr_nothing
405 #if GNUC_ATLEAST(4,5,0)
406 #define attr_noclone __attribute__((__noclone__))
408 #define attr_noclone attr_nothing
411 #if GNUC_ATLEAST(3,0,0) && !defined(__PCC__) && defined(__i386__)
412 #if GNUC_ATLEAST(4,1,0) && defined(HAVE_REAL_GNUC) && defined(__SSE__) && defined(__SSE_MATH__)
413 #define attr_fastcall __attribute__((__regparm__(3),__sseregparm__))
415 #define attr_fastcall __attribute__((__regparm__(3)))
417 #elif GNUC_ATLEAST(4,4,0) && defined(__x86_64__) && (defined(__CYGWIN__) || defined(__WIN32))
418 /*#define attr_fastcall __attribute__((__sysv_abi__))*/
419 #define attr_fastcall attr_nothing
420 #elif defined(_MSC_VER)
421 #define attr_fastcall __fastcall
422 #elif defined(__TURBOC__) || defined(__BORLANDC__)
423 #define attr_fastcall __fastcall
425 #define attr_fastcall attr_nothing
428 #define attr_hot_fastcall attr_hot attr_fastcall
430 #if defined(__GNUC__) && defined(__OPTIMIZE__) && !defined(__OPEN64__)
431 attr_noreturn
not_reached(void);
433 #define not_reached() internal(file_line, "this location should not be reached")
436 /* Borland C has preprocessor expansion size limits */
437 #if (defined(__TURBOC__) || defined(__BORLANDC__)) && !defined(__BIGGEST_ALIGNMENT__)
438 #define __BIGGEST_ALIGNMENT__ 8
441 #define HEAP_ALIGN (is_power_of_2(sizeof(void *)) ? sizeof(void *) * 2 : 16)
443 #if GNUC_ATLEAST(1,36,0)
444 #define align_of(type) __alignof__(type)
445 #elif defined(HAVE_STDALIGN_H)
446 #include <stdalign.h>
447 #define align_of(type) alignof(type)
449 #define align_of(type) minimum(HEAP_ALIGN, \
450 !sizeof(type) ? 1 : \
451 sizeof(type) & -sizeof(type))
454 #if defined(__STDC__) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901
455 #define FLEXIBLE_ARRAY
456 #elif defined(__GNUC__) && !defined(GNUC_PEDANTIC)
457 #define FLEXIBLE_ARRAY 0
459 #define FLEXIBLE_ARRAY 1
462 #if defined(__GNUC__) && !defined(GNUC_PEDANTIC)
463 #define FLEXIBLE_ARRAY_GCC 0
464 #define EMPTY_TYPE struct { }
466 #define FLEXIBLE_ARRAY_GCC 1
467 #define EMPTY_TYPE char
470 static attr_always_inline
void *return_ptr(const void *ptr
)
475 #if defined(HAVE_REAL_GNUC)
476 #define cast_ptr(type, ptr) ((type)return_ptr(ptr))
478 #define cast_ptr(type, ptr) ((type)(void *)(ptr))
482 #define cast_cpp cast_ptr
484 #define cast_cpp(type, ptr) (ptr)
487 #ifndef HAVE___BUILTIN_ASSUME_ALIGNED
488 #define __builtin_assume_aligned(p, align) (p)
493 * We allocate partial structures with union as the last member.
494 * If this causes problems with any compiler, enable this.
497 #define partial_sizeof_lower_bound(full) sizeof(full)
498 #define partial_sizeof(full, part) sizeof(full)
499 #define partial_sizeof_array(full, part, extra) maximum_maybe0(sizeof(full), (offsetof(full, part) + (extra) * sizeof(((full *)NULL)->part[0])))
501 #define partial_sizeof_lower_bound(full) ((size_t)0)
502 #define partial_sizeof(full, part) (offsetof(full, part) + sizeof(((full *)NULL)->part))
503 #define partial_sizeof_array(full, part, extra) (offsetof(full, part) + (extra) * sizeof(((full *)NULL)->part[0]))
506 #if defined(_MSC_VER)
507 #define barrier_aliasing() do { } while (0)
508 #elif defined(HAVE_GCC_ASSEMBLER)
509 #define barrier_aliasing() __asm__ volatile ("":::"memory")
511 #define NEED_EXPLICIT_ALIASING_BARRIER
512 extern volatile char * volatile alias_ptr
;
513 #define barrier_aliasing() \
519 #if defined(HAVE_GCC_ASSEMBLER)
520 #define ASM_PREVENT_CSE __asm__ volatile ("":::"memory")
522 #define ASM_PREVENT_CSE do { } while (0)
525 #if defined(HAVE_GCC_ASSEMBLER) && 0
526 #define ASM_PREVENT_JOIN(i) __asm__ (""::"i"(i))
528 #define ASM_PREVENT_JOIN(i) do { } while (0)
531 #if defined(HAVE_GCC_ASSEMBLER)
532 #define asm_copy(dest, src) __asm__ volatile (".if 0 \n .endif" : "=r"(dest) : "0"(src))
535 #if !defined(HAVE_INT64_T_UINT64_T)
536 #define EFFICIENT_WORD_SIZE 32
537 #elif defined(BIT64) || defined(__x86_64__) || defined(__aarch64__) || (defined(_PA_RISC2_0) && defined(__HP_cc)) || (defined(__VMS) && !defined(__VAX))
538 #define EFFICIENT_WORD_SIZE 64
540 #define EFFICIENT_WORD_SIZE 32
543 #define int_efficient_t cat4(int,EFFICIENT_WORD_SIZE,_,t)
544 #define uint_efficient_t cat4(uint,EFFICIENT_WORD_SIZE,_,t)
546 #if defined(__alpha__) && !defined(__alpha_bwx__)
547 typedef int32_t char_efficient_t
;
548 typedef uint32_t uchar_efficient_t
;
549 typedef int32_t short_efficient_t
;
550 typedef uint32_t ushort_efficient_t
;
552 typedef int8_t char_efficient_t
;
553 typedef uint8_t uchar_efficient_t
;
554 typedef int16_t short_efficient_t
;
555 typedef uint16_t ushort_efficient_t
;
559 #if defined(HAVE_COMPUTED_GOTO) && defined(__clang__) && 0
560 /* Clang supports computed goto but it increases compilation time extremely. */
561 #undef HAVE_COMPUTED_GOTO
564 #if defined(HAVE_COMPUTED_GOTO) && defined(GNUC_PEDANTIC)
565 #undef HAVE_COMPUTED_GOTO
569 #if !defined(UNUSUAL_NO_ASSEMBLER)
571 #if defined(HAVE_GCC_ASSEMBLER) && (defined(__i386__) || defined(__x86_64__))
574 #ifdef HAVE_GCC_ASSEMBLER
575 #define INLINE_ASM_GCC_X86
578 #if defined(__i386__)
580 #define ARCH_NAME "i386"
581 #ifdef HAVE_GCC_ASSEMBLER
582 #define INLINE_ASM_GCC_I386
584 #elif defined(__x86_64__) && !defined(__ILP32__)
586 #define ARCH_NAME "x86_64"
587 #ifdef HAVE_GCC_ASSEMBLER
588 #define INLINE_ASM_GCC_X86_64
592 #define ARCH_NAME "x86_x32"
593 #ifdef HAVE_GCC_ASSEMBLER
594 #define INLINE_ASM_GCC_X32
598 #ifdef HAVE_GCC_ASSEMBLER
600 #if defined(__clang__) || defined(__llvm__) || !GNUC_ATLEAST(4,0,0) /* !!! TODO: check GCC version exactly */
602 * LLVM has inefficient "rm" implementation - it always references memory
603 * on the stack - https://bugs.llvm.org/show_bug.cgi?id=9723
605 * gcc 2.7 and 3.0 can't concatenate strings in asm constraint
609 #define X86_ASM_M "m"
613 #define X86_ASM_XMM0_CLOB
614 #define X86_ASM_XMM0_CLOBC
615 #define X86_ASM_XMM1_CLOBC
617 #define X86_ASM_XMM0_CLOB : "xmm0"
618 #define X86_ASM_XMM0_CLOBC , "xmm0"
619 #define X86_ASM_XMM1_CLOBC , "xmm1"
624 #define X86_ASM_AVX_PARAM(x) #x
626 #define X86_ASM_V "v"
627 #define X86_ASM_AVX_PARAM(x) #x ", " #x
632 #elif defined(_M_IX86)
636 #define ARCH_NAME "i386"
638 #elif defined(_M_X64)
642 #define ARCH_NAME "x86_64"
644 #elif defined(__alpha__)
647 #define ARCH_NAME "alpha"
649 #elif (defined(__arm__) && defined(__ARM_EABI__) && (!defined(__thumb__) || defined(__thumb2__))) || defined(__aarch64__)
654 #define ARCH_NAME "aarchc64"
657 #define ARCH_NAME "arm"
661 #define ARM_VERSION __ARM_ARCH
662 #elif defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_8A)
663 #define ARM_VERSION 8
664 #elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
665 #define ARM_VERSION 7
666 #elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) || defined(__ARM_ARCH_6M__)
667 #define ARM_VERSION 6
668 #elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5E__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__)
669 #define ARM_VERSION 5
670 #elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) || defined(__ARM_ARCH_3M__)
671 #define ARM_VERSION 4
672 #elif defined(__ARM_ARCH_3__)
673 #define ARM_VERSION 3
674 #elif defined(__ARM_ARCH_2__)
675 #define ARM_VERSION 2
677 #define ARM_VERSION 1
678 #define ARM_VERSION_UNKNOWN
681 #if defined(HAVE_GCC_ASSEMBLER) && defined(HAVE_ARM_ASSEMBLER) && !defined(ARCH_ARM64)
682 #define INLINE_ASM_GCC_ARM
684 #define ARM_ASM_PREFIX ".cpu cortex-a15\n .fpu neon-vfpv4\n;;;;;;;;;;;;;;;;\n"
686 #define ARM_ASM_PREFIX ".fpu neon-vfpv4\n;;;;;;;;;;;;;;;;\n"
688 #define ARM_ASM_APSR "apsr"
689 #define ARM_ASM_LO "Q"
690 #define ARM_ASM_HI "R"
691 #if !defined(__thumb2__)
693 #define ARM_ASM_S_CLOB
694 #define ARM_ASM_IF_T12(x,y) y
696 #define INLINE_ASM_GCC_ARM_THUMB2
697 #define ARM_ASM_STRD "strd"
698 #define ARM_ASM_S "s"
699 #define ARM_ASM_S_CLOB : "cc"
700 #define ARM_ASM_IF_T12(x,y) x
704 #if defined(HAVE_GCC_ASSEMBLER) && defined(ARCH_ARM64)
705 #define INLINE_ASM_GCC_ARM64
706 #define ARM_ASM_PREFIX
707 #define ARM_ASM_APSR "nzcv"
708 #define ARM_ASM_LO "x"
709 #define ARM_ASM_HI "H"
710 #define ARM_ASM_STRD "stp"
712 #define ARM_ASM_S_CLOB
713 #define ARM_ASM_IF_T12(x,y) y
716 #if defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_8A__) || defined(__ARM_ARCH_8A) || (defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'A')
717 #define ARM_ASM_DIV_NO_TRAP 1
719 #define ARM_ASM_DIV_NO_TRAP 0
722 #elif defined(__ia64) && defined(__linux__)
725 #define ARCH_NAME "ia64"
727 #elif defined(__loongarch64)
729 #define ARCH_LOONGARCH64
730 #define ARCH_NAME "loongarch64"
732 #elif defined(__mips) && defined(_MIPS_SIM) && (_MIPS_SIM == 1 || _MIPS_SIM == 2 || _MIPS_SIM == 3)
735 #if defined(__LP64__)
737 #define ARCH_NAME "mips64"
740 #define ARCH_NAME "mips"
742 #define ARCH_MIPS_O32
744 #define ARCH_MIPS_N32
748 #elif defined(__hppa)
751 #if defined(__LP64__)
752 #define ARCH_PARISC64
753 #define ARCH_NAME "parisc64"
756 #define ARCH_PARISC32
757 #define ARCH_NAME "parisc"
765 #elif defined(__PPC__)
768 #if defined(__LP64__)
770 #define ARCH_NAME "power64"
773 #define ARCH_NAME "power"
776 #elif defined(__s390__)
779 #if defined(__LP64__)
781 #define ARCH_NAME "s390x"
784 #define ARCH_NAME "s390"
787 #elif defined(__sparc__)
790 #if defined(__LP64__)
792 #define ARCH_NAME "sparc64"
795 #define ARCH_NAME "sparc"
798 #elif defined(__riscv) && defined(_LP64)
801 #define ARCH_NAME "riscv64"
807 #if defined(OS_CYGWIN) || defined(OS_WIN32)
808 #define ARCH_X86_WIN_ABI
813 #if defined(HAVE_ASM_GOTO) && !defined(UNUSUAL_NO_ASSEMBLER_GOTO)
814 #define INLINE_ASM_GCC_LABELS
820 #if !defined(UNUSUAL_NO_TAGGED_POINTERS)
821 #if defined(HAVE_MMAP) || defined(OS_DOS) || defined(OS_OS2) || defined(OS_WIN32)
822 #if defined(ARCH_ALPHA)
824 #define HAVE_CODEGEN_TRAPS
826 #if defined(ARCH_ARM32) && defined(__ARMEL__)
829 #if defined(ARCH_ARM64) && !defined(__ILP32__) && defined(HAVE___BUILTIN___CLEAR_CACHE)
832 #if defined(ARCH_IA64)
835 #if defined(ARCH_LOONGARCH64)
838 #if defined(ARCH_MIPS)
840 #define HAVE_CODEGEN_TRAPS
842 #if defined(ARCH_PARISC)
845 #if defined(ARCH_POWER)
848 #if defined(ARCH_S390)
851 #if defined(ARCH_SPARC)
854 #if defined(ARCH_RISCV64)
857 #if defined(ARCH_X86)
863 #if defined(HAVE_CODEGEN) && (defined(HAVE_MPROTECT) || defined(OS_DOS) || defined(OS_OS2) || defined(OS_WIN32))
864 #if defined(ARCH_ARM) && defined(HAVE___BUILTIN___CLEAR_CACHE)
865 #define CODEGEN_USE_HEAP
867 #if defined(ARCH_PARISC) && defined(HAVE_GCC_ASSEMBLER)
868 #define CODEGEN_USE_HEAP
870 #if defined(ARCH_RISCV64) && defined(HAVE___BUILTIN___CLEAR_CACHE)
871 #define CODEGEN_USE_HEAP
873 #if defined(ARCH_S390)
874 #define CODEGEN_USE_HEAP
876 #if defined(ARCH_SPARC64) && defined(HAVE_GCC_ASSEMBLER)
877 #define CODEGEN_USE_HEAP
879 #if defined(ARCH_X86)
880 #define CODEGEN_USE_HEAP
884 #if defined(CODEGEN_USE_HEAP) && defined(DISABLE_RWX_MAPPINGS)
885 #undef CODEGEN_USE_HEAP
889 #ifdef attr_unaligned
890 #if defined(__i386__) || defined(__x86_64__) || defined(__ARM_FEATURE_UNALIGNED) || defined(__alpha__) || defined(__m68k__) || defined(__mips) || defined(__powerpc__) || defined(__s390__)
891 /* define if unaligned access to code array is faster then assembling the value from 16-bit code_t entries */
892 #define UNALIGNED_ACCESS
895 #if defined(__i386__) || defined(__x86_64__) || defined(__ARM_FEATURE_UNALIGNED) || defined(__m68k__) || defined(__powerpc__) || defined(__s390__)
896 /* define if unaligned access results in the same instructions as aligned access */
897 #define UNALIGNED_ACCESS_EFFICIENT
902 #define SMP_ALIAS_ALIGNMENT 1
904 #define SMP_ALIAS_ALIGNMENT 128
905 #ifdef __SANITIZE_THREAD__
906 #define THREAD_SANITIZER
911 #ifdef UNUSUAL_ARITHMETICS
912 #define DIVIDE_ROUNDS_TO_ZERO 0
913 #define RIGHT_SHIFT_KEEPS_SIGN 0
915 #define DIVIDE_ROUNDS_TO_ZERO ((intmax_t)9 / -4 == -2 && \
916 (intmax_t)-9 / 4 == -2 && \
917 (intmax_t)-9 / -4 == 2 && \
918 (intmax_t)9 % -4 == 1 && \
919 (intmax_t)-9 % 4 == -1 && \
920 (intmax_t)-9 % -4 == -1)
921 #define RIGHT_SHIFT_KEEPS_SIGN ((~(intmax_t)0x1234U >> 1) == ~(intmax_t)0x91aU)
925 /* Define if volatile access to pointer, uintptr_t and uint32_t is atomic */
926 #if (SIZEOF_UNSIGNED >= 4 || defined(THREAD_NONE)) && !defined(THREAD_SANITIZER)
927 #define POINTERS_ARE_ATOMIC
931 #define BAD_POINTER_1 ((void *)(uintptr_t)1)
932 #define BAD_POINTER_2 ((void *)(uintptr_t)2)
933 #define BAD_POINTER_3 ((void *)(uintptr_t)3)
934 #define SPECIAL_POINTER_1 BAD_POINTER_1
935 #define SPECIAL_POINTER_2 BAD_POINTER_2
936 #define SPECIAL_POINTER_3 BAD_POINTER_3
937 #if !defined(UNUSUAL_NO_TAGGED_POINTERS) && !defined(UNUSUAL_NO_ARCH_TAGGED_POINTERS)
938 #if defined(HAVE_POINTER_TAGS) && defined(__aarch64__) && !defined(__ILP32__)
939 #define POINTER_IGNORE_START 56
940 #define POINTER_IGNORE_BITS 8
941 #elif defined(HAVE_POINTER_TAGS) && defined(__s390__) && !defined(__LP64__)
942 #define POINTER_IGNORE_START 31
943 #define POINTER_IGNORE_BITS 1
945 #define POINTER_TAG_BIT 0
946 #define POINTER_TAG ((uintptr_t)1 << POINTER_TAG_BIT)
951 static inline void *POINTER_TAG_ADD(void *ptr
)
953 return (void *)((uintptr_t)ptr
+ POINTER_TAG
);
955 static inline void *POINTER_TAG_CLEAR(void *ptr
)
957 return (void *)((uintptr_t)ptr
& ~(uintptr_t)POINTER_TAG
);
959 static inline void *POINTER_TAG_SUB(void *ptr
)
961 return (void *)((uintptr_t)ptr
- POINTER_TAG
);
963 static inline uintptr_t POINTER_TAG_GET(const void *ptr
)
965 return (uintptr_t)ptr
& POINTER_TAG
;
968 #ifdef POINTER_IGNORE_START
969 #define POINTER_IGNORE_TOP_BIT (POINTER_IGNORE_START + POINTER_IGNORE_BITS - 1)
970 #define POINTER_IGNORE_MASK ((((uintptr_t)1 << POINTER_IGNORE_BITS) - 1) << POINTER_IGNORE_START)
971 #define POINTER_IGNORE_TOP ((uintptr_t)1 << POINTER_IGNORE_TOP_BIT)
981 #if defined(HAVE_REAL_GNUC) && defined(__mips_isa_rev) && __mips_isa_rev >= 6
982 #define broken_128bit_multiply volatile
984 #define broken_128bit_multiply