summary refs log tree commit diff
path: root/sysdeps/x86_64/multiarch
diff options
context:
space:
mode:
authorNoah Goldstein <goldstein.w.n@gmail.com>2022-07-13 16:33:00 -0700
committerNoah Goldstein <goldstein.w.n@gmail.com>2022-07-16 03:07:59 -0700
commit192979ee351315b84ff4277d0985f26243717cd7 (patch)
treea62f2737cc82add1047d89ef9e89984849a6de8d /sysdeps/x86_64/multiarch
parentceabdcd130ca7043b0fcf2676183d79431d10493 (diff)
downloadglibc-192979ee351315b84ff4277d0985f26243717cd7.tar.gz
glibc-192979ee351315b84ff4277d0985f26243717cd7.tar.xz
glibc-192979ee351315b84ff4277d0985f26243717cd7.zip
x86: Add support to build wcscpy with explicit ISA level
1. Add ISA level build guards to different implementations.
    - wcscpy-ssse3.S is used as ISA level 2/3/4.
    - wcscpy-generic.c is only used at ISA level 1 and will
      only build if compiled with ISA level == 1. Otherwise
      there is no reason to include it as we will always use
      wcscpy-ssse3.S

2. 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.
Diffstat (limited to 'sysdeps/x86_64/multiarch')
-rw-r--r--sysdeps/x86_64/multiarch/Makefile1
-rw-r--r--sysdeps/x86_64/multiarch/ifunc-impl-list.c12
-rw-r--r--sysdeps/x86_64/multiarch/wcscpy-generic.c9
-rw-r--r--sysdeps/x86_64/multiarch/wcscpy-ssse3.S16
-rw-r--r--sysdeps/x86_64/multiarch/wcscpy.c5
5 files changed, 31 insertions, 12 deletions
diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile
index ba29a65716..df4601c294 100644
--- a/sysdeps/x86_64/multiarch/Makefile
+++ b/sysdeps/x86_64/multiarch/Makefile
@@ -134,7 +134,6 @@ sysdep_routines += \
   wcscmp-avx2-rtm \
   wcscmp-evex \
   wcscmp-sse2 \
-  wcscpy-generic \
   wcscpy-ssse3 \
   wcslen-avx2 \
   wcslen-avx2-rtm \
diff --git a/sysdeps/x86_64/multiarch/ifunc-impl-list.c b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
index 3b1df9b73c..9318e98cc8 100644
--- a/sysdeps/x86_64/multiarch/ifunc-impl-list.c
+++ b/sysdeps/x86_64/multiarch/ifunc-impl-list.c
@@ -791,9 +791,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   /* Support sysdeps/x86_64/multiarch/wcscpy.c.  */
   IFUNC_IMPL (i, name, wcscpy,
-	      IFUNC_IMPL_ADD (array, i, wcscpy, CPU_FEATURE_USABLE (SSSE3),
-			      __wcscpy_ssse3)
-	      IFUNC_IMPL_ADD (array, i, wcscpy, 1, __wcscpy_generic))
+	      /* ISA V4 wrapper for SSSE3 implementation because
+	         the SSSE3 implementation is also used at ISA
+	         level 3/4.  */
+	      X86_IFUNC_IMPL_ADD_V4 (array, i, wcscpy,
+				     CPU_FEATURE_USABLE (SSSE3),
+				     __wcscpy_ssse3)
+	      X86_IFUNC_IMPL_ADD_V1 (array, i, wcscpy,
+				     1,
+				     __wcscpy_generic))
 
   /* Support sysdeps/x86_64/multiarch/wcslen.c.  */
   IFUNC_IMPL (i, name, wcslen,
diff --git a/sysdeps/x86_64/multiarch/wcscpy-generic.c b/sysdeps/x86_64/multiarch/wcscpy-generic.c
index 5ea905f33f..93d314aaad 100644
--- a/sysdeps/x86_64/multiarch/wcscpy-generic.c
+++ b/sysdeps/x86_64/multiarch/wcscpy-generic.c
@@ -17,8 +17,11 @@
    <https://www.gnu.org/licenses/>.  */
 
 
-#if IS_IN (libc)
+#include <isa-level.h>
+
+#if ISA_SHOULD_BUILD (1)
+
 # define WCSCPY  __wcscpy_generic
-#endif
+# include <wcsmbs/wcscpy.c>
 
-#include <wcsmbs/wcscpy.c>
+#endif
diff --git a/sysdeps/x86_64/multiarch/wcscpy-ssse3.S b/sysdeps/x86_64/multiarch/wcscpy-ssse3.S
index aa2b9d030f..62741071e6 100644
--- a/sysdeps/x86_64/multiarch/wcscpy-ssse3.S
+++ b/sysdeps/x86_64/multiarch/wcscpy-ssse3.S
@@ -16,11 +16,21 @@
    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 <= 4 because there are not V3/V4
+   implementations so we need this to build for ISA V3/V4
+    builds. */
+#if ISA_SHOULD_BUILD (4)
+
+# ifndef WCSCPY
+#  define WCSCPY	__wcscpy_ssse3
+# endif
+
 # include <sysdep.h>
 
 	.section .text.ssse3,"ax",@progbits
-ENTRY (__wcscpy_ssse3)
+ENTRY (WCSCPY)
 
 	mov	%rsi, %rcx
 	mov	%rdi, %rdx
@@ -547,5 +557,5 @@ L(Exit16):
 	mov	%rdi, %rax
 	ret
 
-END(__wcscpy_ssse3)
+END(WCSCPY)
 #endif
diff --git a/sysdeps/x86_64/multiarch/wcscpy.c b/sysdeps/x86_64/multiarch/wcscpy.c
index 53c3228dc2..92c917b6b4 100644
--- a/sysdeps/x86_64/multiarch/wcscpy.c
+++ b/sysdeps/x86_64/multiarch/wcscpy.c
@@ -26,15 +26,16 @@
 # define SYMBOL_NAME wcscpy
 # include <init-arch.h>
 
-extern __typeof (REDIRECT_NAME) OPTIMIZE (generic) attribute_hidden;
 extern __typeof (REDIRECT_NAME) OPTIMIZE (ssse3) attribute_hidden;
 
+extern __typeof (REDIRECT_NAME) OPTIMIZE (generic) attribute_hidden;
+
 static inline void *
 IFUNC_SELECTOR (void)
 {
   const struct cpu_features* cpu_features = __get_cpu_features ();
 
-  if (CPU_FEATURE_USABLE_P (cpu_features, SSSE3))
+  if (X86_ISA_CPU_FEATURE_USABLE_P (cpu_features, SSSE3))
     return OPTIMIZE (ssse3);
 
   return OPTIMIZE (generic);