]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
x86: Add support to build strcmp/strlen/strchr with explicit ISA level
authorNoah Goldstein <goldstein.w.n@gmail.com>
Wed, 13 Jul 2022 23:32:59 +0000 (16:32 -0700)
committerNoah Goldstein <goldstein.w.n@gmail.com>
Sat, 16 Jul 2022 10:07:59 +0000 (03:07 -0700)
1. Add default ISA level selection in non-multiarch/rtld
   implementations.

2. Add ISA level build guards to different implementations.
    - I.e strcmp-avx2.S which is ISA level 3 will only build if
      compiled ISA level <= 3. Otherwise there is no reason to
      include it as we will always use one of the ISA level 4
      implementations (strcmp-evex.S).

3. Refactor the ifunc selector and ifunc implementation list to use
   the ISA level aware wrapper macros that allow functions below the
   compiled ISA level (with a guranteed replacement) to be skipped.

Tested with and without multiarch on x86_64 for ISA levels:
{generic, x86-64-v2, x86-64-v3, x86-64-v4}

And m32 with and without multiarch.

88 files changed:
sysdeps/x86/isa-level.h
sysdeps/x86_64/Makefile
sysdeps/x86_64/memrchr.S
sysdeps/x86_64/multiarch/Makefile
sysdeps/x86_64/multiarch/ifunc-avx2.h
sysdeps/x86_64/multiarch/ifunc-impl-list.c
sysdeps/x86_64/multiarch/ifunc-strcasecmp.h
sysdeps/x86_64/multiarch/ifunc-wcslen.h
sysdeps/x86_64/multiarch/memrchr-avx2.S
sysdeps/x86_64/multiarch/memrchr-evex.S
sysdeps/x86_64/multiarch/memrchr-sse2.S
sysdeps/x86_64/multiarch/strcasecmp_l-avx2-rtm.S
sysdeps/x86_64/multiarch/strcasecmp_l-avx2.S
sysdeps/x86_64/multiarch/strcasecmp_l-evex.S
sysdeps/x86_64/multiarch/strcasecmp_l-sse2.S
sysdeps/x86_64/multiarch/strchr-avx2.S
sysdeps/x86_64/multiarch/strchr-evex.S
sysdeps/x86_64/multiarch/strchr-sse2-no-bsf.S
sysdeps/x86_64/multiarch/strchr-sse2.S
sysdeps/x86_64/multiarch/strchr.c
sysdeps/x86_64/multiarch/strchrnul-avx2.S
sysdeps/x86_64/multiarch/strchrnul-evex.S
sysdeps/x86_64/multiarch/strchrnul-sse2.S
sysdeps/x86_64/multiarch/strcmp-avx2-rtm.S
sysdeps/x86_64/multiarch/strcmp-avx2.S
sysdeps/x86_64/multiarch/strcmp-evex.S
sysdeps/x86_64/multiarch/strcmp-sse2-unaligned.S
sysdeps/x86_64/multiarch/strcmp-sse2.S
sysdeps/x86_64/multiarch/strcmp-sse4_2.S
sysdeps/x86_64/multiarch/strcmp.c
sysdeps/x86_64/multiarch/strlen-avx2.S
sysdeps/x86_64/multiarch/strlen-evex-base.S
sysdeps/x86_64/multiarch/strlen-evex.S
sysdeps/x86_64/multiarch/strlen-sse2.S
sysdeps/x86_64/multiarch/strncase_l-avx2-rtm.S
sysdeps/x86_64/multiarch/strncase_l-avx2.S
sysdeps/x86_64/multiarch/strncase_l-evex.S
sysdeps/x86_64/multiarch/strncmp-avx2-rtm.S
sysdeps/x86_64/multiarch/strncmp-avx2.S
sysdeps/x86_64/multiarch/strncmp-evex.S
sysdeps/x86_64/multiarch/strncmp.c
sysdeps/x86_64/multiarch/strnlen-avx2.S
sysdeps/x86_64/multiarch/strnlen-evex.S
sysdeps/x86_64/multiarch/strnlen-sse2.S
sysdeps/x86_64/multiarch/strrchr-avx2.S
sysdeps/x86_64/multiarch/strrchr-evex.S
sysdeps/x86_64/multiarch/strrchr-sse2.S
sysdeps/x86_64/multiarch/strstr-sse2-unaligned.S
sysdeps/x86_64/multiarch/wcschr-avx2.S
sysdeps/x86_64/multiarch/wcschr-evex.S
sysdeps/x86_64/multiarch/wcschr-sse2.S
sysdeps/x86_64/multiarch/wcscmp-avx2-rtm.S
sysdeps/x86_64/multiarch/wcscmp-avx2.S
sysdeps/x86_64/multiarch/wcscmp-evex.S
sysdeps/x86_64/multiarch/wcscmp-sse2.S
sysdeps/x86_64/multiarch/wcslen-avx2.S
sysdeps/x86_64/multiarch/wcslen-evex.S
sysdeps/x86_64/multiarch/wcslen-sse2.S
sysdeps/x86_64/multiarch/wcslen-sse4_1.S
sysdeps/x86_64/multiarch/wcsncmp-avx2-rtm.S
sysdeps/x86_64/multiarch/wcsncmp-avx2.S
sysdeps/x86_64/multiarch/wcsncmp-evex.S
sysdeps/x86_64/multiarch/wcsncmp-generic.c
sysdeps/x86_64/multiarch/wcsnlen-avx2.S
sysdeps/x86_64/multiarch/wcsnlen-evex.S
sysdeps/x86_64/multiarch/wcsnlen-generic.c
sysdeps/x86_64/multiarch/wcsnlen-sse4_1.S
sysdeps/x86_64/multiarch/wcsrchr-avx2.S
sysdeps/x86_64/multiarch/wcsrchr-evex.S
sysdeps/x86_64/multiarch/wcsrchr-sse2.S
sysdeps/x86_64/strcasecmp_l.S
sysdeps/x86_64/strchr-isa-default-impl.h [new file with mode: 0644]
sysdeps/x86_64/strchr.S
sysdeps/x86_64/strchrnul.S
sysdeps/x86_64/strcmp.S
sysdeps/x86_64/strlen.S
sysdeps/x86_64/strncase_l.S
sysdeps/x86_64/strncmp.S
sysdeps/x86_64/strnlen.S
sysdeps/x86_64/strrchr.S
sysdeps/x86_64/wcschr.S
sysdeps/x86_64/wcscmp.S
sysdeps/x86_64/wcslen.S
sysdeps/x86_64/wcsncmp-generic.c [new file with mode: 0644]
sysdeps/x86_64/wcsncmp.S [new file with mode: 0644]
sysdeps/x86_64/wcsnlen-generic.c [new file with mode: 0644]
sysdeps/x86_64/wcsnlen.S [new file with mode: 0644]
sysdeps/x86_64/wcsrchr.S

index 77f9e2c0c3ccd41d9068ee6d618d5903885b5660..3c4480aba70193a22cc07703a421a81dde82fd3c 100644 (file)
@@ -84,6 +84,7 @@
 
 /* ISA level >= 2 guaranteed includes.  */
 #define SSE4_2_X86_ISA_LEVEL 2
+#define SSE4_1_X86_ISA_LEVEL 2
 #define SSSE3_X86_ISA_LEVEL 2
 
 
    when ISA level < 3.  */
 #define Prefer_No_VZEROUPPER_X86_ISA_LEVEL 3
 
+/* NB: This feature is disable when ISA level >= 3.  All CPUs with
+   this feature don't run on glibc built with ISA level >= 3.  */
+#define Slow_SSE42_X86_ISA_LEVEL 3
+
 /* Feature(s) enabled when ISA level >= 2.  */
 #define Fast_Unaligned_Load_X86_ISA_LEVEL 2
 
+/* NB: This feature is disable when ISA level >= 2, which was enabled
+   for the early Atom CPUs.  */
+#define Slow_BSF_X86_ISA_LEVEL 2
+
+
 /* Both X86_ISA_CPU_FEATURE_USABLE_P and X86_ISA_CPU_FEATURES_ARCH_P
    macros are wrappers for the respective CPU_FEATURE{S}_{USABLE|ARCH}_P
    runtime checks.  They differ in two ways.
index e597a4855fa9c2252eb3f2cccfcdc2d05a078206..341ee69a3537d0a41c2827b3e5fddb016f8e5aa4 100644 (file)
@@ -197,6 +197,12 @@ gen-as-const-headers += tlsdesc.sym rtld-offsets.sym
 endif
 
 ifeq ($(subdir),wcsmbs)
+
+sysdep_routines += \
+  wcsncmp-generic \
+  wcsnlen-generic \
+# sysdep_routines
+
 tests += \
   tst-rsi-wcslen
 endif
index 385e2c5668e9258b9043ae281011f454cf4ab58b..d39b1aa0e26a75ef971bbe53e87cdecd3528ce63 100644 (file)
@@ -1,4 +1,4 @@
-/* fast SSE2 memrchr with 64 byte loop and pmaxub instruction using
+/* memrchr dispatch for RTLD and non-multiarch build
 
    Copyright (C) 2011-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    <https://www.gnu.org/licenses/>.  */
 
 #define MEMRCHR        __memrchr
-#include "multiarch/memrchr-sse2.S"
+
+#define DEFAULT_IMPL_V1        "multiarch/memrchr-sse2.S"
+#define DEFAULT_IMPL_V3        "multiarch/memrchr-avx2.S"
+#define DEFAULT_IMPL_V4        "multiarch/memrchr-evex.S"
+
+#include "isa-default-impl.h"
+
 weak_alias (__memrchr, memrchr)
index d6b62af850930ee53f2bd1b9827116bb3200b331..ba29a65716fb8ee390b09b5854c217429e0284bc 100644 (file)
@@ -144,11 +144,9 @@ sysdep_routines += \
   wcslen-sse4_1 \
   wcsncmp-avx2 \
   wcsncmp-avx2-rtm \
-  wcsncmp-generic \
   wcsncmp-evex \
   wcsnlen-avx2 \
   wcsnlen-avx2-rtm \
-  wcsnlen-generic \
   wcsnlen-evex \
   wcsnlen-evex512 \
   wcsnlen-sse4_1 \
index 1d9cdfcfec7fcee8dfaa105071d9eec1eee10a94..a57a9952f31ff97cd64464565e11f284dfe9956b 100644 (file)
 # define GENERIC sse2
 #endif
 
-extern __typeof (REDIRECT_NAME) OPTIMIZE (GENERIC) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden;
+
 extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2) attribute_hidden;
 extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_rtm) attribute_hidden;
-extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden;
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (GENERIC) attribute_hidden;
 
 static inline void *
 IFUNC_SELECTOR (void)
 {
-  const struct cpu_featurescpu_features = __get_cpu_features ();
+  const struct cpu_features *cpu_features = __get_cpu_features ();
 
-  if (CPU_FEATURE_USABLE_P (cpu_features, AVX2)
-      && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
-      && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load))
+  if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX2)
+      && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, BMI2)
+      && X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
+                                     AVX_Fast_Unaligned_Load, ))
     {
-      if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
-         && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW))
+      if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
+         && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512BW))
        return OPTIMIZE (evex);
 
       if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
        return OPTIMIZE (avx2_rtm);
 
-      if (!CPU_FEATURES_ARCH_P (cpu_features, Prefer_No_VZEROUPPER))
+      if (X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
+                                      Prefer_No_VZEROUPPER, !))
        return OPTIMIZE (avx2);
     }
 
index 2c96cb62d25cd0f5aaeec02ab208b5f8f69a9723..3b1df9b73cb2a9b73df5f3112bbcf519f11c2d18 100644 (file)
@@ -205,19 +205,22 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   /* Support sysdeps/x86_64/multiarch/memrchr.c.  */
   IFUNC_IMPL (i, name, memrchr,
-             IFUNC_IMPL_ADD (array, i, memrchr,
-                             CPU_FEATURE_USABLE (AVX2),
-                             __memrchr_avx2)
-             IFUNC_IMPL_ADD (array, i, memrchr,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __memrchr_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, memrchr,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)),
-                             __memrchr_evex)
-
-             IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, memrchr,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)),
+                                    __memrchr_evex)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, memrchr,
+                                    CPU_FEATURE_USABLE (AVX2),
+                                    __memrchr_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, memrchr,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __memrchr_avx2_rtm)
+             /* ISA V2 wrapper for SSE2 implementation because the SSE2
+                implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, memrchr,
+                                    1,
+                                    __memrchr_sse2))
 
 #ifdef SHARED
   /* Support sysdeps/x86_64/multiarch/memset_chk.c.  */
