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.
Passes regress, OK for commit?
libatomic:
* config/linux/aarch64/host-config.h (has_lse2): Remove unused arg.
(has_lse128): Change to just use HWCAPs.
(has_rcpc3): Likewise.
---
diff --git a/libatomic/config/linux/aarch64/host-config.h
b/libatomic/config/linux/aarch64/host-config.h
index
d0d44bf18eaa64437f52c2894da6ece9e02618df..6a4f7014323a2ed196cabe408aaa6df0d2521518
100644
--- a/libatomic/config/linux/aarch64/host-config.h
+++ b/libatomic/config/linux/aarch64/host-config.h
@@ -69,7 +69,7 @@ typedef struct __ifunc_arg_t {
# elif defined (LSE2_LRCPC3_ATOP)
# define IFUNC_NCOND(N) 2
# define IFUNC_COND_1 (has_rcpc3 (hwcap, features))
-# define IFUNC_COND_2 (has_lse2 (hwcap, features))
+# define IFUNC_COND_2 (has_lse2 (hwcap))
# elif defined (LSE128_ATOP)
# define IFUNC_NCOND(N) 1
# define IFUNC_COND_1 (has_lse128 (hwcap, features))
@@ -86,7 +86,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)
{
/* Check for LSE2. */
if (hwcap & HWCAP_USCAT)
@@ -105,50 +105,20 @@ 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->_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;
+ return (hwcap & HWCAP_USCAT
+ && hwcap & _IFUNC_ARG_HWCAP
+ && features->_hwcap2 & HWCAP2_LRCPC3);
}
#endif /* HAVE_IFUNC */