From f2077005e80b08bc03a67f7b1aca9be809e93e95 Mon Sep 17 00:00:00 2001 From: Mika Lindqvist Date: Sun, 9 May 2021 08:17:03 +0300 Subject: [PATCH] [ARM/AArch64] More thorough testing of getauxval() macros and includes * 32-bit ARM and AArch64 use slightly different macros for CRC32 and NEON feature bits * 32-bit ARM sometimes requires asm/hwcap.h for AT_HWCAP2 --- CMakeLists.txt | 62 ++++++++++++++++++++++++++++++++++--------- arch/arm/armfeature.c | 11 ++++++++ configure | 33 +++++++++++++++++++---- 3 files changed, 89 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index dd174a3d..42316c9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -650,30 +650,68 @@ if(WITH_OPTIM) if(BASEARCH_ARM_FOUND) add_definitions(-DARM_FEATURES) if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - check_c_source_compiles( - "#include - int main() { - return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); - }" - ARM_AUXV_HAS_CRC32 - ) - if(ARM_AUXV_HAS_CRC32) - add_definitions(-DARM_AUXV_HAS_CRC32) + if(NOT "${ARCH}" MATCHES "aarch64") + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); + }" + ARM_AUXV_HAS_CRC32 + ) + if(ARM_AUXV_HAS_CRC32) + add_definitions(-DARM_AUXV_HAS_CRC32) + else() + check_c_source_compiles( + "#include + #include + int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); + }" + ARM_HWCAP_HAS_CRC32 + ) + if (ARM_HWCAP_HAS_CRC32) + add_definitions(-DARM_AUXV_HAS_CRC32 -DARM_ASM_HWCAP) + else() + message(STATUS "HWCAP2_CRC32 not present in sys/auxv.h; cannot detect support at runtime.") + endif() + endif() else() - message(STATUS "HWCAP2_CRC32 not present in sys/auxv.h; cannot detect support at runtime.") + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP) & HWCAP_CRC32); + }" + ARM_AUXV_HAS_CRC32 + ) + if(ARM_AUXV_HAS_CRC32) + add_definitions(-DARM_AUXV_HAS_CRC32) + else() + message(STATUS "HWCAP_CRC32 not present in sys/auxv.h; cannot detect support at runtime.") + endif() endif() if(NOT "${ARCH}" MATCHES "aarch64") check_c_source_compiles( "#include int main() { - return (getauxval(AT_HWCAP) & HWCAP_NEON); + return (getauxval(AT_HWCAP) & HWCAP_ARM_NEON); }" ARM_AUXV_HAS_NEON ) if(ARM_AUXV_HAS_NEON) add_definitions(-DARM_AUXV_HAS_NEON) else() - message(STATUS "HWCAP_NEON not present in sys/auxv.h; cannot detect support at runtime.") + check_c_source_compiles( + "#include + int main() { + return (getauxval(AT_HWCAP) & HWCAP_NEON); + }" + ARM_AUXV_HAS_NEON + ) + if (ARM_AUXV_HAS_NEON) + add_definitions(-DARM_AUXV_HAS_NEON) + else() + message(STATUS "Neither HWCAP_ARM_NEON or HWCAP_NEON present in sys/auxv.h; cannot detect support at runtime.") + endif() endif() endif() endif() diff --git a/arch/arm/armfeature.c b/arch/arm/armfeature.c index e8fcc1e5..bef9b290 100644 --- a/arch/arm/armfeature.c +++ b/arch/arm/armfeature.c @@ -2,6 +2,9 @@ #if defined(__linux__) # include +# ifdef ARM_ASM_HWCAP +# include +# endif #elif defined(__FreeBSD__) && defined(__aarch64__) # include # ifndef ID_AA64ISAR0_CRC32_VAL @@ -15,7 +18,11 @@ static int arm_has_crc32() { #if defined(__linux__) && defined(ARM_AUXV_HAS_CRC32) +# ifdef HWCAP_CRC32 + return (getauxval(AT_HWCAP) & HWCAP_CRC32) != 0 ? 1 : 0; +# else return (getauxval(AT_HWCAP2) & HWCAP2_CRC32) != 0 ? 1 : 0; +# endif #elif defined(__FreeBSD__) && defined(__aarch64__) return getenv("QEMU_EMULATING") == NULL && ID_AA64ISAR0_CRC32_VAL(READ_SPECIALREG(id_aa64isar0_el1)) >= ID_AA64ISAR0_CRC32_BASE; @@ -35,7 +42,11 @@ static int arm_has_crc32() { #if !defined(__aarch64__) && !defined(_M_ARM64) static inline int arm_has_neon() { #if defined(__linux__) && defined(ARM_AUXV_HAS_NEON) +# ifdef HWCAP_ARM_NEON + return (getauxval(AT_HWCAP) & HWCAP_ARM_NEON) != 0 ? 1 : 0; +# else return (getauxval(AT_HWCAP) & HWCAP_NEON) != 0 ? 1 : 0; +# endif #elif defined(__APPLE__) int hasneon; size_t size = sizeof(hasneon); diff --git a/configure b/configure index 9812d057..fd02a6fe 100755 --- a/configure +++ b/configure @@ -1288,20 +1288,43 @@ EOF CFLAGS="${CFLAGS} -DARM_AUXV_HAS_CRC32" SFLAGS="${SFLAGS} -DARM_AUXV_HAS_CRC32" else - echo "HWCAP2_CRC32 not present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + cat > $test.c < +#include +int main() { + return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_CRC32 -DARM_ASM_HWCAP" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_CRC32 -DARM_ASM_HWCAP" + else + echo "HWCAP2_CRC32 not present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + fi fi cat > $test.c < int main() { - return (getauxval(AT_HWCAP) & HWCAP_NEON); + return (getauxval(AT_HWCAP) & HWCAP_ARM_NEON); } EOF if try $CC -c $CFLAGS $test.c; then CFLAGS="${CFLAGS} -DARM_AUXV_HAS_NEON" SFLAGS="${SFLAGS} -DARM_AUXV_HAS_NEON" else - echo "HWCAP_NEON not present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + cat > $test.c < +int main() { + return (getauxval(AT_HWCAP) & HWCAP_NEON); +} +EOF + if try $CC -c $CFLAGS $test.c; then + CFLAGS="${CFLAGS} -DARM_AUXV_HAS_NEON" + SFLAGS="${SFLAGS} -DARM_AUXV_HAS_NEON" + else + echo "Neither HWCAP_ARM_NEON or HWCAP_NEON present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + fi fi fi fi @@ -1448,14 +1471,14 @@ EOF cat > $test.c < int main() { - return (getauxval(AT_HWCAP2) & HWCAP2_CRC32); + return (getauxval(AT_HWCAP) & HWCAP_CRC32); } EOF if try $CC -c $CFLAGS $test.c; then CFLAGS="${CFLAGS} -DARM_AUXV_HAS_CRC32" SFLAGS="${SFLAGS} -DARM_AUXV_HAS_CRC32" else - echo "HWCAP2_CRC32 not present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log + echo "HWCAP_CRC32 not present in sys/auxv.h; cannot detect support at runtime." | tee -a configure.log fi fi -- 2.47.3