@@ -346,49 +349,57 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   /* Support sysdeps/x86_64/multiarch/strlen.c.  */
   IFUNC_IMPL (i, name, strlen,
-             IFUNC_IMPL_ADD (array, i, strlen,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __strlen_avx2)
-             IFUNC_IMPL_ADD (array, i, strlen,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (BMI2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __strlen_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, strlen,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __strlen_evex)
-             IFUNC_IMPL_ADD (array, i, strlen,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __strlen_evex512)
-             IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, strlen,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __strlen_evex)
+             X86_IFUNC_IMPL_ADD_V4 (array, i, strlen,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __strlen_evex512)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strlen,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __strlen_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strlen,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (BMI2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __strlen_avx2_rtm)
+             /* ISA V2 wrapper for SSE2 implementation because the SSE2
+                implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strlen,
+                                    1,
+                                    __strlen_sse2))
 
   /* Support sysdeps/x86_64/multiarch/strnlen.c.  */
   IFUNC_IMPL (i, name, strnlen,
-             IFUNC_IMPL_ADD (array, i, strnlen,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __strnlen_avx2)
-             IFUNC_IMPL_ADD (array, i, strnlen,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (BMI2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __strnlen_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, strnlen,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __strnlen_evex)
-             IFUNC_IMPL_ADD (array, i, strnlen,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __strnlen_evex512)
-             IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, strnlen,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __strnlen_evex)
+             X86_IFUNC_IMPL_ADD_V4 (array, i, strnlen,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __strnlen_evex512)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strnlen,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __strnlen_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strnlen,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (BMI2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __strnlen_avx2_rtm)
+             /* ISA V2 wrapper for SSE2 implementation because the SSE2
+                implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strnlen,
+                                    1,
+                                    __strnlen_sse2))
 
   /* Support sysdeps/x86_64/multiarch/stpncpy.c.  */
   IFUNC_IMPL (i, name, stpncpy,
@@ -422,40 +433,47 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   /* Support sysdeps/x86_64/multiarch/strcasecmp_l.c.  */
   IFUNC_IMPL (i, name, strcasecmp,
-             IFUNC_IMPL_ADD (array, i, strcasecmp,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)),
-                             __strcasecmp_evex)
-             IFUNC_IMPL_ADD (array, i, strcasecmp,
-                             CPU_FEATURE_USABLE (AVX2),
-                             __strcasecmp_avx2)
-             IFUNC_IMPL_ADD (array, i, strcasecmp,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __strcasecmp_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, strcasecmp,
-                             CPU_FEATURE_USABLE (SSE4_2),
-                             __strcasecmp_sse42)
-             IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, strcasecmp,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)),
+                                    __strcasecmp_evex)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strcasecmp,
+                                    CPU_FEATURE_USABLE (AVX2),
+                                    __strcasecmp_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strcasecmp,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __strcasecmp_avx2_rtm)
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strcasecmp,
+                                    CPU_FEATURE_USABLE (SSE4_2),
+                                    __strcasecmp_sse42)
+             /* ISA V2 wrapper for SSE2 implementation because the SSE2
+                implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strcasecmp,
+                                    1,
+                                    __strcasecmp_sse2))
 
   /* Support sysdeps/x86_64/multiarch/strcasecmp_l.c.  */
   IFUNC_IMPL (i, name, strcasecmp_l,
-             IFUNC_IMPL_ADD (array, i, strcasecmp,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)),
-                             __strcasecmp_l_evex)
-             IFUNC_IMPL_ADD (array, i, strcasecmp,
-                             CPU_FEATURE_USABLE (AVX2),
-                             __strcasecmp_l_avx2)
-             IFUNC_IMPL_ADD (array, i, strcasecmp,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __strcasecmp_l_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, strcasecmp_l,
-                             CPU_FEATURE_USABLE (SSE4_2),
-                             __strcasecmp_l_sse42)
-             IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1,
-                             __strcasecmp_l_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, strcasecmp,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)),
+                                    __strcasecmp_l_evex)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strcasecmp,
+                                    CPU_FEATURE_USABLE (AVX2),
+                                    __strcasecmp_l_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strcasecmp,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __strcasecmp_l_avx2_rtm)
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strcasecmp_l,
+                                    CPU_FEATURE_USABLE (SSE4_2),
+                                    __strcasecmp_l_sse42)
+             /* ISA V2 wrapper for SSE2 implementation because the SSE2
+                implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strcasecmp_l,
+                                    1,
+                                    __strcasecmp_l_sse2))
 
   /* Support sysdeps/x86_64/multiarch/strcat.c.  */
   IFUNC_IMPL (i, name, strcat,
@@ -474,74 +492,95 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   /* Support sysdeps/x86_64/multiarch/strchr.c.  */
   IFUNC_IMPL (i, name, strchr,
-             IFUNC_IMPL_ADD (array, i, strchr,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __strchr_avx2)
-             IFUNC_IMPL_ADD (array, i, strchr,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (BMI2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __strchr_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, strchr,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __strchr_evex)
-             IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_sse2_no_bsf)
-             IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, strchr,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __strchr_evex)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strchr,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __strchr_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strchr,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (BMI2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __strchr_avx2_rtm)
+             /* ISA V2 wrapper for SSE2 implementation because the SSE2
+                implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strchr,
+                                    1,
+                                    __strchr_sse2)
+             X86_IFUNC_IMPL_ADD_V1 (array, i, strchr,
+                                    1,
+                                    __strchr_sse2_no_bsf))
 
   /* Support sysdeps/x86_64/multiarch/strchrnul.c.  */
   IFUNC_IMPL (i, name, strchrnul,
-             IFUNC_IMPL_ADD (array, i, strchrnul,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __strchrnul_avx2)
-             IFUNC_IMPL_ADD (array, i, strchrnul,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (BMI2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __strchrnul_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, strchrnul,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __strchrnul_evex)
-             IFUNC_IMPL_ADD (array, i, strchrnul, 1, __strchrnul_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, strchrnul,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __strchrnul_evex)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strchrnul,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __strchrnul_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strchrnul,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (BMI2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __strchrnul_avx2_rtm)
+             /* ISA V2 wrapper for SSE2 implementation because the SSE2
+                implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strchrnul,
+                                    1,
+                                    __strchrnul_sse2))
 
   /* Support sysdeps/x86_64/multiarch/strrchr.c.  */
   IFUNC_IMPL (i, name, strrchr,
-             IFUNC_IMPL_ADD (array, i, strrchr,
-                             CPU_FEATURE_USABLE (AVX2),
-                             __strrchr_avx2)
-             IFUNC_IMPL_ADD (array, i, strrchr,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __strrchr_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, strrchr,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)),
-                             __strrchr_evex)
-             IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, strrchr,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)),
+                                    __strrchr_evex)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strrchr,
+                                    CPU_FEATURE_USABLE (AVX2),
+                                    __strrchr_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strrchr,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __strrchr_avx2_rtm)
+             /* ISA V2 wrapper for SSE2 implementation because the SSE2
+                implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strrchr,
+                                    1,
+                                    __strrchr_sse2))
 
   /* Support sysdeps/x86_64/multiarch/strcmp.c.  */
   IFUNC_IMPL (i, name, strcmp,
-             IFUNC_IMPL_ADD (array, i, strcmp,
-                             CPU_FEATURE_USABLE (AVX2),
-                             __strcmp_avx2)
-             IFUNC_IMPL_ADD (array, i, strcmp,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __strcmp_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, strcmp,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __strcmp_evex)
-             IFUNC_IMPL_ADD (array, i, strcmp, CPU_FEATURE_USABLE (SSE4_2),
-                             __strcmp_sse42)
-             IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_sse2_unaligned)
-             IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, strcmp,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __strcmp_evex)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strcmp,
+                                    CPU_FEATURE_USABLE (AVX2),
+                                    __strcmp_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strcmp,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __strcmp_avx2_rtm)
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strcmp,
+                                 CPU_FEATURE_USABLE (SSE4_2),
+                                 __strcmp_sse42)
+             /* ISA V2 wrapper for SSE2 implementations because the SSE2
+                implementations are also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strcmp,
+                                    1,
+                                    __strcmp_sse2_unaligned)
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strcmp,
+                                    1,
+                                    __strcmp_sse2))
 
   /* Support sysdeps/x86_64/multiarch/strcpy.c.  */
   IFUNC_IMPL (i, name, strcpy,
@@ -568,41 +607,47 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   /* Support sysdeps/x86_64/multiarch/strncase_l.c.  */
   IFUNC_IMPL (i, name, strncasecmp,
-             IFUNC_IMPL_ADD (array, i, strncasecmp,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)),
-                             __strncasecmp_evex)
-             IFUNC_IMPL_ADD (array, i, strncasecmp,
-                             CPU_FEATURE_USABLE (AVX2),
-                             __strncasecmp_avx2)
-             IFUNC_IMPL_ADD (array, i, strncasecmp,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __strncasecmp_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, strncasecmp,
-                             CPU_FEATURE_USABLE (SSE4_2),
-                             __strncasecmp_sse42)
-             IFUNC_IMPL_ADD (array, i, strncasecmp, 1,
-                             __strncasecmp_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, strncasecmp,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)),
+                                    __strncasecmp_evex)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strncasecmp,
+                                    CPU_FEATURE_USABLE (AVX2),
+                                    __strncasecmp_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strncasecmp,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __strncasecmp_avx2_rtm)
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strncasecmp,
+                                    CPU_FEATURE_USABLE (SSE4_2),
+                                    __strncasecmp_sse42)
+             /* ISA V2 wrapper for SSE2 implementation because the SSE2
+                implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strncasecmp,
+                                    1,
+                                    __strncasecmp_sse2))
 
   /* Support sysdeps/x86_64/multiarch/strncase_l.c.  */
   IFUNC_IMPL (i, name, strncasecmp_l,
-             IFUNC_IMPL_ADD (array, i, strncasecmp,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)),
-                             __strncasecmp_l_evex)
-             IFUNC_IMPL_ADD (array, i, strncasecmp,
-                             CPU_FEATURE_USABLE (AVX2),
-                             __strncasecmp_l_avx2)
-             IFUNC_IMPL_ADD (array, i, strncasecmp,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __strncasecmp_l_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, strncasecmp_l,
-                             CPU_FEATURE_USABLE (SSE4_2),
-                             __strncasecmp_l_sse42)
-             IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1,
-                             __strncasecmp_l_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, strncasecmp,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)),
+                                    __strncasecmp_l_evex)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strncasecmp,
+                                    CPU_FEATURE_USABLE (AVX2),
+                                    __strncasecmp_l_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strncasecmp,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __strncasecmp_l_avx2_rtm)
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strncasecmp_l,
+                                    CPU_FEATURE_USABLE (SSE4_2),
+                                    __strncasecmp_l_sse42)
+             /* ISA V2 wrapper for SSE2 implementation because the SSE2
+                implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strncasecmp_l,
+                                    1,
+                                    __strncasecmp_l_sse2))
 
   /* Support sysdeps/x86_64/multiarch/strncat.c.  */
   IFUNC_IMPL (i, name, strncat,
@@ -664,69 +709,85 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   /* Support sysdeps/x86_64/multiarch/wcschr.c.  */
   IFUNC_IMPL (i, name, wcschr,
-             IFUNC_IMPL_ADD (array, i, wcschr,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __wcschr_avx2)
-             IFUNC_IMPL_ADD (array, i, wcschr,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (BMI2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __wcschr_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, wcschr,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __wcschr_evex)
-             IFUNC_IMPL_ADD (array, i, wcschr, 1, __wcschr_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, wcschr,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __wcschr_evex)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, wcschr,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __wcschr_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, wcschr,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (BMI2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __wcschr_avx2_rtm)
+             /* ISA V2 wrapper for SSE2 implementation because the SSE2
+                implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, wcschr,
+                                    1,
+                                    __wcschr_sse2))
 
   /* Support sysdeps/x86_64/multiarch/wcsrchr.c.  */
   IFUNC_IMPL (i, name, wcsrchr,
-             IFUNC_IMPL_ADD (array, i, wcsrchr,
-                             CPU_FEATURE_USABLE (AVX2),
-                             __wcsrchr_avx2)
-             IFUNC_IMPL_ADD (array, i, wcsrchr,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __wcsrchr_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, wcsrchr,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __wcsrchr_evex)
-             IFUNC_IMPL_ADD (array, i, wcsrchr, 1, __wcsrchr_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, wcsrchr,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __wcsrchr_evex)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, wcsrchr,
+                                    CPU_FEATURE_USABLE (AVX2),
+                                    __wcsrchr_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, wcsrchr,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __wcsrchr_avx2_rtm)
+             /* ISA V2 wrapper for SSE2 implementation because the SSE2
+                implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, wcsrchr,
+                                    1,
+                                    __wcsrchr_sse2))
 
   /* Support sysdeps/x86_64/multiarch/wcscmp.c.  */
   IFUNC_IMPL (i, name, wcscmp,
-             IFUNC_IMPL_ADD (array, i, wcscmp,
-                             CPU_FEATURE_USABLE (AVX2),
-                             __wcscmp_avx2)
-             IFUNC_IMPL_ADD (array, i, wcscmp,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __wcscmp_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, wcscmp,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __wcscmp_evex)
-             IFUNC_IMPL_ADD (array, i, wcscmp, 1, __wcscmp_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, wcscmp,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __wcscmp_evex)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, wcscmp,
+                                    CPU_FEATURE_USABLE (AVX2),
+                                    __wcscmp_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, wcscmp,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __wcscmp_avx2_rtm)
+             /* ISA V2 wrapper for SSE2 implementation because the SSE2
+                implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, wcscmp,
+                                    1,
+                                    __wcscmp_sse2))
 
   /* Support sysdeps/x86_64/multiarch/wcsncmp.c.  */
   IFUNC_IMPL (i, name, wcsncmp,
-             IFUNC_IMPL_ADD (array, i, wcsncmp,
-                             CPU_FEATURE_USABLE (AVX2),
-                             __wcsncmp_avx2)
-             IFUNC_IMPL_ADD (array, i, wcsncmp,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __wcsncmp_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, wcsncmp,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __wcsncmp_evex)
-             IFUNC_IMPL_ADD (array, i, wcsncmp, 1, __wcsncmp_generic))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, wcsncmp,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __wcsncmp_evex)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, wcsncmp,
+                                    CPU_FEATURE_USABLE (AVX2),
+                                    __wcsncmp_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, wcsncmp,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __wcsncmp_avx2_rtm)
+             /* ISA V2 wrapper for GENERIC implementation because the
+                GENERIC implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, wcsncmp,
+                                    1,
+                                    __wcsncmp_generic))
 
   /* Support sysdeps/x86_64/multiarch/wcscpy.c.  */
   IFUNC_IMPL (i, name, wcscpy,
@@ -736,55 +797,59 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   /* Support sysdeps/x86_64/multiarch/wcslen.c.  */
   IFUNC_IMPL (i, name, wcslen,
-             IFUNC_IMPL_ADD (array, i, wcslen,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __wcslen_avx2)
-             IFUNC_IMPL_ADD (array, i, wcslen,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (BMI2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __wcslen_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, wcslen,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __wcslen_evex)
-             IFUNC_IMPL_ADD (array, i, wcslen,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __wcslen_evex512)
-             IFUNC_IMPL_ADD (array, i, wcslen,
-                             CPU_FEATURE_USABLE (SSE4_1),
-                             __wcslen_sse4_1)
-             IFUNC_IMPL_ADD (array, i, wcslen, 1, __wcslen_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, wcslen,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __wcslen_evex)
+             X86_IFUNC_IMPL_ADD_V4 (array, i, wcslen,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __wcslen_evex512)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, wcslen,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __wcslen_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, wcslen,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (BMI2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __wcslen_avx2_rtm)
+             X86_IFUNC_IMPL_ADD_V2 (array, i, wcslen,
+                                    CPU_FEATURE_USABLE (SSE4_1),
+                                    __wcslen_sse4_1)
+             X86_IFUNC_IMPL_ADD_V1 (array, i, wcslen,
+                                    1,
+                                    __wcslen_sse2))
 
   /* Support sysdeps/x86_64/multiarch/wcsnlen.c.  */
   IFUNC_IMPL (i, name, wcsnlen,
-             IFUNC_IMPL_ADD (array, i, wcsnlen,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __wcsnlen_avx2)
-             IFUNC_IMPL_ADD (array, i, wcsnlen,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (BMI2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __wcsnlen_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, wcsnlen,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __wcsnlen_evex)
-             IFUNC_IMPL_ADD (array, i, wcsnlen,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)
-                              && CPU_FEATURE_USABLE (BMI2)),
-                             __wcsnlen_evex512)
-             IFUNC_IMPL_ADD (array, i, wcsnlen,
-                             CPU_FEATURE_USABLE (SSE4_1),
-                             __wcsnlen_sse4_1)
-             IFUNC_IMPL_ADD (array, i, wcsnlen, 1, __wcsnlen_generic))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, wcsnlen,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __wcsnlen_evex)
+             X86_IFUNC_IMPL_ADD_V4 (array, i, wcsnlen,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __wcsnlen_evex512)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, wcsnlen,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (BMI2)),
+                                    __wcsnlen_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, wcsnlen,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (BMI2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __wcsnlen_avx2_rtm)
+             X86_IFUNC_IMPL_ADD_V2 (array, i, wcsnlen,
+                                    CPU_FEATURE_USABLE (SSE4_1),
+                                    __wcsnlen_sse4_1)
+             X86_IFUNC_IMPL_ADD_V1 (array, i, wcsnlen,
+                                    1,
+                                    __wcsnlen_generic))
 
   /* Support sysdeps/x86_64/multiarch/wmemchr.c.  */
   IFUNC_IMPL (i, name, wmemchr,
@@ -1050,20 +1115,25 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   /* Support sysdeps/x86_64/multiarch/strncmp.c.  */
   IFUNC_IMPL (i, name, strncmp,
-             IFUNC_IMPL_ADD (array, i, strncmp,
-                             CPU_FEATURE_USABLE (AVX2),
-                             __strncmp_avx2)
-             IFUNC_IMPL_ADD (array, i, strncmp,
-                             (CPU_FEATURE_USABLE (AVX2)
-                              && CPU_FEATURE_USABLE (RTM)),
-                             __strncmp_avx2_rtm)
-             IFUNC_IMPL_ADD (array, i, strncmp,
-                             (CPU_FEATURE_USABLE (AVX512VL)
-                              && CPU_FEATURE_USABLE (AVX512BW)),
-                             __strncmp_evex)
-             IFUNC_IMPL_ADD (array, i, strncmp, CPU_FEATURE_USABLE (SSE4_2),
-                             __strncmp_sse42)
-             IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_sse2))
+             X86_IFUNC_IMPL_ADD_V4 (array, i, strncmp,
+                                    (CPU_FEATURE_USABLE (AVX512VL)
+                                     && CPU_FEATURE_USABLE (AVX512BW)),
+                                    __strncmp_evex)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strncmp,
+                                    CPU_FEATURE_USABLE (AVX2),
+                                    __strncmp_avx2)
+             X86_IFUNC_IMPL_ADD_V3 (array, i, strncmp,
+                                    (CPU_FEATURE_USABLE (AVX2)
+                                     && CPU_FEATURE_USABLE (RTM)),
+                                    __strncmp_avx2_rtm)
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strncmp,
+                                    CPU_FEATURE_USABLE (SSE4_2),
+                                    __strncmp_sse42)
+             /* ISA V2 wrapper for SSE2 implementation because the SSE2
+                implementation is also used at ISA level 2.  */
+             X86_IFUNC_IMPL_ADD_V2 (array, i, strncmp,
+                                    1,
+                                    __strncmp_sse2))
 
 #ifdef SHARED
   /* Support sysdeps/x86_64/multiarch/wmemset_chk.c.  */
