diff options
author | Mika Lindqvist <postmaster@raasu.org> | 2021-05-09 08:17:03 +0300 |
---|---|---|
committer | Hans Kristian Rosbach <hk-github@circlestorm.org> | 2021-05-09 22:30:40 +0200 |
commit | f2077005e80b08bc03a67f7b1aca9be809e93e95 (patch) | |
tree | 8abe277b43fea620982f7041c048617424867172 | |
parent | 62b269b4a5f4502d6dc03d73bb5b552e80066885 (diff) |
[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
-rw-r--r-- | CMakeLists.txt | 62 | ||||
-rw-r--r-- | arch/arm/armfeature.c | 11 | ||||
-rwxr-xr-x | configure | 33 |
3 files changed, 89 insertions, 17 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index dd174a3..42316c9 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 <sys/auxv.h> - 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 <sys/auxv.h> + 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 <sys/auxv.h> + #include <asm/hwcap.h> + 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 <sys/auxv.h> + 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 <sys/auxv.h> 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 <sys/auxv.h> + 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 e8fcc1e..bef9b29 100644 --- a/arch/arm/armfeature.c +++ b/arch/arm/armfeature.c @@ -2,6 +2,9 @@ #if defined(__linux__) # include <sys/auxv.h> +# ifdef ARM_ASM_HWCAP +# include <asm/hwcap.h> +# endif #elif defined(__FreeBSD__) && defined(__aarch64__) # include <machine/armreg.h> # 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); @@ -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 <<EOF +#include <sys/auxv.h> +#include <asm/hwcap.h> +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 <<EOF #include <sys/auxv.h> 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 <<EOF +#include <sys/auxv.h> +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 <<EOF #include <sys/auxv.h> 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 |