/* zarch.h -- Detect compiler architecture and define ARCH_* macros * Copyright (C) 2019 Hans Kristian Rosbach * For conditions of distribution and use, see copyright notice in zlib.h */ #ifndef ZARCH_H #define ZARCH_H #define ZARCH_STRINGIZE(X) ZARCH_DOSTRINGIZE(X) #define ZARCH_DOSTRINGIZE(X) #X /* ARM64EC defines both _M_ARM64EC and _M_AMD64/_M_X64, so check for ARM first. */ /* ARM 64-bit */ #if defined(__aarch64__) || defined(__arm64__) || defined(_M_ARM64) || defined(_M_ARM64EC) # define ARCH_ARM # define ARCH_64BIT # define ARCH_NAME "aarch64" /* ARM 32-bit */ #elif defined(__arm__) || defined(__arm) || defined(_M_ARM) || defined(__TARGET_ARCH_ARM) # define ARCH_ARM # define ARCH_32BIT # if defined(__ARM64_ARCH_8__) || defined(__ARM_ARCH_8A__) || defined(__ARMv8__) || defined(__ARMv8_A__) # define ARCH_NAME "armv8" # elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) # define ARCH_NAME "armv7" # elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6T2__) || \ defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6ZK__) || \ defined(__ARM_ARCH_6M__) # define ARCH_NAME "armv6" # elif defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) || defined(__ARM_ARCH_5TEJ__) # define ARCH_NAME "armv5" # elif defined(__ARM_ARCH_4T__) # define ARCH_NAME "armv4" # elif defined(__ARM_ARCH_3__) # define ARCH_NAME "armv3" # elif defined(__ARM_ARCH_2__) # define ARCH_NAME "armv2" # else # define ARCH_NAME "arm" # endif /* x86_64 */ #elif defined(__x86_64__) || defined(_M_X64) # define ARCH_X86 # define ARCH_64BIT # define ARCH_NAME "x86_64" /* x86 (32-bit) */ #elif defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || \ defined(__i386) || defined(_M_IX86) # define ARCH_X86 # define ARCH_32BIT # define ARCH_NAME "i686" /* PowerPC */ #elif defined(__powerpc__) || defined(__ppc__) || defined(__PPC__) # define ARCH_POWER # if defined(__64BIT__) || defined(__powerpc64__) || defined(__ppc64__) # define ARCH_64BIT # if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ # define ARCH_NAME "powerpc64le" # else # define ARCH_NAME "powerpc64" # endif # else # define ARCH_32BIT # define ARCH_NAME "powerpc" # endif /* --------------- Less common architectures alphabetically below --------------- */ /* ALPHA */ #elif defined(__alpha__) || defined(__alpha) # define ARCH_ALPHA # define ARCH_64BIT # define ARCH_NAME "alpha" /* Blackfin */ #elif defined(__BFIN__) # define ARCH_BLACKFIN # define ARCH_32BIT # define ARCH_NAME "blackfin" /* Itanium */ #elif defined(__ia64) || defined(_M_IA64) # define ARCH_IA64 # define ARCH_64BIT # define ARCH_NAME "ia64" /* MIPS */ #elif defined(__mips__) || defined(__mips) # define ARCH_MIPS # if defined(__mips64) || defined(__mips64__) # define ARCH_64BIT # define ARCH_NAME "mips64" # else # define ARCH_32BIT # define ARCH_NAME "mips" # endif /* Motorola 68000-series */ #elif defined(__m68k__) # define ARCH_M68K # define ARCH_32BIT # define ARCH_NAME "m68k" /* SuperH */ #elif defined(__sh__) # define ARCH_SH # define ARCH_32BIT # define ARCH_NAME "sh" /* SPARC */ #elif defined(__sparc__) || defined(__sparc) # define ARCH_SPARC # if defined(__sparcv9) || defined(__sparc_v9__) || defined(__sparc64__) # define ARCH_64BIT # define ARCH_NAME "sparc9" # elif defined(__sparcv8) || defined(__sparc_v8__) # define ARCH_32BIT # define ARCH_NAME "sparc8" # else # define ARCH_32BIT # define ARCH_NAME "sparc" # endif /* SystemZ / S390 */ #elif defined(__s390x) || defined(__zarch__) # define ARCH_S390 # define ARCH_64BIT # define ARCH_NAME "s390x" #elif defined(__s390__) # define ARCH_S390 # define ARCH_32BIT # define ARCH_NAME "s390" #elif defined(__370__) # define ARCH_S390 # define ARCH_32BIT # define ARCH_NAME "s370" /* PARISC */ #elif defined(__hppa__) # define ARCH_PARISC # if defined(__hppa64__) || defined(__LP64__) # define ARCH_64BIT # define ARCH_NAME "parisc64" # else # define ARCH_32BIT # define ARCH_NAME "parisc" # endif /* RS-6000 */ #elif defined(__THW_RS6000) # define ARCH_RS6000 # define ARCH_32BIT # define ARCH_NAME "rs6000" /* RISC-V */ #elif defined(__riscv) # define ARCH_RISCV # if __riscv_xlen == 64 # define ARCH_64BIT # define ARCH_NAME "riscv64" # elif __riscv_xlen == 32 # define ARCH_32BIT # define ARCH_NAME "riscv32" # else # define ARCH_NAME "riscv" # endif /* LOONGARCH */ #elif defined(__loongarch_lp64) # define ARCH_LOONGARCH # define ARCH_64BIT # define ARCH_NAME "loongarch64" /* Emscripten (WebAssembly) */ #elif defined(__EMSCRIPTEN__) # define ARCH_WASM # if defined(__wasm64__) # define ARCH_64BIT # define ARCH_NAME "wasm64" # else # define ARCH_32BIT # define ARCH_NAME "wasm32" # endif /* Elbrus 2000 (aka e2k) */ #elif defined(__e2k__) # define ARCH_E2K /* e2k reuse x86 optimizations */ # define ARCH_X86 # define ARCH_64BIT # define ARCH_NAME "e2k" # define ARCH_VERSION_STR ZARCH_STRINGIZE(__iset__) /* Unrecognized architecture */ #else # if defined(__LP64__) || defined(_LP64) || defined(_WIN64) # define ARCH_64BIT # else # define ARCH_32BIT # endif # define ARCH_NAME "unrecognized" #endif #endif /* ZARCH_H */