index 296d32071bc0ab4dcab58539583a9ad969665f40..68646ef199ecb71ce93af9cdc98460c2c771437a 100644 (file)
 
 #include <init-arch.h>
 
-extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
-extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden;
+
 extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2) attribute_hidden;
 extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_rtm) attribute_hidden;
-extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden;
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden;
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
 
 static inline void *
 IFUNC_SELECTOR (void)
 {
-  const struct cpu_featurescpu_features = __get_cpu_features ();
+  const struct cpu_features *cpu_features = __get_cpu_features ();
 
-  if (CPU_FEATURE_USABLE_P (cpu_features, AVX2)
-      && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load))
+  if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX2)
+      && X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
+                                     AVX_Fast_Unaligned_Load, ))
     {
-      if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
-          && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW))
-        return OPTIMIZE (evex);
+      if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
+         && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512BW))
+       return OPTIMIZE (evex);
 
       if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
-        return OPTIMIZE (avx2_rtm);
+       return OPTIMIZE (avx2_rtm);
 
-      if (!CPU_FEATURES_ARCH_P (cpu_features, Prefer_No_VZEROUPPER))
-        return OPTIMIZE (avx2);
+      if (X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
+                                      Prefer_No_VZEROUPPER, !))
+       return OPTIMIZE (avx2);
     }
 
-  if (CPU_FEATURE_USABLE_P (cpu_features, SSE4_2)
+  if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, SSE4_2)
+      /* Keep this as a runtime check as its not guaranteed at ISA
+         level 2.  */
       && !CPU_FEATURES_ARCH_P (cpu_features, Slow_SSE4_2))
     return OPTIMIZE (sse42);
 
index 88c1c502afd98ddc5e8e5841f564d30cb2668c67..064722c2bd1442e34b1c06e79e115321c7270390 100644 (file)
 # define GENERIC sse2
 #endif
 
-extern __typeof (REDIRECT_NAME) OPTIMIZE (GENERIC) attribute_hidden;
-extern __typeof (REDIRECT_NAME) OPTIMIZE (sse4_1) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden;
+
 extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2) attribute_hidden;
 extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_rtm) attribute_hidden;
-extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden;
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse4_1) attribute_hidden;
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (GENERIC) attribute_hidden;
 
 static inline void *
 IFUNC_SELECTOR (void)
 {
-  const struct cpu_featurescpu_features = __get_cpu_features ();
+  const struct cpu_features *cpu_features = __get_cpu_features ();
 
-  if (CPU_FEATURE_USABLE_P (cpu_features, AVX2)
-      && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
-      && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load))
+  if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX2)
+      && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, BMI2)
+      && X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
+                                     AVX_Fast_Unaligned_Load, ))
     {
-      if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
-         && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW))
+      if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
+         && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512BW))
        return OPTIMIZE (evex);
 
       if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
        return OPTIMIZE (avx2_rtm);
 
-      if (!CPU_FEATURES_ARCH_P (cpu_features, Prefer_No_VZEROUPPER))
+      if (X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
+                                      Prefer_No_VZEROUPPER, !))
        return OPTIMIZE (avx2);
     }
 
-  if (CPU_FEATURE_USABLE_P (cpu_features, SSE4_1))
+  if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, SSE4_1))
     return OPTIMIZE (sse4_1);
 
   return OPTIMIZE (GENERIC);
index f300d7daf4aa565eeb31861bd080db8653109177..d1457ab60c61383396c348697bc641d23da6e2ec 100644 (file)
@@ -16,7 +16,9 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (3)
 
 # include <sysdep.h>
 
index 91329b18dca970d97125b8590fe53ece47d1d417..ea3a0a0a600d6e39333e3821f58208266c916054 100644 (file)
@@ -16,7 +16,9 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (4)
 
 # include <sysdep.h>
 # include "evex256-vecs.h"
index d92a4022dcb221acf28128ad7b4189bbc168ed41..4cc8b9e3b02a75bc0ebcd6e617c021ab5c25793a 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+/* MINIMUM_X86_ISA_LEVEL <= 2 because there is no V2 implementation
+   so we need this to build for ISA V2 builds. */
+#if ISA_SHOULD_BUILD (2)
+
 # ifndef MEMRCHR
 #  define MEMRCHR __memrchr_sse2
 # endif
-#endif
 
-#include <sysdep.h>
-#define VEC_SIZE                       16
-#define PAGE_SIZE                      4096
+# include <sysdep.h>
+# define VEC_SIZE                      16
+# define PAGE_SIZE                     4096
 
        .text
 ENTRY_P2ALIGN(MEMRCHR, 6)
-#ifdef __ILP32__
+# ifdef __ILP32__
        /* Clear upper bits.  */
        mov     %RDX_LP, %RDX_LP
-#endif
+# endif
        movd    %esi, %xmm0
 
        /* Get end pointer.  */
@@ -352,3 +356,4 @@ L(zero_3):
        ret
        /* 2-bytes from next cache line.  */
 END(MEMRCHR)
