https://gcc.gnu.org/g:ea72e6be34c41ccf54aab44d17386a4fba74edcd
commit r17-4712-gea72e6be34c41ccf54aab44d17386a4fba74edcd Author: Wilco Dijkstra <[email protected]> Date: Mon Feb 24 16:38:34 2025 +0000 libatomic: Use HWCAPs in AArch64 ifunc tests Feedback from the kernel team suggests that it's best to only use HWCAPs rather than also use low-level checks as done by has_lse128() and has_rcpc3(). So change these to just use HWCAPs which simplifies the code and speeds up ifunc selection by avoiding expensive system register accesses. libatomic: * config/linux/aarch64/host-config.h (has_lse2): Mark unused arg. (has_lse128): Change to use HWCAPs and check size of struct. (has_rcpc3): Likewise. Diff: --- libatomic/config/linux/aarch64/host-config.h | 45 ++++++---------------------- 1 file changed, 9 insertions(+), 36 deletions(-) diff --git a/libatomic/config/linux/aarch64/host-config.h b/libatomic/config/linux/aarch64/host-config.h index 7f91528de5b2..78f56bad5aee 100644 --- a/libatomic/config/linux/aarch64/host-config.h +++ b/libatomic/config/linux/aarch64/host-config.h @@ -90,7 +90,7 @@ typedef struct __ifunc_arg_t { #define MIDR_PARTNUM(midr) (((midr) >> 4) & 0xfff) static inline bool -has_lse2 (unsigned long hwcap, const __ifunc_arg_t *features) +has_lse2 (unsigned long hwcap, const __ifunc_arg_t *features UNUSED) { /* Check for LSE2. */ if (hwcap & HWCAP_USCAT) @@ -109,50 +109,23 @@ has_lse2 (unsigned long hwcap, const __ifunc_arg_t *features) return false; } -/* LSE128 atomic support encoded in ID_AA64ISAR0_EL1.Atomic, bits[23:20]. - The minimum value for LSE128 is 0b0011. */ - -#define AT_FEAT_FIELD(isar0) (((isar0) >> 20) & 15) - static inline bool has_lse128 (unsigned long hwcap, const __ifunc_arg_t *features) { - if (hwcap & _IFUNC_ARG_HWCAP && features->_hwcap2 & HWCAP2_LSE128) - return true; - - /* If LSE2 and CPUID are supported, check for LSE128. */ - if (hwcap & HWCAP_CPUID && hwcap & HWCAP_USCAT) - { - unsigned long isar0; - asm volatile ("mrs %0, ID_AA64ISAR0_EL1" : "=r" (isar0)); - return AT_FEAT_FIELD (isar0) >= 3; - } - - return false; + return (hwcap & _IFUNC_ARG_HWCAP + && features->_size > offsetof (__ifunc_arg_t, _hwcap2) + && features->_hwcap2 & HWCAP2_LSE128); } -/* LRCPC atomic support encoded in ID_AA64ISAR1_EL1.Atomic, bits[23:20]. - The minimum value for LRCPC3 is 0b0011. */ - static inline bool has_rcpc3 (unsigned long hwcap, const __ifunc_arg_t *features) { /* LSE2 is a prerequisite for atomic LDIAPP/STILP - check HWCAP_USCAT since - has_lse2 is more expensive and Neoverse N1 does not have LRCPC3. */ - if (!(hwcap & HWCAP_USCAT)) - return false; - - if (hwcap & _IFUNC_ARG_HWCAP && features->_hwcap2 & HWCAP2_LRCPC3) - return true; - - if (hwcap & HWCAP_CPUID) - { - unsigned long isar1; - asm volatile ("mrs %0, ID_AA64ISAR1_EL1" : "=r" (isar1)); - return AT_FEAT_FIELD (isar1) >= 3; - } - - return false; + has_lse2 is more expensive and Neoverse N1 does not have LRCPC3. */ + return (hwcap & _IFUNC_ARG_HWCAP + && features->_size > offsetof (__ifunc_arg_t, _hwcap2) + && features->_hwcap & HWCAP_USCAT + && features->_hwcap2 & HWCAP2_LRCPC3); } #endif /* HAVE_IFUNC */
