From 7be4c57f00d004d7fc3721138eb4e2619dd0a66e Mon Sep 17 00:00:00 2001 From: Hans Kristian Rosbach Date: Fri, 5 Dec 2025 20:04:14 +0100 Subject: [PATCH] Improve cmake/detect-arch.cmake to also provide bitness. Rewrite checks in CMakelists.txt and cmake/detect-intrinsics.cmake to utilize the new variables. --- CMakeLists.txt | 18 +++---- cmake/detect-arch.cmake | 95 +++++++++++++++++++++++++++-------- cmake/detect-intrinsics.cmake | 12 ++--- 3 files changed, 90 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 39b0efe75..0476b9af4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,7 +118,7 @@ set(WITH_SANITIZER AUTO CACHE STRING "Enable sanitizer support") set_property(CACHE WITH_SANITIZER PROPERTY STRINGS "Memory" "Address" "Undefined" "Thread") if(BASEARCH_ARM_FOUND) - cmake_dependent_option(WITH_ARMV6 "Build with ARMv6 SIMD" ON "NOT ARCH MATCHES \"aarch64\"" OFF) + cmake_dependent_option(WITH_ARMV6 "Build with ARMv6 SIMD" ON ARCH_32BIT OFF) option(WITH_ARMV8 "Build with ARMv8 CRC32 intrinsics" ON) option(WITH_NEON "Build with NEON intrinsics" ON) @@ -236,7 +236,7 @@ elseif(MSVC) set(WARNFLAGS_DISABLE /wd4206 /wd4054 /wd4324) if(BASEARCH_ARM_FOUND) add_definitions(-D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE) - if(NOT "${ARCH}" MATCHES "aarch64") + if(ARCH_32BIT) set(NEONFLAG "/arch:VFPv4") endif() endif() @@ -256,7 +256,7 @@ elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang" endif() if(NOT WITH_NATIVE_INSTRUCTIONS) if(BASEARCH_ARM_FOUND) - if("${ARCH}" MATCHES "arm" AND NOT CMAKE_C_FLAGS MATCHES "-mfloat-abi") + if(ARCH_32BIT AND NOT CMAKE_C_FLAGS MATCHES "-mfloat-abi") # Auto-detect support for ARM floating point ABI check_include_file(features.h HAVE_FEATURES_H) if(HAVE_FEATURES_H) @@ -744,7 +744,7 @@ elseif(BASEARCH_LOONGARCH_FOUND) set(ARCHDIR "arch/loongarch") elseif(BASEARCH_X86_FOUND) set(ARCHDIR "arch/x86") - if(NOT ${ARCH} MATCHES "x86_64") + if(ARCH_32BIT) add_feature_info(SSE2 1 "Support the SSE2 instruction set, using \"${SSE2FLAG}\"") endif() else() @@ -757,7 +757,7 @@ if(WITH_OPTIM) if(BASEARCH_ARM_FOUND) add_definitions(-DARM_FEATURES) if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - if("${ARCH}" MATCHES "aarch64") + if(ARCH_64BIT) check_c_source_compiles( "#include int main() { @@ -822,7 +822,7 @@ if(WITH_OPTIM) endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD" OR ${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD") - if("${ARCH}" MATCHES "aarch64") + if(ARCH_64BIT) check_c_source_compiles( "#include int main() { @@ -973,7 +973,7 @@ if(WITH_OPTIM) if(HAVE_POWER8_INTRIN) add_definitions(-DPOWER8_VSX) set(POWER8_SRCS ${ARCHDIR}/adler32_power8.c ${ARCHDIR}/chunkset_power8.c ${ARCHDIR}/slide_hash_power8.c) - if("${ARCH}" MATCHES "powerpc64(le)?") + if(ARCH_64BIT) add_definitions(-DPOWER8_VSX_CRC32) list(APPEND POWER8_SRCS ${ARCHDIR}/crc32_power8.c) endif() @@ -1135,7 +1135,7 @@ if(WITH_OPTIM) add_definitions(-DX86_SSE2) set(SSE2_SRCS ${ARCHDIR}/chunkset_sse2.c ${ARCHDIR}/chorba_sse2.c ${ARCHDIR}/compare256_sse2.c ${ARCHDIR}/slide_hash_sse2.c) list(APPEND ZLIB_ARCH_SRCS ${SSE2_SRCS}) - if(NOT ${ARCH} MATCHES "x86_64") + if(ARCH_32BIT) set_property(SOURCE ${SSE2_SRCS} PROPERTY COMPILE_FLAGS "${SSE2FLAG} ${NOLTOFLAG}") endif() else() @@ -1394,7 +1394,7 @@ set(ZLIB_ALL_FALLBACK_SRCS if(WITH_ALL_FALLBACKS) list(APPEND ZLIB_GENERIC_SRCS ${ZLIB_ALL_FALLBACK_SRCS}) add_definitions(-DWITH_ALL_FALLBACKS) -elseif(${ARCH} STREQUAL "x86_64" AND WITH_SSE2) +elseif(BASEARCH_X86_FOUND AND ARCH_64BIT AND WITH_SSE2) # x86_64 always has SSE2, so let the SSE2 functions act as fallbacks. list(APPEND ZLIB_GENERIC_SRCS arch/generic/adler32_c.c diff --git a/cmake/detect-arch.cmake b/cmake/detect-arch.cmake index f80ee4a05..a8b70a63c 100644 --- a/cmake/detect-arch.cmake +++ b/cmake/detect-arch.cmake @@ -1,21 +1,11 @@ # detect-arch.cmake -- Detect compiler architecture and set ARCH and BASEARCH # Copyright (C) 2019 Hans Kristian Rosbach # Licensed under the Zlib license, see LICENSE.md for details -set(ARCHDETECT_FOUND TRUE) - if(CMAKE_OSX_ARCHITECTURES) # If multiple architectures are requested (universal build), pick only the first list(GET CMAKE_OSX_ARCHITECTURES 0 ARCH) elseif(MSVC) - if("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "X86") - set(ARCH "i686") - elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "x64") - set(ARCH "x86_64") - elseif("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM" OR "${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARMV7") - set(ARCH "arm") - elseif ("${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM64" OR "${MSVC_C_ARCHITECTURE_ID}" STREQUAL "ARM64EC") - set(ARCH "aarch64") - endif() + set(ARCH ${MSVC_C_ARCHITECTURE_ID}) elseif(EMSCRIPTEN) set(ARCH "wasm32") elseif(CMAKE_CROSSCOMPILING) @@ -46,58 +36,123 @@ else() message(STATUS "Arch detected: '${ARCH}'") endif() +# Convert ARCH to lowercase +string(TOLOWER "${ARCH}" ARCH) + # Base arch detection -if("${ARCH}" MATCHES "(x86_64|AMD64|i[3-6]86)") +if("${ARCH}" MATCHES "(x86(_32|_64)?|amd64|x64|i[3-6]86)") set(BASEARCH "x86") set(BASEARCH_X86_FOUND TRUE) -elseif("${ARCH}" MATCHES "(arm(v[0-9])?|aarch64|cortex)") + if("${ARCH}" MATCHES "(x86_64|amd64|x64)") + set(ARCH_BITS 64) + else() + set(ARCH_BITS 32) + endif() +elseif("${ARCH}" MATCHES "(aarch64|arm64(ec)?|aarch32|arm(v[0-9])?|cortex)") set(BASEARCH "arm") set(BASEARCH_ARM_FOUND TRUE) -elseif("${ARCH}" MATCHES "ppc(64(le)?)?|powerpc(64(le)?)?") + if("${ARCH}" MATCHES "(aarch64|arm64(ec)?)") + set(ARCH_BITS 64) + else() + set(ARCH_BITS 32) + endif() +elseif("${ARCH}" MATCHES "(ppc|powerpc)(64)?(le)?") set(BASEARCH "ppc") set(BASEARCH_PPC_FOUND TRUE) + if("${ARCH}" MATCHES "(ppc|powerpc)64(le)?") + set(ARCH_BITS 64) + else() + set(ARCH_BITS 32) + endif() elseif("${ARCH}" MATCHES "alpha") set(BASEARCH "alpha") set(BASEARCH_ALPHA_FOUND TRUE) + set(ARCH_BITS 64) elseif("${ARCH}" MATCHES "blackfin") set(BASEARCH "blackfin") set(BASEARCH_BLACKFIN_FOUND TRUE) + set(ARCH_BITS 32) elseif("${ARCH}" MATCHES "ia64") set(BASEARCH "ia64") set(BASEARCH_IA64_FOUND TRUE) -elseif("${ARCH}" MATCHES "mips") + set(ARCH_BITS 64) +elseif("${ARCH}" MATCHES "mips(isa)?(64)?") set(BASEARCH "mips") set(BASEARCH_MIPS_FOUND TRUE) + if("${ARCH}" MATCHES "mips(isa)?64") + set(ARCH_BITS 64) + else() + set(ARCH_BITS 32) + endif() elseif("${ARCH}" MATCHES "m68k") set(BASEARCH "m68k") set(BASEARCH_M68K_FOUND TRUE) + set(ARCH_BITS 32) elseif("${ARCH}" MATCHES "sh") set(BASEARCH "sh") set(BASEARCH_SH_FOUND TRUE) -elseif("${ARCH}" MATCHES "sparc[89]?") + set(ARCH_BITS 32) +elseif("${ARCH}" MATCHES "sparc(v)?[89]?(64)?") set(BASEARCH "sparc") set(BASEARCH_SPARC_FOUND TRUE) + if("${ARCH}" MATCHES "(sparc64|sparc(v)?9)") + set(ARCH_BITS 64) + else() + set(ARCH_BITS 32) + endif() elseif("${ARCH}" MATCHES "s3[679]0x?") set(BASEARCH "s360") set(BASEARCH_S360_FOUND TRUE) -elseif("${ARCH}" MATCHES "parisc") + if("${ARCH}" MATCHES "s3[679]0x") + set(ARCH_BITS 64) + else() + set(ARCH_BITS 32) + endif() +elseif("${ARCH}" MATCHES "(parisc|hppa)(64)?") set(BASEARCH "parisc") set(BASEARCH_PARISC_FOUND TRUE) + if("${ARCH}" MATCHES "(parisc|hppa)64") + set(ARCH_BITS 64) + else() + set(ARCH_BITS 32) + endif() elseif("${ARCH}" MATCHES "rs6000") set(BASEARCH "rs6000") set(BASEARCH_RS6000_FOUND TRUE) + set(ARCH_BITS 32) elseif("${ARCH}" MATCHES "riscv(32|64)") set(BASEARCH "riscv") set(BASEARCH_RISCV_FOUND TRUE) -elseif("${ARCH}" MATCHES "loongarch64") + if("${ARCH}" MATCHES "riscv64") + set(ARCH_BITS 64) + else() + set(ARCH_BITS 32) + endif() +elseif("${ARCH}" MATCHES "(loong64|loongarch64)") set(BASEARCH "loongarch") set(BASEARCH_LOONGARCH_FOUND TRUE) -elseif("${ARCH}" MATCHES "wasm32") + set(ARCH_BITS 64) +elseif("${ARCH}" MATCHES "wasm(32|64)") set(BASEARCH "wasm32") set(BASEARCH_WASM32_FOUND TRUE) + if("${ARCH}" MATCHES "wasm64") + set(ARCH_BITS 64) + else() + set(ARCH_BITS 32) + endif() else() set(BASEARCH "x86") set(BASEARCH_X86_FOUND TRUE) + set(ARCH_BITS 32) message(STATUS "Basearch '${ARCH}' not recognized, defaulting to 'x86'.") endif() -message(STATUS "Basearch of '${ARCH}' has been detected as: '${BASEARCH}'") + +if (ARCH_BITS EQUAL 64) + set(ARCH_64BIT TRUE) + set(ARCH_32BIT FALSE) +else() + set(ARCH_64BIT FALSE) + set(ARCH_32BIT TRUE) +endif() + +message(STATUS "Basearch of '${ARCH}' (${ARCH_BITS}bit) has been detected as: '${BASEARCH}'") diff --git a/cmake/detect-intrinsics.cmake b/cmake/detect-intrinsics.cmake index d1c814ffa..0fd83d0bc 100644 --- a/cmake/detect-intrinsics.cmake +++ b/cmake/detect-intrinsics.cmake @@ -211,7 +211,7 @@ endmacro() macro(check_neon_compiler_flag) if(NOT NATIVEFLAG) if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") - if("${ARCH}" MATCHES "aarch64") + if(ARCH_64BIT) set(NEONFLAG "-march=armv8-a+simd") else() set(NEONFLAG "-mfpu=neon") @@ -230,7 +230,7 @@ macro(check_neon_compiler_flag) NEON_AVAILABLE FAIL_REGEX "not supported") # Check whether compiler native flag is enough for NEON support # Some GCC versions don't enable FPU (vector unit) when using -march=native - if(NEON_AVAILABLE AND NATIVEFLAG AND (NOT "${ARCH}" MATCHES "aarch64")) + if(NEON_AVAILABLE AND NATIVEFLAG AND ARCH_32BIT) check_c_source_compiles( "#include uint8x16_t f(uint8x16_t x, uint8x16_t y) { @@ -274,7 +274,7 @@ endmacro() macro(check_neon_ld4_intrinsics) if(NOT NATIVEFLAG) if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") - if("${ARCH}" MATCHES "aarch64") + if(ARCH_64BIT) set(NEONFLAG "-march=armv8-a+simd") else() set(NEONFLAG "-mfpu=neon") @@ -302,7 +302,7 @@ macro(check_pclmulqdq_intrinsics) endif() endif() # Check whether compiler supports PCLMULQDQ intrinsics - if(NOT (APPLE AND "${ARCH}" MATCHES "i386")) + if(NOT (APPLE AND ARCH_32BIT)) # The pclmul code currently crashes on Mac in 32bit mode. Avoid for now. set(CMAKE_REQUIRED_FLAGS "${PCLMULFLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}") check_c_source_compiles( @@ -325,7 +325,7 @@ macro(check_vpclmulqdq_intrinsics) endif() endif() # Check whether compiler supports VPCLMULQDQ intrinsics - if(NOT (APPLE AND "${ARCH}" MATCHES "i386")) + if(NOT (APPLE AND ARCH_32BIT)) set(CMAKE_REQUIRED_FLAGS "${VPCLMULFLAG} ${NATIVEFLAG} ${ZNOLTOFLAG}") check_c_source_compiles( "#include @@ -548,7 +548,7 @@ macro(check_sse2_intrinsics) set(SSE2FLAG "/arch:SSE2") endif() elseif(MSVC) - if(NOT "${ARCH}" MATCHES "x86_64") + if(ARCH_32BIT) set(SSE2FLAG "/arch:SSE2") endif() elseif(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang" OR CMAKE_C_COMPILER_ID MATCHES "NVHPC") -- 2.47.3