+#endif
index 09957fc3c543b40c12edb83d8e97b7b41a162da6..d408751f4c888b19508581a19295e22cb638a2da 100644 (file)
@@ -1,15 +1,2 @@
-#ifndef STRCMP
-# define STRCMP        __strcasecmp_l_avx2_rtm
-#endif
-
-#define _GLABEL(x)     x ## _rtm
-#define GLABEL(x)      _GLABEL(x)
-
-#define ZERO_UPPER_VEC_REGISTERS_RETURN        \
-       ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST
-
-#define VZEROUPPER_RETURN      jmp L(return_vzeroupper)
-
-#define SECTION(p)     p##.avx.rtm
-
-#include "strcasecmp_l-avx2.S"
+#define USE_AS_STRCASECMP_L
+#include "strcmp-avx2-rtm.S"
index e2762f2a222b2a65d75ee93a32b1438da31b2c39..167f866014b129ee6a8e69916cf06dcf2ecd61e5 100644 (file)
@@ -16,8 +16,5 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef STRCMP
-# define STRCMP        __strcasecmp_l_avx2
-#endif
 #define USE_AS_STRCASECMP_L
 #include "strcmp-avx2.S"
index 58642db748e3db71a07e2cf74ad07ee5de5f639e..012a0849307abceb641e8ca466ad8063dc27414e 100644 (file)
@@ -16,8 +16,5 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef STRCMP
-# define STRCMP        __strcasecmp_l_evex
-#endif
 #define USE_AS_STRCASECMP_L
 #include "strcmp-evex.S"
index a2b574139962df705cef6e94327055f7576e3ca4..6ffd09b513813049c9b3a2415e164212d09d71e3 100644 (file)
@@ -17,4 +17,5 @@
    <https://www.gnu.org/licenses/>.  */
 
 #define USE_AS_STRCASECMP_L
+
 #include "strcmp-sse2.S"
index 1a916cc95185daac2c6a657cf2d9817809ae34ca..425a40b8de17b5ae7d63928eccd9067ec9c348e9 100644 (file)
@@ -16,7 +16,9 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (3)
 
 # include <sysdep.h>
 
index ec739fb8f9f2f251f07d620df099ef418ee10233..a1c15c4419e22e08b2961c42864c8cc054e03985 100644 (file)
@@ -16,7 +16,9 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (4)
 
 # include <sysdep.h>
 
index 93e6f62d7fde4c74537de99c8298cb91abf9f250..bb092e3f61e37bf6d6f674b2fdcbaeeaa1c3de32 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+/* NB: atom builds with ISA level == 1 so no reason to hold onto this
+   at ISA level >= 2.  */
+#if ISA_SHOULD_BUILD (1)
 
 # include <sysdep.h>
 # include "asm-syntax.h"
index f7767ca543684d5da89f5b44d01da0b3e5cc7379..7a182f0c3be0b780126fc5049a9d9d618daa28b5 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc) || defined STRCHR
+#include <isa-level.h>
+
+/* MINIMUM_X86_ISA_LEVEL <= 2 because there is no V2 implementation
+   so we need this to build for ISA V2 builds. */
+#if ISA_SHOULD_BUILD (2)
+
 # ifndef STRCHR
 #  define STRCHR __strchr_sse2
 # endif
index de737580ebfcc7ff7bfd99bf52d544bd39f0b2c5..ce7441c53218cc6db75e7be7fa09345b65b81262 100644 (file)
 # define SYMBOL_NAME strchr
 # include <init-arch.h>
 
-extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
-extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2_no_bsf) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden;
+
 extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2) attribute_hidden;
 extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_rtm) attribute_hidden;
-extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden;
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2_no_bsf) attribute_hidden;
 
 static inline void *
 IFUNC_SELECTOR (void)
 {
-  const struct cpu_featurescpu_features = __get_cpu_features ();
+  const struct cpu_features *cpu_features = __get_cpu_features ();
 
-  if (CPU_FEATURE_USABLE_P (cpu_features, AVX2)
-      && CPU_FEATURE_USABLE_P (cpu_features, BMI2)
-      && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load))
+  if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX2)
+      && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, BMI2)
+      && X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
+                                     AVX_Fast_Unaligned_Load, ))
     {
-      if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
-         && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW))
+      if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
+         && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512BW))
        return OPTIMIZE (evex);
 
       if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
        return OPTIMIZE (avx2_rtm);
 
-      if (!CPU_FEATURES_ARCH_P (cpu_features, Prefer_No_VZEROUPPER))
+      if (X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
+                                      Prefer_No_VZEROUPPER, !))
        return OPTIMIZE (avx2);
     }
 
-  if (CPU_FEATURES_ARCH_P (cpu_features, Slow_BSF))
-    return OPTIMIZE (sse2_no_bsf);
+  if (X86_ISA_CPU_FEATURES_ARCH_P (cpu_features, Slow_BSF, !))
+    return OPTIMIZE (sse2);
 
-  return OPTIMIZE (sse2);
+  return OPTIMIZE (sse2_no_bsf);
 }
 
 libc_ifunc_redirected (__redirect_strchr, strchr, IFUNC_SELECTOR ());
index fa0cc097601e5eebc026ac77b5bf13b295a738cd..10ad5e6058be51e9953794b0f9be57b4992e9e3e 100644 (file)
@@ -1,3 +1,8 @@
-#define STRCHR __strchrnul_avx2
+#ifndef STRCHRNUL
+# define STRCHRNUL     __strchrnul_avx2
+#endif
+
+#define STRCHR STRCHRNUL
 #define USE_AS_STRCHRNUL 1
+
 #include "strchr-avx2.S"
index 064fe7ca9e9ca31b89206f88d2d1ed23964d5ec1..0f216cb47f7bde4f0ff0703e0f1509e07f2f0d38 100644 (file)
@@ -1,3 +1,8 @@
-#define STRCHR __strchrnul_evex
+#ifndef STRCHRNUL
+# define STRCHRNUL     __strchrnul_evex
+#endif
+
+#define STRCHR STRCHRNUL
 #define USE_AS_STRCHRNUL 1
+
 #include "strchr-evex.S"
index 7238977a21b46f655ba73933a639aa72ab6730d2..7ee81ae5105df297787b198b6b2aef6cbdf69618 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
-# ifndef STRCHR
-#  define STRCHR       __strchrnul_sse2
-# endif
+#ifndef STRCHRNUL
+# define STRCHRNUL     __strchrnul_sse2
 #endif
-
 #define AS_STRCHRNUL
+#define STRCHR STRCHRNUL
 
 #include "strchr-sse2.S"
index aecd30d97f02e999b22608e263ed02ff1b878e7a..74f1f996a9b44a43bba57982f53c47f1f9690efb 100644 (file)
@@ -1,12 +1,9 @@
-#ifndef STRCMP
-# define STRCMP __strcmp_avx2_rtm
-#endif
-
 #define ZERO_UPPER_VEC_REGISTERS_RETURN \
   ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST
 
 #define VZEROUPPER_RETURN jmp   L(return_vzeroupper)
 
 #define SECTION(p) p##.avx.rtm
+#define STRCMP_ISA     _avx2_rtm
 
 #include "strcmp-avx2.S"
index 3ab21e3a586f33513c75c8410de509f5dd04b1f0..4c01d664e8769fbcd0768000b9cf923d17f0eae1 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (3)
+
+# ifndef STRCMP_ISA
+#  define STRCMP_ISA   _avx2
+# endif
+
+# include "strcmp-naming.h"
 
 # include <sysdep.h>
 
 
 # ifdef USE_AS_STRCASECMP_L
 #  ifdef USE_AS_STRNCMP
-#   define STRCASECMP  __strncasecmp_avx2
 #   define LOCALE_REG  rcx
 #   define LOCALE_REG_LP       RCX_LP
-#   define STRCASECMP_L_NONASCII       __strncasecmp_l_nonascii
 #  else
-#   define STRCASECMP  __strcasecmp_avx2
 #   define LOCALE_REG  rdx
 #   define LOCALE_REG_LP       RDX_LP
-#   define STRCASECMP_L_NONASCII       __strcasecmp_l_nonascii
 #  endif
 # endif
 
        .type   STRCMP, @function
        .globl  STRCMP
 
-# ifndef GLABEL
-#  define GLABEL(...)  __VA_ARGS__
-# endif
-
 # ifdef USE_AS_STRCASECMP_L
-ENTRY (GLABEL(STRCASECMP))
+ENTRY (STRCASECMP)
        movq    __libc_tsd_LOCALE@gottpoff(%rip), %rax
        mov     %fs:(%rax), %LOCALE_REG_LP
 
        /* Either 1 or 5 bytes (dependeing if CET is enabled).  */
        .p2align 4
-END (GLABEL(STRCASECMP))
+END (STRCASECMP)
        /* FALLTHROUGH to strcasecmp/strncasecmp_l.  */
 # endif
 
index afbf13a230b92da71c65635dfe8b5ad3dd18c3fd..e482d0167f9b5e7891440c8a9334977e9babb6b0 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (4)
+
+# define STRCMP_ISA    _evex
+# include "strcmp-naming.h"
 
 # include <sysdep.h>
 # if defined USE_AS_STRCASECMP_L
 # define VMOVA vmovdqa64
 
 # ifdef USE_AS_WCSCMP
-#  ifndef OVERFLOW_STRCMP
-#   define OVERFLOW_STRCMP     __wcscmp_evex
-#  endif
-
 #  define TESTEQ       subl $0xff,
        /* Compare packed dwords.  */
 #  define VPCMP        vpcmpd
        /* 1 dword char == 4 bytes.  */
 #  define SIZE_OF_CHAR 4
 # else
-#  ifndef OVERFLOW_STRCMP
-#   define OVERFLOW_STRCMP     __strcmp_evex
-#  endif
-
 #  define TESTEQ       incl
        /* Compare packed bytes.  */
 #  define VPCMP        vpcmpb
 
 # ifdef USE_AS_STRCASECMP_L
 #  ifdef USE_AS_STRNCMP
-#   define STRCASECMP  __strncasecmp_evex
 #   define LOCALE_REG  rcx
 #   define LOCALE_REG_LP       RCX_LP
-#   define STRCASECMP_L_NONASCII       __strncasecmp_l_nonascii
 #  else
-#   define STRCASECMP  __strcasecmp_evex
 #   define LOCALE_REG  rdx
 #   define LOCALE_REG_LP       RDX_LP
-#   define STRCASECMP_L_NONASCII       __strcasecmp_l_nonascii
 #  endif
 # endif
 
        .align  16
        .type   STRCMP, @function
        .globl  STRCMP
-
 # ifdef USE_AS_STRCASECMP_L
 ENTRY (STRCASECMP)
        movq    __libc_tsd_LOCALE@gottpoff(%rip), %rax
index 0d691b78a8491e7c96c7eaa7a474b350704344be..33c18a28e8f04e4a0cc51685ce3f27bb50a5d5c1 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
 
-#include "sysdep.h"
+/* Continue building as ISA level 2.  We use this as ISA V2 default
+   because strcmp-sse42 uses pcmpstri (slow on some SSE4.2
+   processors) and this implementation is potenially faster than
+   strcmp-sse42 (aside from the slower page cross case).  */
+#if ISA_SHOULD_BUILD (2)
 
-ENTRY ( __strcmp_sse2_unaligned)
+# define STRCMP_ISA    _sse2_unaligned
+# include "strcmp-naming.h"
+
+# include "sysdep.h"
+
+ENTRY (STRCMP)
        movl    %edi, %eax
        xorl    %edx, %edx
        pxor    %xmm7, %xmm7
@@ -208,6 +217,5 @@ L(cross_page):
 L(different):
        subl    %ecx, %eax
        ret
-END (__strcmp_sse2_unaligned)
-
+END (STRCMP)
 #endif
index b1220231abd7382ce662aa75045eb0b89f8fea82..3c69fc1df1b0031fc226243096a54bbe8a184488 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc) || IS_IN (rtld)
+#include <isa-level.h>
+
+/* Continue building at ISA level 2 as the strcmp-sse42 is not always
+   preferable for ISA level == 2 CPUs.  */
+#if ISA_SHOULD_BUILD (2)
 
 # define STRCMP_ISA    _sse2
 # include "strcmp-naming.h"
index 963e208ccb711a7c20b83e03e8b9df9d6d1bc6cc..dc6fc90e14a07f5f7bdd869ecfd958f7152bd05a 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (2)
+
 # include <sysdep.h>
 
 # define STRCMP_ISA    _sse42
