From dc03f6290f5b9bd3d50c7e12e58dee870889d599 Mon Sep 17 00:00:00 2001 From: Lasse Collin Date: Fri, 7 Jun 2024 15:06:59 +0300 Subject: [PATCH] liblzma: Add ARM64 CRC32 instruction support detection on OpenBSD The C code is from Christian Weisgerber, I merely reordered the OSes. Then I added the build system checks without testing them. Also thanks to Brad Smith who submitted a similar patch on GitHub a few hours after Christian had sent his via email. Co-authored-by: Christian Weisgerber Closes: https://github.com/tukaani-project/xz/pull/125 --- CMakeLists.txt | 6 ++++++ configure.ac | 9 +++++++++ src/liblzma/check/crc32_arm64.h | 15 +++++++++++++++ src/liblzma/check/crc_common.h | 1 + 4 files changed, 31 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ac3e45bf..ab5bba72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1220,6 +1220,12 @@ if(ALLOW_ARM64_CRC32) check_symbol_exists(elf_aux_info sys/auxv.h HAVE_ELF_AUX_INFO) tuklib_add_definition_if(liblzma HAVE_ELF_AUX_INFO) + # OpenBSD has a sysctl() based method. The macro CPU_ID_AA64ISAR0 + # is used to detect when it's available. + check_symbol_exists(CPU_ID_AA64ISAR0 machine/cpu.h + HAVE_CPU_ID_AA64ISAR0) + tuklib_add_definition_if(liblzma HAVE_CPU_ID_AA64ISAR0) + # sysctlbyname("hw.optional.armv8_crc32", ...) is supported on Darwin # (macOS, iOS, etc.). Note that sysctlbyname() is supported on FreeBSD, # NetBSD, and possibly others too but the string is specific to diff --git a/configure.ac b/configure.ac index 57831048..74e7c538 100644 --- a/configure.ac +++ b/configure.ac @@ -1088,14 +1088,23 @@ uint32_t my_crc(uint32_t a, uint64_t b) ]) # Check for ARM64 CRC32 instruction runtime detection. +# # getauxval() is supported on Linux, elf_aux_info() on FreeBSD, and # sysctlbyname("hw.optional.armv8_crc32", ...) is supported on Darwin # (macOS, iOS, etc.). Note that sysctlbyname() is supported on FreeBSD, # NetBSD, and possibly others too but the string is specific to Apple OSes. # The C code is responsible for checking defined(__APPLE__) before using # sysctlbyname("hw.optional.armv8_crc32", ...). +# +# sysctl() with CPU_ID_AA64ISAR0 is used on OpenBSD. AS_IF([test "x$enable_arm64_crc32" = xyes], [ AC_CHECK_FUNCS([getauxval elf_aux_info sysctlbyname], [break]) + AC_CHECK_DECL([CPU_ID_AA64ISAR0], + [AC_DEFINE([HAVE_CPU_ID_AA64ISAR0], [1], + [Define to 1 if CPU_ID_AA64ISAR0 is defined + in .])], + [], + [#include ]) ]) diff --git a/src/liblzma/check/crc32_arm64.h b/src/liblzma/check/crc32_arm64.h index 39c1c63e..5bad0e00 100644 --- a/src/liblzma/check/crc32_arm64.h +++ b/src/liblzma/check/crc32_arm64.h @@ -25,6 +25,11 @@ #if defined(CRC32_GENERIC) && defined(CRC32_ARCH_OPTIMIZED) # if defined(HAVE_GETAUXVAL) || defined(HAVE_ELF_AUX_INFO) # include +# elif defined(HAVE_CPU_ID_AA64ISAR0) +# include +# include +# include +# include # elif defined(_WIN32) # include # elif defined(__APPLE__) && defined(HAVE_SYSCTLBYNAME) @@ -89,6 +94,16 @@ is_arch_extension_supported(void) return (feature_flags & HWCAP_CRC32) != 0; +#elif defined(HAVE_CPU_ID_AA64ISAR0) + const int isar0_mib[] = { CTL_MACHDEP, CPU_ID_AA64ISAR0 }; + uint64_t isar0; + size_t len = sizeof(isar0); + + if (sysctl(isar0_mib, 2, &isar0, &len, NULL, 0) == -1) + return false; + + return ID_AA64ISAR0_CRC32(isar0) >= ID_AA64ISAR0_CRC32_BASE; + #elif defined(_WIN32) return IsProcessorFeaturePresent( PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE); diff --git a/src/liblzma/check/crc_common.h b/src/liblzma/check/crc_common.h index 63a7b5ce..1adf1474 100644 --- a/src/liblzma/check/crc_common.h +++ b/src/liblzma/check/crc_common.h @@ -50,6 +50,7 @@ // Keep this in sync with changes to crc32_arm64.h #if defined(_WIN32) || defined(HAVE_GETAUXVAL) \ || defined(HAVE_ELF_AUX_INFO) \ + || defined(HAVE_CPU_ID_AA64ISAR0) \ || (defined(__APPLE__) && defined(HAVE_SYSCTLBYNAME)) # define ARM64_RUNTIME_DETECTION 1 #endif