libatomic: Cleanup AArch64 ifunc selection

Message ID PAWPR08MB8982862648E18777F9428A1383282@PAWPR08MB8982.eurprd08.prod.outlook.com
State New
Headers
Series libatomic: Cleanup AArch64 ifunc selection |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_gcc_check--master-arm success Test passed
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 success Test passed

Commit Message

Wilco Dijkstra Nov. 27, 2024, 11:43 a.m. UTC
  Simplify and cleanup ifunc selection logic.  Since LRCPC3 does
not imply LSE2, has_rcpc3() should also check LSE2 is enabled.

Passes regress and bootstrap, OK for commit?

libatomic:
        * config/linux/aarch64/host-config.h (has_lse2): Cleanup.
        (has_lse128): Likewise.
        (has_rcpc3): Add early check for LSE2.

---
  

Patch

diff --git a/libatomic/config/linux/aarch64/host-config.h b/libatomic/config/linux/aarch64/host-config.h
index 93f367d587803ce26b3c9a45881ac2d9b2e37168..d9d9239897c82d2eebff2bf38f6bac3a7c7b23ea 100644
--- a/libatomic/config/linux/aarch64/host-config.h
+++ b/libatomic/config/linux/aarch64/host-config.h
@@ -91,69 +91,62 @@  has_lse2 (unsigned long hwcap, const __ifunc_arg_t *features)
   /* Check for LSE2.  */
   if (hwcap & HWCAP_USCAT)
     return true;
-  /* No point checking further for atomic 128-bit load/store if LSE
-     prerequisite not met.  */
-  if (!(hwcap & HWCAP_ATOMICS))
-    return false;
-  if (!(hwcap & HWCAP_CPUID))
-    return false;
 
-  unsigned long midr;
-  asm volatile ("mrs %0, midr_el1" : "=r" (midr));
+  /* If LSE and CPUID are supported, check MIDR.  */
+  if (hwcap & HWCAP_CPUID && hwcap & HWCAP_ATOMICS)
+    {
+      unsigned long midr;
+      asm volatile ("mrs %0, midr_el1" : "=r" (midr));
 
-  /* Neoverse N1 supports atomic 128-bit load/store.  */
-  if (MIDR_IMPLEMENTOR (midr) == 'A' && MIDR_PARTNUM (midr) == 0xd0c)
-    return true;
+      /* Neoverse N1 supports atomic 128-bit load/store.  */
+      return MIDR_IMPLEMENTOR (midr) == 'A' && MIDR_PARTNUM (midr) == 0xd0c;
+    }
 
   return false;
 }
 
-/* LSE128 atomic support encoded in ID_AA64ISAR0_EL1.Atomic,
-   bits[23:20].  The expected value is 0b0011.  Check that.  */
+/* 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;
-  /* A 0 HWCAP2_LSE128 bit may be just as much a sign of missing HWCAP2 bit
-     support in older kernels as it is of CPU feature absence.  Try fallback
-     method to guarantee LSE128 is not implemented.
-
-     In the absence of HWCAP_CPUID, we are unable to check for LSE128.
-     If feature check available, check LSE2 prerequisite before proceeding.  */
-  if (!(hwcap & HWCAP_CPUID) || !(hwcap & HWCAP_USCAT))
-     return false;
-
-  unsigned long isar0;
-  asm volatile ("mrs %0, ID_AA64ISAR0_EL1" : "=r" (isar0));
-  if (AT_FEAT_FIELD (isar0) >= 3)
+  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;
 }
 
-/* LRCPC atomic support encoded in ID_AA64ISAR1_EL1.Atomic, bits[23:20].  The
-   expected value is 0b0011.  Check that.  */
+/* 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)
 {
-  if (hwcap & _IFUNC_ARG_HWCAP
-      && features->_hwcap2 & HWCAP2_LRCPC3)
-    return true;
-  /* Try fallback feature check method to guarantee LRCPC3 is not implemented.
-
-     In the absence of HWCAP_CPUID, we are unable to check for RCPC3, return.
-     If feature check available, check LSE2 prerequisite before proceeding.  */
-  if (!(hwcap & HWCAP_CPUID) || !(hwcap & HWCAP_USCAT))
+  /* LSE2 is a prerequisite for atomic LDIAPP/STILP.  */
+  if (!(hwcap & HWCAP_USCAT))
     return false;
-  unsigned long isar1;
-  asm volatile ("mrs %0, ID_AA64ISAR1_EL1" : "=r" (isar1));
-  if (AT_FEAT_FIELD (isar1) >= 3)
+
+  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;
 }