@@ -1766,7 +1769,6 @@ LABEL(unaligned_table):
        .int    LABEL(ashr_0) - LABEL(unaligned_table)
 
 # undef LABEL
-# undef GLABEL
 # undef SECTION
 # undef movdqa
 # undef movdqu
index 9c1677724cf7c32eef819ac54c200aed8d673e26..fdd5afe3af16eb473e3cfb7a39eb59836af3883a 100644 (file)
 # define SYMBOL_NAME strcmp
 # include <init-arch.h>
 
-extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
-extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2_unaligned) attribute_hidden;
-extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden;
+
 extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2) attribute_hidden;
 extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_rtm) attribute_hidden;
-extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden;
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden;
+
+extern __typeof (REDIRECT_NAME)
+    OPTIMIZE (sse2_unaligned) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
+
+
 
 static inline void *
 IFUNC_SELECTOR (void)
 {
-  const struct cpu_featurescpu_features = __get_cpu_features ();
+  const struct cpu_features *cpu_features = __get_cpu_features ();
 
-  if (CPU_FEATURE_USABLE_P (cpu_features, AVX2)
-      && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load))
+  if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX2)
+      && X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
+                                     AVX_Fast_Unaligned_Load, ))
     {
-      if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
-         && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)
-         && CPU_FEATURE_USABLE_P (cpu_features, BMI2))
+      if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
+         && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)
+         && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, BMI2))
        return OPTIMIZE (evex);
 
       if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
        return OPTIMIZE (avx2_rtm);
 
-      if (!CPU_FEATURES_ARCH_P (cpu_features, Prefer_No_VZEROUPPER))
+      if (X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
+                                      Prefer_No_VZEROUPPER, !))
        return OPTIMIZE (avx2);
     }
 
-  if (CPU_FEATURE_USABLE_P (cpu_features, SSE4_2)
+  if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, SSE4_2)
+      /* Keep this as runtime check.  Some ISA level >= 2 CPUs such as
+        Tremont, Silvermont, and more check this.  */
       && !CPU_FEATURES_ARCH_P (cpu_features, Slow_SSE4_2))
     return OPTIMIZE (sse42);
 
+  /* Keep this as runtime check.  The standard SSE2 version has
+     meaningful optimizations around keeping all loads aligned in the
+     main loop which can benefit some ISA level >= 2 CPUs.  */
   if (CPU_FEATURES_ARCH_P (cpu_features, Fast_Unaligned_Load))
     return OPTIMIZE (sse2_unaligned);
 
index 9e36290dd246f247128d4a8216b0b1daea463110..0593fb303b3068115b3fba15b1c15b01d44a3a0e 100644 (file)
@@ -16,7 +16,9 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (3)
 
 # include <sysdep.h>
 
index 278c899691d89ba77fcb84f1d14a45fddd37279e..418e9f841171517744a65ff7ac2497b1833e90ca 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+/* UNUSED. Exists purely as reference implementation.  */
+
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (4)
 
 # include <sysdep.h>
 
index 59ade7749860d4b37d83bd81b42f0f4ab8868f45..2109ec2f7a2aa6d18a7fa39375db891386542dbe 100644 (file)
@@ -16,7 +16,9 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (4)
 
 # include <sysdep.h>
 
index 5be72267d558a2bf399bdb5eb93936cc4edb6681..a96ccbb2d58c7ad41115834a13de153d447b2ad8 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc) || defined STRLEN
-
-# ifndef STRLEN
-#  define STRLEN __strlen_sse2
-# endif
+#include <isa-level.h>
 
+/* ISA level >= 2 for both strlen and wcslen.  wcslen uses `pminud`
+   which is SSE4.1. strlen doesn't have an ISA level == 2
+   implementation so the SSE2 implementation must be built with ISA
+   level == 2.  */
+# if ISA_SHOULD_BUILD (2)
 
 # include <sysdep.h>
 
+# ifndef STRLEN
+#  define STRLEN       __strlen_sse2
+# endif
+
 # ifdef AS_WCSLEN
 #  define PMINU                pminud
 #  define PCMPEQ               pcmpeqd
@@ -82,7 +87,7 @@ L(n_nonzero):
    suffice.  */
        mov     %RSI_LP, %R10_LP
        sar     $62, %R10_LP
-       jnz     __wcslen_sse4_1
+       jnz     OVERFLOW_STRLEN
        sal     $2, %RSI_LP
 #  endif
 
index 58c05dcfb864379186bcffdcd8f7b9ce14146471..c2596ab103e512cc908152cef5b5c8b27593ccf1 100644 (file)
@@ -1,16 +1,4 @@
-#ifndef STRCMP
-# define STRCMP        __strncasecmp_l_avx2_rtm
-#endif
+#define USE_AS_STRCASECMP_L
+#define USE_AS_STRNCMP
 
-#define _GLABEL(x)     x ## _rtm
-#define GLABEL(x)      _GLABEL(x)
-
-#define ZERO_UPPER_VEC_REGISTERS_RETURN        \
-       ZERO_UPPER_VEC_REGISTERS_RETURN_XTEST
-
-#define VZEROUPPER_RETURN      jmp L(return_vzeroupper)
-
-#define SECTION(p)     p##.avx.rtm
-#define OVERFLOW_STRCMP        __strcasecmp_l_avx2_rtm
-
-#include "strncase_l-avx2.S"
+#include "strcmp-avx2-rtm.S"
index 48c0aa21f84ad32c42786ab06306c10d75b4790f..d00687aac526a524f7aeae0146b5a8be62995dfb 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef STRCMP
-# define STRCMP        __strncasecmp_l_avx2
-#endif
 #define USE_AS_STRCASECMP_L
 #define USE_AS_STRNCMP
-#ifndef OVERFLOW_STRCMP
-# define OVERFLOW_STRCMP       __strcasecmp_l_avx2
-#endif
+
 #include "strcmp-avx2.S"
index 8a5af3695cb8cfffb985db73dc7bd7130d3ab76d..1a79758065a1cc798b22eca11be39fa6301636fd 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#ifndef STRCMP
-# define STRCMP        __strncasecmp_l_evex
-#endif
-#define OVERFLOW_STRCMP        __strcasecmp_l_evex
 #define USE_AS_STRCASECMP_L
 #define USE_AS_STRNCMP
 #include "strcmp-evex.S"
index 68bad365ba728eecc879a847341ba7eb7e700be7..6bb6be85858bd45bc35d8bac73e0be18d33f2760 100644 (file)
@@ -1,4 +1,2 @@
-#define STRCMP __strncmp_avx2_rtm
 #define USE_AS_STRNCMP 1
-#define OVERFLOW_STRCMP        __strcmp_avx2_rtm
 #include "strcmp-avx2-rtm.S"
index f138e9f1fdcf277c35fd8fc54faf950a33464efb..def3509c4cff2eed5d590ef5da5693c7c1405e5d 100644 (file)
@@ -1,4 +1,3 @@
-#define STRCMP __strncmp_avx2
 #define USE_AS_STRNCMP 1
-#define OVERFLOW_STRCMP __strcmp_avx2
+
 #include "strcmp-avx2.S"
index a1d53e8c9f894e3171be91d8b77940cdb1112188..aa69c189281f3ea8e98f04b2c742e5223e4d606c 100644 (file)
@@ -1,3 +1,2 @@
-#define STRCMP __strncmp_evex
 #define USE_AS_STRNCMP 1
 #include "strcmp-evex.S"
index 70ae6547c9ed84e1c31fd194f2b33040eb9d0ca8..4ebe4bde30994e824b2a843033a7cc03d533537b 100644 (file)
 # define SYMBOL_NAME strncmp
 # include <init-arch.h>
 
-extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
-extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden;
+extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden;
+
 extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2) attribute_hidden;
 extern __typeof (REDIRECT_NAME) OPTIMIZE (avx2_rtm) attribute_hidden;
-extern __typeof (REDIRECT_NAME) OPTIMIZE (evex) attribute_hidden;
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden;
+
+extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden;
 
 static inline void *
 IFUNC_SELECTOR (void)
 {
-  const struct cpu_featurescpu_features = __get_cpu_features ();
+  const struct cpu_features *cpu_features = __get_cpu_features ();
 
-  if (CPU_FEATURE_USABLE_P (cpu_features, AVX2)
-      && CPU_FEATURES_ARCH_P (cpu_features, AVX_Fast_Unaligned_Load))
+  if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX2)
+      && X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
+                                     AVX_Fast_Unaligned_Load, ))
     {
-      if (CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
-         && CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)
-         && CPU_FEATURE_USABLE_P (cpu_features, BMI2))
+      if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512VL)
+         && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, AVX512BW)
+         && X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, BMI2))
        return OPTIMIZE (evex);
 
       if (CPU_FEATURE_USABLE_P (cpu_features, RTM))
        return OPTIMIZE (avx2_rtm);
 
-      if (!CPU_FEATURES_ARCH_P (cpu_features, Prefer_No_VZEROUPPER))
+      if (X86_ISA_CPU_FEATURES_ARCH_P (cpu_features,
+                                      Prefer_No_VZEROUPPER, !))
        return OPTIMIZE (avx2);
     }
 
-  if (CPU_FEATURE_USABLE_P (cpu_features, SSE4_2)
+  if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, SSE4_2)
       && !CPU_FEATURES_ARCH_P (cpu_features, Slow_SSE4_2))
     return OPTIMIZE (sse42);
 
index c4062b22f7af426129e116fea48abe313183a38c..c4a12097f0678efae10a0e84992943269d527a32 100644 (file)
@@ -1,4 +1,8 @@
-#define STRLEN __strnlen_avx2
+#ifndef STRNLEN
+# define STRNLEN __strnlen_avx2
+#endif
+
 #define USE_AS_STRNLEN 1
+#define STRLEN STRNLEN
 
 #include "strlen-avx2.S"
index 722022f303cc0ab581b0c957d7ceb933474b97f9..64a9fc26064db18aa788df65104244dc20a37ec2 100644 (file)
@@ -1,4 +1,8 @@
-#define STRLEN __strnlen_evex
+#ifndef STRNLEN
+# define STRNLEN __strnlen_evex
+#endif
+
 #define USE_AS_STRNLEN 1
+#define STRLEN STRNLEN
 
 #include "strlen-evex.S"
index a50c7d6a287629d8f5a4563d454089e508d0c4cb..8841ba9faf3c56cd77c6a7a2059620a21e2883bb 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
-# ifndef STRLEN
-#  define STRLEN       __strnlen_sse2
-# endif
+#ifndef STRNLEN
+# define STRNLEN       __strnlen_sse2
 #endif
 
-#define AS_STRNLEN
+#define AS_STRNLEN     1
+#define STRLEN STRNLEN
+
 #include "strlen-sse2.S"
index eb128a2ae33960cdbcb74ac37ccd5a168915dd6f..924171d8e49166d0d04313367b59a6df32c2d286 100644 (file)
@@ -16,7 +16,9 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (3)
 
 # include <sysdep.h>
 
index 8014c285b31b4f6b3b29131d4be8ebefd5b435bc..992b45fb47fbe27907fdfa98866778c7b2dfa952 100644 (file)
@@ -16,7 +16,9 @@
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (4)
 
 # include <sysdep.h>
 
index 6ee7a5e33a07a78deea830925308fef88f994078..892e861fa8c77c4379f02ce4363c0758c8875040 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+/* ISA level >= 2 because there are no {wcs|str}rchr-sse4
+   implementations.  */
+#if ISA_SHOULD_BUILD (2)
+
+# include <sysdep.h>
+
 # ifndef STRRCHR
 #  define STRRCHR __strrchr_sse2
 # endif
-#endif
-
-#include <sysdep.h>
 
-#ifdef USE_AS_WCSRCHR
-# define PCMPEQ        pcmpeqd
-# define CHAR_SIZE     4
-# define PMINU pminud
-#else
-# define PCMPEQ        pcmpeqb
-# define CHAR_SIZE     1
-# define PMINU pminub
-#endif
+# ifdef USE_AS_WCSRCHR
+#  define PCMPEQ       pcmpeqd
+#  define CHAR_SIZE    4
+#  define PMINU        pminud
+# else
+#  define PCMPEQ       pcmpeqb
+#  define CHAR_SIZE    1
+#  define PMINU        pminub
+# endif
 
-#define PAGE_SIZE      4096
-#define VEC_SIZE       16
+# define PAGE_SIZE     4096
+# define VEC_SIZE      16
 
        .text
 ENTRY(STRRCHR)
        movd    %esi, %xmm0
        movq    %rdi, %rax
        andl    $(PAGE_SIZE - 1), %eax
-#ifndef USE_AS_WCSRCHR
+# ifndef USE_AS_WCSRCHR
        punpcklbw %xmm0, %xmm0
        punpcklwd %xmm0, %xmm0
-#endif
+# endif
        pshufd  $0, %xmm0, %xmm0
        cmpl    $(PAGE_SIZE - VEC_SIZE), %eax
        ja      L(cross_page)
@@ -69,9 +73,9 @@ L(cross_page_continue):
        /* We are off by 3 for wcsrchr if search CHAR is non-zero. If
           search CHAR is zero we are correct. Either way `andq
           -CHAR_SIZE, %rax` gets the correct result.  */
-#ifdef USE_AS_WCSRCHR
+# ifdef USE_AS_WCSRCHR
        andq    $-CHAR_SIZE, %rax
-#endif
+# endif
 L(ret0):
        ret
 
@@ -85,9 +89,9 @@ L(first_vec_x0_test):
        jz      L(ret0)
        bsrl    %eax, %eax
        addq    %r8, %rax
-#ifdef USE_AS_WCSRCHR
+# ifdef USE_AS_WCSRCHR
        andq    $-CHAR_SIZE, %rax
-#endif
+# endif
        ret
 
        .p2align 4
@@ -100,9 +104,9 @@ L(first_vec_x1):
        jz      L(first_vec_x0_test)
        bsrl    %eax, %eax
        leaq    (VEC_SIZE)(%rdi, %rax), %rax
-#ifdef USE_AS_WCSRCHR
+# ifdef USE_AS_WCSRCHR
        andq    $-CHAR_SIZE, %rax
-#endif
+# endif
        ret
 
        .p2align 4
@@ -113,9 +117,9 @@ L(first_vec_x1_test):
        jz      L(first_vec_x0_test)
        bsrl    %eax, %eax
        leaq    (VEC_SIZE)(%rdi, %rax), %rax
-#ifdef USE_AS_WCSRCHR
+# ifdef USE_AS_WCSRCHR
        andq    $-CHAR_SIZE, %rax
-#endif
+# endif
        ret
 
        .p2align 4
@@ -128,9 +132,9 @@ L(first_vec_x2):
        jz      L(first_vec_x1_test)
        bsrl    %eax, %eax
        leaq    (VEC_SIZE * 2)(%rdi, %rax), %rax
-#ifdef USE_AS_WCSRCHR
+# ifdef USE_AS_WCSRCHR
        andq    $-CHAR_SIZE, %rax
-#endif
+# endif
        ret
 
        .p2align 4
@@ -165,27 +169,27 @@ L(first_loop):
        /* Since SSE2 no pminud so wcsrchr needs seperate logic for
           detecting zero. Note if this is found to be a bottleneck it
           may be worth adding an SSE4.1 wcsrchr implementation.  */
-#ifdef USE_AS_WCSRCHR
+# ifdef USE_AS_WCSRCHR
        movaps  %xmm5, %xmm6
        pxor    %xmm8, %xmm8
 
        PCMPEQ  %xmm8, %xmm5
        PCMPEQ  %xmm4, %xmm8
        por     %xmm5, %xmm8
-#else
+# else
        movaps  %xmm5, %xmm6
        PMINU   %xmm4, %xmm5
-#endif
+# endif
 
        movaps  %xmm4, %xmm9
        PCMPEQ  %xmm0, %xmm4
        PCMPEQ  %xmm0, %xmm6
        movaps  %xmm6, %xmm7
        por     %xmm4, %xmm6
-#ifndef USE_AS_WCSRCHR
+# ifndef USE_AS_WCSRCHR
        pxor    %xmm8, %xmm8
        PCMPEQ  %xmm5, %xmm8
-#endif
+# endif
        pmovmskb %xmm8, %ecx
        pmovmskb %xmm6, %eax
 
@@ -219,9 +223,9 @@ L(first_loop_old_match):
 
        bsrl    %eax, %eax
        addq    %rsi, %rax
-#ifdef USE_AS_WCSRCHR
+# ifdef USE_AS_WCSRCHR
        andq    $-CHAR_SIZE, %rax
-#endif
+# endif
        ret
 
        .p2align 4
@@ -247,9 +251,9 @@ L(new_match):
        jz      L(first_loop_old_match)
        bsrl    %eax, %eax
        addq    %rdi, %rax
-#ifdef USE_AS_WCSRCHR
+# ifdef USE_AS_WCSRCHR
        andq    $-CHAR_SIZE, %rax
-#endif
+# endif
        ret
 
        /* Save minimum state for getting most recent match. We can
@@ -267,27 +271,27 @@ L(second_loop):
        /* Since SSE2 no pminud so wcsrchr needs seperate logic for
           detecting zero. Note if this is found to be a bottleneck it
           may be worth adding an SSE4.1 wcsrchr implementation.  */
-#ifdef USE_AS_WCSRCHR
+# ifdef USE_AS_WCSRCHR
        movaps  %xmm5, %xmm6
        pxor    %xmm8, %xmm8
 
        PCMPEQ  %xmm8, %xmm5
        PCMPEQ  %xmm4, %xmm8
        por     %xmm5, %xmm8
-#else
+# else
        movaps  %xmm5, %xmm6
        PMINU   %xmm4, %xmm5
-#endif
+# endif
 
        movaps  %xmm4, %xmm9
        PCMPEQ  %xmm0, %xmm4
        PCMPEQ  %xmm0, %xmm6
        movaps  %xmm6, %xmm7
        por     %xmm4, %xmm6
-#ifndef USE_AS_WCSRCHR
+# ifndef USE_AS_WCSRCHR
        pxor    %xmm8, %xmm8
        PCMPEQ  %xmm5, %xmm8
-#endif
+# endif
 
        pmovmskb %xmm8, %ecx
        pmovmskb %xmm6, %eax
@@ -312,9 +316,9 @@ L(second_loop_old_match):
        orl     %ecx, %eax
        bsrl    %eax, %eax
        addq    %rsi, %rax
-#ifdef USE_AS_WCSRCHR
+# ifdef USE_AS_WCSRCHR
        andq    $-CHAR_SIZE, %rax
-#endif
+# endif
        ret
 
        .p2align 4
@@ -340,9 +344,9 @@ L(second_loop_new_match):
        jz      L(second_loop_old_match)
        bsrl    %eax, %eax
        addq    %rdi, %rax
-#ifdef USE_AS_WCSRCHR
+# ifdef USE_AS_WCSRCHR
        andq    $-CHAR_SIZE, %rax
-#endif
+# endif
        ret
 
        .p2align 4,, 4
@@ -366,9 +370,10 @@ L(cross_page):
        jz      L(ret1)
        bsrl    %eax, %eax
        addq    %rdi, %rax
-#ifdef USE_AS_WCSRCHR
+# ifdef USE_AS_WCSRCHR
        andq    $-CHAR_SIZE, %rax
-#endif
+# endif
 L(ret1):
        ret
 END(STRRCHR)
+#endif
index c6aa8f45a60d175826c3d4e6eb483495a2cbf424..dc342a9f44d753a939f6d6426f3eb518abc9a95a 100644 (file)
@@ -17,6 +17,7 @@
    <https://www.gnu.org/licenses/>.  */
 
 #include <sysdep.h>
+#include "../strchr-isa-default-impl.h"
 
 ENTRY(__strstr_sse2_unaligned)
        movzbl  (%rsi), %eax
@@ -75,7 +76,7 @@ L(next_pair_index):
        .p2align 4
 L(strchr):
        movzbl  %al, %esi
-       jmp     __strchr_sse2
+       jmp     DEFAULT_STRCHR
 
        .p2align 4
 L(pair_loop):
index 67726b6837399e7a5995d1f738a18c469239b494..f404888a934ab47233e38e5750d72437d314372f 100644 (file)
@@ -1,3 +1,8 @@
-#define STRCHR __wcschr_avx2
+#ifndef WCSCHR
+# define WCSCHR        __wcschr_avx2
+#endif
+
+#define STRCHR WCSCHR
 #define USE_AS_WCSCHR 1
+
 #include "strchr-avx2.S"
index 7cb8f1e41ab971251f8bea23840f79aca5aade7a..b5ccc59230a6e59e668e75a023d28ba59927e67a 100644 (file)
@@ -1,3 +1,8 @@
-#define STRCHR __wcschr_evex
+#ifndef WCSCHR
+# define WCSCHR        __wcschr_evex
+#endif
+
+#define STRCHR WCSCHR
 #define USE_AS_WCSCHR 1
+
 #include "strchr-evex.S"
index c872926ba943bbb2338b46e9c8462347955d4483..1c83957cbc1ca6367c90864b93e891854e7723d6 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
+
+#include <isa-level.h>
+
+/* ISA level >= 2 because there is no wcschr-sse4 implementations.  */
+#if ISA_SHOULD_BUILD (2)
+
 # ifndef WCSCHR
 #  define WCSCHR __wcschr_sse2
 # endif
-#endif
 
-#include <sysdep.h>
+# include <sysdep.h>
 
        .text
 ENTRY (WCSCHR)
@@ -155,3 +159,4 @@ L(return_null):
        ret
 
 END (WCSCHR)
+#endif
index d6ca2b80644f2f018797aabbbd228d8f76655e16..f17a8969cb016661f67295f5b6efba3a1e9efb56 100644 (file)
@@ -1,4 +1,3 @@
-#define STRCMP __wcscmp_avx2_rtm
 #define USE_AS_WCSCMP 1
 
 #include "strcmp-avx2-rtm.S"
index e5da4da689dfc6d3e70f244d70e6c46fef23ef39..0a71f907f03ca599148ab52e903ad26bbea2df64 100644 (file)
@@ -1,4 +1,3 @@
-#define STRCMP __wcscmp_avx2
 #define USE_AS_WCSCMP 1
 
 #include "strcmp-avx2.S"
index 42e73e51eb5ed0bea1bf2440abb9af3adcb6e36f..b0337a83112bd4b63ee08232b6cef717bf256c90 100644 (file)
@@ -1,4 +1,3 @@
-#define STRCMP __wcscmp_evex
 #define USE_AS_WCSCMP 1
 
 #include "strcmp-evex.S"
index 6cb7d9faf9b0865fbb151bb04db118b09e216592..3f32e8127d77467b6d61daef9807aa8520fd52bf 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#define USE_AS_WCSCMP
-#define STRCMP_ISA     _sse2
-#include "strcmp-naming.h"
+#include <isa-level.h>
 
-#include <sysdep.h>
+/* ISA level >= 2 because there is no wcscmp-sse4 implementations.  */
+#if ISA_SHOULD_BUILD (2)
+# include <sysdep.h>
+
+/* Needed to get right name.  */
+# define USE_AS_WCSCMP
+# define STRCMP_ISA    _sse2
+# include "strcmp-naming.h"
 
 /* Note: wcscmp uses signed comparison, not unsighed as in strcmp function. */
 
@@ -949,3 +954,4 @@ L(equal):
        ret
 
 END (STRCMP)
+#endif
index c9224f1bc575dea2cac6bfd2a19589292e3a4f44..9784d8f780b8e62df022fe86ea0a5b8d2a6072f2 100644 (file)
@@ -1,4 +1,8 @@
-#define STRLEN __wcslen_avx2
+#ifndef WCSLEN
+# define WCSLEN        __wcslen_avx2
+#endif
+
+#define STRLEN WCSLEN
 #define USE_AS_WCSLEN 1
 
 #include "strlen-avx2.S"
index bdafa83bd531f8dcfc23eb8c52f30bd47a3c5258..df21bac63c03dcb627717f62ed241f9dbcbb9926 100644 (file)
@@ -1,4 +1,8 @@
-#define STRLEN __wcslen_evex
+#ifndef WCSLEN
+# define WCSLEN        __wcslen_evex
+#endif
+
+#define STRLEN WCSLEN
 #define USE_AS_WCSLEN 1
 
 #include "strlen-evex.S"
index 944c3bd9c6e50967f527e31fa6333402d95f948e..e9c518a93203a57cd51dc587d377f91100c72970 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
-# ifndef WCSLEN
-#  define WCSLEN __wcslen_sse2
-# endif
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (1)
+
+# include <sysdep.h>
+
+#ifndef WCSLEN
+# define WCSLEN        __wcslen_sse2
 #endif
 
-#include <sysdep.h>
 
        .text
 ENTRY (WCSLEN)
@@ -235,3 +238,5 @@ L(exit_tail7):
        ret
 
 END (WCSLEN)
+
+#endif
index c88e8342a1f780d021be115621bac8cd2262bffc..126d183e750d8ff2d1c383d499d9ee617f5150eb 100644 (file)
@@ -1,5 +1,9 @@
-#define AS_WCSLEN
-#define STRLEN __wcslen_sse4_1
-#define SECTION(p)     p##.sse4.1
+#ifndef WCSLEN
+# define WCSLEN        __wcslen_sse4_1
+#endif
+
+#define AS_WCSLEN      1
+#define STRLEN WCSLEN
+#define SECTION(p)             p##.sse4.1
 
 #include "strlen-sse2.S"
index f467582cbedd45357be8f4e37b66edf8ed4bd4c5..099a60c48ea55b758f7c795ed98b2a084aaa57e3 100644 (file)
@@ -1,5 +1,3 @@
-#define STRCMP __wcsncmp_avx2_rtm
 #define USE_AS_STRNCMP 1
 #define USE_AS_WCSCMP 1
-#define OVERFLOW_STRCMP        __wcscmp_avx2_rtm
 #include "strcmp-avx2-rtm.S"
index e9ede522b8bde27d1ebea2ad12aeca5b23442710..fc26b593d08eac27162a13869020623cd458744f 100644 (file)
@@ -1,5 +1,4 @@
-#define STRCMP __wcsncmp_avx2
 #define USE_AS_STRNCMP 1
 #define USE_AS_WCSCMP 1
-#define OVERFLOW_STRCMP        __wcscmp_avx2
+
 #include "strcmp-avx2.S"
index 8a8e310713eb59079fab4452efe4e2626f53ee00..d3a92e20001bbbe3cea7854dc2934f9f5b230a7f 100644 (file)
@@ -1,4 +1,3 @@
-#define STRCMP __wcsncmp_evex
 #define USE_AS_STRNCMP 1
 #define USE_AS_WCSCMP 1
 
index 658d541886ac391f00ff2f2daa57e1d6914483eb..b0cf4e87d5bff9812a5117a9b72dcd312c9d1a8c 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#define WCSNCMP __wcsncmp_generic
-#include <wcsmbs/wcsncmp.c>
+#include <isa-level.h>
+#if ISA_SHOULD_BUILD (2)
+
+# define WCSNCMP __wcsncmp_generic
+# include <wcsmbs/wcsncmp.c>
+
+#endif
index fac83546b53bf1a0a69a206ecf21672f6ae7baa5..12c3a0fd05243582deee2581539945ed361c3bd4 100644 (file)
@@ -1,4 +1,8 @@
-#define STRLEN __wcsnlen_avx2
+#ifndef WCSNLEN
+# define WCSNLEN       __wcsnlen_avx2
+#endif
+
+#define STRLEN WCSNLEN
 #define USE_AS_WCSLEN 1
 #define USE_AS_STRNLEN 1
 
index 24773bb4e2327ca4c45e856f08a9e207b5a402d6..e2aad94c1e8dd13aacdcfe7880d8f6c4f33fbafb 100644 (file)
@@ -1,4 +1,8 @@
-#define STRLEN __wcsnlen_evex
+#ifndef WCSNLEN
+# define WCSNLEN       __wcsnlen_evex
+#endif
+
+#define STRLEN WCSNLEN
 #define USE_AS_WCSLEN 1
 #define USE_AS_STRNLEN 1
 
index 2d75da7709b8b48ffdecf723fc01306ce1efe62b..8b466aac2f42e14d95f2f418c57b5a33416b66c4 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (1)
 
-#if IS_IN (libc)
 # include <wchar.h>
 
-# define WCSNLEN __wcsnlen_generic
+# ifndef WCSNLEN
+#  define WCSNLEN __wcsnlen_generic
+# endif
 
 extern __typeof (wcsnlen) __wcsnlen_generic;
-#endif
 
-#include "wcsmbs/wcsnlen.c"
+# include "wcsmbs/wcsnlen.c"
+
+#endif
index 17cdedc2a975a162d2bf7756d8e35aaa754dc62d..8f534102a2818d3ffb21e0d1a1f39a1a3aeb620e 100644 (file)
@@ -1,6 +1,11 @@
+#ifndef WCSNLEN
+# define WCSNLEN       __wcsnlen_sse4_1
+# define OVERFLOW_STRLEN       __wcslen_sse4_1
+#endif
+
 #define AS_WCSLEN
 #define AS_STRNLEN
-#define STRLEN __wcsnlen_sse4_1
+#define STRLEN WCSNLEN
 #define SECTION(p)     p##.sse4.1
 
 #include "strlen-sse2.S"
index cf8a239ab2aa414a918ba1c62abeb786634f2a4c..6eaf5e090bd719f6776040916eeea066ed71655c 100644 (file)
@@ -1,3 +1,8 @@
-#define STRRCHR __wcsrchr_avx2
+#ifndef WCSRCHR
+# define WCSRCHR       __wcsrchr_avx2
+#endif
+
+#define STRRCHR        WCSRCHR
 #define USE_AS_WCSRCHR 1
+
 #include "strrchr-avx2.S"
index c64602f7dc154ad6f1522f1bbeb50771918c5da1..e5c5fe3bf28a59663d7196746e360d9c8eff3ae9 100644 (file)
@@ -1,3 +1,7 @@
-#define STRRCHR __wcsrchr_evex
+#ifndef WCSRCHR
+# define WCSRCHR       __wcsrchr_evex
+#endif
+
+#define STRRCHR        WCSRCHR
 #define USE_AS_WCSRCHR 1
 #include "strrchr-evex.S"
index d9259720f8a8926fc511e9f97eb9e3fcd1fed6a1..21388d900ce1075ab4ed205b1fa44cc136e551fa 100644 (file)
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#if IS_IN (libc)
-# ifndef STRRCHR
-#  define STRRCHR      __wcsrchr_sse2
-# endif
+#ifndef WCSRCHR
+# define WCSRCHR       __wcsrchr_sse2
 #endif
 
+#define STRRCHR        WCSRCHR
 #define USE_AS_WCSRCHR 1
 #define NO_PMINU       1
 
index 84fd7fdfd322fcd3b1c6d33ae9add221b53911b5..5afa7ea0987f5f38dcae26b159dce0d7631c1c61 100644 (file)
@@ -1,11 +1,35 @@
+/* strcasecmp_l dispatch for RTLD and non-multiarch build
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
 /* Symbols = __strcasecmp_l and __strcasecmp.  */
 
-#include "multiarch/strcasecmp_l-sse2.S"
+#define DEFAULT_IMPL_V1        "multiarch/strcasecmp_l-sse2.S"
+/* This may cause regressions on some processors that heavily prefer
+   aligned loads or have slow a implementation of the `pcmpstri`
+   instruction.  */
+#define DEFAULT_IMPL_V2        "multiarch/strcasecmp_l-sse4_2.S"
+#define DEFAULT_IMPL_V3        "multiarch/strcasecmp_l-avx2.S"
+#define DEFAULT_IMPL_V4        "multiarch/strcasecmp_l-evex.S"
 
-libc_hidden_builtin_def (__strcasecmp_l)
+#include "isa-default-impl.h"
 
+libc_hidden_def (__strcasecmp_l)
 weak_alias (__strcasecmp_l, strcasecmp_l)
-libc_hidden_def (strcasecmp_l)
 
-weak_alias (__strcasecmp, strcasecmp)
 libc_hidden_def (__strcasecmp)
+weak_alias (__strcasecmp, strcasecmp)
diff --git a/sysdeps/x86_64/strchr-isa-default-impl.h b/sysdeps/x86_64/strchr-isa-default-impl.h
new file mode 100644 (file)
index 0000000..0c8cbc6
--- /dev/null
@@ -0,0 +1,28 @@
+/* Set default strchr impl based on ISA level.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#include <isa-level.h>
+#if MINIMUM_X86_ISA_LEVEL == 1 || MINIMUM_X86_ISA_LEVEL == 2
+# define DEFAULT_STRCHR        __strchr_sse2
+#elif MINIMUM_X86_ISA_LEVEL == 3
+# define DEFAULT_STRCHR        __strchr_avx2
+#elif MINIMUM_X86_ISA_LEVEL == 4
+# define DEFAULT_STRCHR        __strchr_evex
+#else
+# error "Unknown default strchr implementation"
+#endif
index 77c956c92ce5ade4b255a9221cc91378a2fe9fdf..1406c633e82b95f62666c2477a3acc805795e4e8 100644 (file)
@@ -1,5 +1,4 @@
-/* strchr (str, ch) -- Return pointer to first occurrence of CH in STR.
-   For AMD x86-64.
+/* strchr dispatch for RTLD and non-multiarch build
    Copyright (C) 2009-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
+#define STRCHR strchr
+
+#define DEFAULT_IMPL_V1        "multiarch/strchr-sse2.S"
+#define DEFAULT_IMPL_V3        "multiarch/strchr-avx2.S"
+#define DEFAULT_IMPL_V4        "multiarch/strchr-evex.S"
+
+#include "isa-default-impl.h"
 
-#define STRCHR strchr
-#include "multiarch/strchr-sse2.S"
 weak_alias (strchr, index)
 libc_hidden_builtin_def (strchr)
index 508e42db26a9d10d9c11e7b842455a673d466935..f1ef907296cd2f94f1a7620c8398dbfe8351f800 100644 (file)
@@ -1,6 +1,4 @@
-/* strchrnul (str, ch) -- Return pointer to first occurrence of CH in STR
-       or terminating NUL byte.
-   For AMD x86-64.
+/* strchrnul dispatch for RTLD and non-multiarch build
    Copyright (C) 2009-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#define STRCHR __strchrnul
-#include "multiarch/strchrnul-sse2.S"
+#define STRCHRNUL      __strchrnul
+
+#define DEFAULT_IMPL_V1        "multiarch/strchrnul-sse2.S"
+#define DEFAULT_IMPL_V3        "multiarch/strchrnul-avx2.S"
+#define DEFAULT_IMPL_V4        "multiarch/strchrnul-evex.S"
+
+#include "isa-default-impl.h"
 
 weak_alias (__strchrnul, strchrnul)
index 19e54bd3a7c6daf75d57e9b58105418d074e5a34..7c3cf87a42912a0e548a9bf7ff8376a674369e9b 100644 (file)
@@ -1,4 +1,4 @@
-/* Highly optimized version for x86-64.
+/* strcmp dispatch for RTLD and non-multiarch build
    Copyright (C) 1999-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
 
 /* Symbol = strcmp.  */
 
-#include "multiarch/strcmp-sse2.S"
+#define DEFAULT_IMPL_V1        "multiarch/strcmp-sse2.S"
+/* strcmp-sse2-unaligned.S is often faster than strcmp-sse42.S and
+   doesn't have the drawback of using the `pcmpstri` instruction
+   which can be very slow on some CPUs.  */
+#define DEFAULT_IMPL_V2        "multiarch/strcmp-sse2-unaligned.S"
+#define DEFAULT_IMPL_V3        "multiarch/strcmp-avx2.S"
+#define DEFAULT_IMPL_V4        "multiarch/strcmp-evex.S"
+
+#include "isa-default-impl.h"
+
 libc_hidden_builtin_def (strcmp)
index c2f5674f8db14f9cad5025bc5df2a305ff0945a8..e7cb4b1680b48e67dfc909b95ac4c5eb410c7140 100644 (file)
@@ -1,4 +1,4 @@
-/* SSE2 version of strlen.
+/* strlen dispatch for RTLD and non-multiarch build
    Copyright (C) 2021-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    <https://www.gnu.org/licenses/>.  */
 
 #define STRLEN strlen
-#include "multiarch/strlen-sse2.S"
+
+#define DEFAULT_IMPL_V1        "multiarch/strlen-sse2.S"
+#define DEFAULT_IMPL_V3        "multiarch/strlen-avx2.S"
+#define DEFAULT_IMPL_V4        "multiarch/strlen-evex.S"
+
+#include "isa-default-impl.h"
 
 libc_hidden_builtin_def (strlen)
index 3780fc50b1f64d3ebf3996173985ef46ea9de5df..de28ecf5d434d2da1a33b1b84971f932799f3ce2 100644 (file)
@@ -1,11 +1,35 @@
+/* strcasecmp_l dispatch for RTLD and non-multiarch build
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
 /* Symbols = __strncasecmp_l and __strncasecmp.  */
 
-#include "multiarch/strncase_l-sse2.S"
+#define DEFAULT_IMPL_V1        "multiarch/strncase_l-sse2.S"
+/* This may cause regressions on some processors that heavily prefer
+   aligned loads or have slow a implementation of the `pcmpstri`
+   instruction.  */
+#define DEFAULT_IMPL_V2        "multiarch/strncase_l-sse4_2.S"
+#define DEFAULT_IMPL_V3        "multiarch/strncase_l-avx2.S"
+#define DEFAULT_IMPL_V4        "multiarch/strncase_l-evex.S"
 
-libc_hidden_builtin_def (__strncasecmp_l)
+#include "isa-default-impl.h"
 
+libc_hidden_def (__strncasecmp_l)
 weak_alias (__strncasecmp_l, strncasecmp_l)
-libc_hidden_def (strncasecmp_l)
 
-weak_alias (__strncasecmp, strncasecmp)
 libc_hidden_def (__strncasecmp)
+weak_alias (__strncasecmp, strncasecmp)
index 13d9e82ee2bbacbee9c31d675a4ae9ebb1a685e7..afb251d9fe0e171206320ac7b39bd6813656c24c 100644 (file)
@@ -1,4 +1,31 @@
+/* strncmp dispatch for RTLD and non-multiarch build
+   Copyright (C) 1999-2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
 /* Symbol = strncmp.  */
 
-#include "multiarch/strncmp-sse2.S"
+#define DEFAULT_IMPL_V1        "multiarch/strncmp-sse2.S"
+/* This may cause regressions on some processors that heavily prefer
+   aligned loads or have slow a implementation of the `pcmpstri`
+   instruction.  */
+#define DEFAULT_IMPL_V2        "multiarch/strncmp-sse4_2.S"
+#define DEFAULT_IMPL_V3        "multiarch/strncmp-avx2.S"
+#define DEFAULT_IMPL_V4        "multiarch/strncmp-evex.S"
+
+#include "isa-default-impl.h"
+
 libc_hidden_builtin_def (strncmp)
index 174970d58fc072161e5b45232f39ef2d65969aab..b2c2149e07d9e18e190680c10a320581b1a11755 100644 (file)
@@ -1,6 +1,29 @@
-#define STRLEN __strnlen
-#include "multiarch/strnlen-sse2.S"
+/* strnlen dispatch for RTLD and non-multiarch build
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
 
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#define STRNLEN        __strnlen
+
+#define DEFAULT_IMPL_V1        "multiarch/strnlen-sse2.S"
+#define DEFAULT_IMPL_V3        "multiarch/strnlen-avx2.S"
+#define DEFAULT_IMPL_V4        "multiarch/strnlen-evex.S"
+
+#include "isa-default-impl.h"
+
+weak_alias (__strnlen, strnlen)
 libc_hidden_def (__strnlen)
-weak_alias (__strnlen, strnlen);
-libc_hidden_builtin_def (strnlen)
+libc_hidden_def (strnlen)
index f39da6045447b31dbf06d11f6b990aff0e4844f5..493d370a28ec06492f9843c20cde9f4ad077ab47 100644 (file)
@@ -1,4 +1,4 @@
-/* strrchr (str, ch) -- Return pointer to last occurrence of CH in STR.
+/* strrchr dispatch for RTLD and non-multiarch build
    Copyright (C) 2013-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    <https://www.gnu.org/licenses/>.  */
 
 #define STRRCHR        strrchr
-#include "multiarch/strrchr-sse2.S"
+
+#define DEFAULT_IMPL_V1        "multiarch/strrchr-sse2.S"
+#define DEFAULT_IMPL_V3        "multiarch/strrchr-avx2.S"
+#define DEFAULT_IMPL_V4        "multiarch/strrchr-evex.S"
+
+#include "isa-default-impl.h"
+
 weak_alias (strrchr, rindex)
 libc_hidden_builtin_def (strrchr)
index 80b12c42869574952c1fc685ffb620da96d8570c..01a432b8992c7c6943ccff268f4451e30142b70f 100644 (file)
@@ -1,4 +1,4 @@
-/* wcschr with SSSE3
+/* wcschr dispatch for RTLD and non-multiarch build
    Copyright (C) 2011-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-
 #define WCSCHR __wcschr
-#include "multiarch/wcschr-sse2.S"
-libc_hidden_def(__wcschr)
+
+#define DEFAULT_IMPL_V1        "multiarch/wcschr-sse2.S"
+#define DEFAULT_IMPL_V3        "multiarch/wcschr-avx2.S"
+#define DEFAULT_IMPL_V4        "multiarch/wcschr-evex.S"
+
+#include "isa-default-impl.h"
+
+libc_hidden_def (__wcschr)
 weak_alias (__wcschr, wcschr)
 libc_hidden_weak (wcschr)
index e04cdbf5fed165a41da8b917d4ee1b34eb58139a..5d30545fb6751906625819f9b566fc88b7442e58 100644 (file)
@@ -1,4 +1,4 @@
-/* Optimized wcscmp for x86-64 with SSE2.
+/* strlen dispatch for RTLD and non-multiarch build
    Copyright (C) 2011-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
 
 /* Symbol = __wcscmp.  */
 
-#include "multiarch/wcscmp-sse2.S"
+#define DEFAULT_IMPL_V1        "multiarch/wcscmp-sse2.S"
+#define DEFAULT_IMPL_V3        "multiarch/wcscmp-avx2.S"
+#define DEFAULT_IMPL_V4        "multiarch/wcscmp-evex.S"
+
+#include "isa-default-impl.h"
+
 libc_hidden_def (__wcscmp)
 weak_alias (__wcscmp, wcscmp)
index 588a0fbe0184b9c3b433f34b8692170b8ff414db..e4e25b5353730ec05184cb841263f3a6eb1ad61d 100644 (file)
@@ -1,4 +1,4 @@
-/* Optimized wcslen for x86-64 with SSE2.
+/* wcslen dispatch for RTLD and non-multiarch build
    Copyright (C) 2011-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    <https://www.gnu.org/licenses/>.  */
 
 #define WCSLEN __wcslen
-#include "multiarch/wcslen-sse2.S"
-weak_alias(__wcslen, wcslen)
+
+#define DEFAULT_IMPL_V1        "multiarch/wcslen-sse2.S"
+#define DEFAULT_IMPL_V2        "multiarch/wcslen-sse4_1.S"
+#define DEFAULT_IMPL_V3        "multiarch/wcslen-avx2.S"
+#define DEFAULT_IMPL_V4        "multiarch/wcslen-evex.S"
+
+#include "isa-default-impl.h"
+
+weak_alias (__wcslen, wcslen)
+
+#if MINIMUM_X86_ISA_LEVEL == 2 && !IS_IN (rtld)
+/* Hidden def so it can be used as overflow fallback in
+   wcsnlen-sse4_1.S.  */
+libc_hidden_def (__wcslen)
+#endif
diff --git a/sysdeps/x86_64/wcsncmp-generic.c b/sysdeps/x86_64/wcsncmp-generic.c
new file mode 100644 (file)
index 0000000..493a6f9
--- /dev/null
@@ -0,0 +1,29 @@
+/* wcsncmp dispatch for RTLD and non-multiarch .c ISA level 1 build.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* wcsncmp non-multiarch build is split into two files,
+   wcsncmp-generic.c and wcsncmp.S. The wcsncmp-generic.c build is for
+   ISA level <= 1 and just uses wcsmbs/wcsncmp.c.  This must be split
+   into two files because we cannot include C code from assembly or
+   vice versa.  */
+
+#include <isa-level.h>
+
+#if MINIMUM_X86_ISA_LEVEL <= 2
+# include "wcsmbs/wcsncmp.c"
+#endif
diff --git a/sysdeps/x86_64/wcsncmp.S b/sysdeps/x86_64/wcsncmp.S
new file mode 100644 (file)
index 0000000..14f9a13
--- /dev/null
@@ -0,0 +1,40 @@
+/* wcsncmp dispatch for RTLD and non-multiarch .c files
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* wcsncmp non-multiarch build is split into two files,
+   wcsncmp-generic.c and wcsncmp.S. The wcsncmp.S build is for
+   ISA level >= 3 uses the optimized assembly implementations in
+   multiarch/wcsncmp*.S.  This must be split into two files because
+   we cannot include C code from assembly or vice versa.  */
+
+#include <isa-level.h>
+
+#if MINIMUM_X86_ISA_LEVEL >= 3
+
+/* Symbol = wcsncmp.  */
+
+# define DEFAULT_IMPL_V3       "multiarch/wcsncmp-avx2.S"
+# define DEFAULT_IMPL_V4       "multiarch/wcsncmp-evex.S"
+
+/* isa-default-impl.h expects DEFAULT_IMPL_V1 to be defined but it
+   should never be used from here.  */
+# define DEFAULT_IMPL_V1       "ERROR -- Invalid ISA IMPL"
+
+# include "isa-default-impl.h"
+
+#endif
diff --git a/sysdeps/x86_64/wcsnlen-generic.c b/sysdeps/x86_64/wcsnlen-generic.c
new file mode 100644 (file)
index 0000000..ec66511
--- /dev/null
@@ -0,0 +1,29 @@
+/* wcsnlen dispatch for RTLD and non-multiarch .c ISA level 1 build.
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* wcsnlen non-multiarch build is split into two files,
+   wcsnlen-generic.c and wcsnlen.S. The wcsnlen-generic.c build is for
+   ISA level <= 1 and just uses wcsmbs/wcsnlen.c.  This must be split
+   into two files because we cannot include C code from assembly or
+   vice versa.  */
+
+#include <isa-level.h>
+
+#if MINIMUM_X86_ISA_LEVEL <= 1
+# include "wcsmbs/wcsnlen.c"
+#endif
diff --git a/sysdeps/x86_64/wcsnlen.S b/sysdeps/x86_64/wcsnlen.S
new file mode 100644 (file)
index 0000000..b30b3f0
--- /dev/null
@@ -0,0 +1,49 @@
+/* wcsnlen dispatch for RTLD and non-multiarch .c files
+   Copyright (C) 2022 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* wcsnlen non-multiarch build is split into two files,
+   wcsnlen-generic.c and wcsnlen.S. The wcsnlen.S build is for
+   ISA level >= 2 uses the optimized assembly implementations in
+   multiarch/wcsnlen*.S.  This must be split into two files because
+   we cannot include C code from assembly or vice versa.  */
+
+#include <isa-level.h>
+
+#if MINIMUM_X86_ISA_LEVEL >= 2
+
+# define WCSNLEN       __wcsnlen
+/* This symbol must stay linked to the name in wcslen.S.  */
+#if IS_IN (rtld)
+# define OVERFLOW_STRLEN       __wcslen
+#else
+# define OVERFLOW_STRLEN       HIDDEN_JUMPTARGET (__wcslen)
+#endif
+
+# define DEFAULT_IMPL_V2       "multiarch/wcsnlen-sse4_1.S"
+# define DEFAULT_IMPL_V3       "multiarch/wcsnlen-avx2.S"
+# define DEFAULT_IMPL_V4       "multiarch/wcsnlen-evex.S"
+
+/* isa-default-impl.h expects DEFAULT_IMPL_V1 to be defined but it
+   should never be used from here.  */
+# define DEFAULT_IMPL_V1       "ERROR -- Invalid ISA IMPL"
+
+# include "isa-default-impl.h"
+
+weak_alias (__wcsnlen, wcsnlen)
+libc_hidden_def (__wcsnlen)
+#endif
index 1d4b1eb21c48e68ebd1cb5a694409a10cc302a1c..abf828b458a0bdf27b7551264fe60bccdc60d67c 100644 (file)
@@ -1,4 +1,4 @@
-/* wcsrchr optimized with SSE2.
+/* wcsrchr dispatch for RTLD and non-multiarch build
    Copyright (C) 2011-2022 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    License along with the GNU C Library; if not, see
    <https://www.gnu.org/licenses/>.  */
 
-#define STRRCHR        wcsrchr
-#include "multiarch/wcsrchr-sse2.S"
+#define WCSRCHR        wcsrchr
+
+#define DEFAULT_IMPL_V1        "multiarch/wcsrchr-sse2.S"
+#define DEFAULT_IMPL_V3        "multiarch/wcsrchr-avx2.S"
+#define DEFAULT_IMPL_V4        "multiarch/wcsrchr-evex.S"
+
+#include "isa-default-impl.h"