bdc76f
commit 18eb862d454a41012ccdd5127715ef7cd2a711ec
bdc76f
Author: Stefan Liebler <stli@linux.ibm.com>
bdc76f
Date:   Tue Dec 18 13:57:06 2018 +0100
bdc76f
bdc76f
    S390: Refactor memcpy/mempcpy ifunc handling.
bdc76f
    
bdc76f
    This patch moves all ifunc variants for memcpy/mempcpy
bdc76f
    to sysdeps/s390/memcpy-z900.S. The configure-check/preprocessor logic
bdc76f
    in sysdeps/s390/ifunc-memcpy.h decides if ifunc is needed at all
bdc76f
    and which ifunc variants should be available.
bdc76f
    E.g. if the compiler/assembler already supports z196 by default,
bdc76f
    the older ifunc variants are not included.
bdc76f
    If we only need the newest ifunc variant,
bdc76f
    then we can skip ifunc at all.
bdc76f
    
bdc76f
    Therefore the ifunc-resolvers and __libc_ifunc_impl_list are adjusted
bdc76f
    in order to handle only the available ifunc variants.
bdc76f
    
bdc76f
    ChangeLog:
bdc76f
    
bdc76f
            * sysdeps/s390/ifunc-memcpy.h: New File.
bdc76f
            * sysdeps/s390/memcpy.S: Move to ...
bdc76f
            * sysdeps/s390/memcpy-z900.S ... here.
bdc76f
            Move implementations from memcpy-s390x.s to here.
bdc76f
            * sysdeps/s390/multiarch/memcpy-s390x.S: Delete File.
bdc76f
            * sysdeps/s390/multiarch/Makefile (sysdep_routines):
bdc76f
            Remove memcpy/mempcpy variants.
bdc76f
            * sysdeps/s390/Makefile (sysdep_routines):
bdc76f
            Add memcpy/mempcpy variants.
bdc76f
            * sysdeps/s390/multiarch/ifunc-impl-list.c
bdc76f
            (__libc_ifunc_impl_list): Adjust ifunc variants for
bdc76f
            memcpy and mempcpy.
bdc76f
            * sysdeps/s390/multiarch/memcpy.c: Move ifunc resolver
bdc76f
            to ...
bdc76f
            * sysdeps/s390/memcpy.c: ... here.
bdc76f
            Adjust ifunc variants for memcpy.
bdc76f
            * sysdeps/s390/multiarch/mempcpy.c: Move to ...
bdc76f
            * sysdeps/s390/mempcpy.c: ... here.
bdc76f
            Adjust ifunc variants for mempcpy.
bdc76f
            * sysdeps/s390/mempcpy.S: Delete file.
bdc76f
bdc76f
diff --git a/sysdeps/s390/Makefile b/sysdeps/s390/Makefile
bdc76f
index c59cbdc25aad408a..838950a5ab958e31 100644
bdc76f
--- a/sysdeps/s390/Makefile
bdc76f
+++ b/sysdeps/s390/Makefile
bdc76f
@@ -32,5 +32,6 @@ endif
bdc76f
 
bdc76f
 ifeq ($(subdir),string)
bdc76f
 sysdep_routines += bzero memset memset-z900 \
bdc76f
-		   memcmp memcmp-z900
bdc76f
+		   memcmp memcmp-z900 \
bdc76f
+		   mempcpy memcpy memcpy-z900
bdc76f
 endif
bdc76f
diff --git a/sysdeps/s390/ifunc-memcpy.h b/sysdeps/s390/ifunc-memcpy.h
bdc76f
new file mode 100644
bdc76f
index 0000000000000000..51c71baa2c0b0452
bdc76f
--- /dev/null
bdc76f
+++ b/sysdeps/s390/ifunc-memcpy.h
bdc76f
@@ -0,0 +1,68 @@
bdc76f
+/* memcpy variant information on S/390 version.
bdc76f
+   Copyright (C) 2018 Free Software Foundation, Inc.
bdc76f
+   This file is part of the GNU C Library.
bdc76f
+
bdc76f
+   The GNU C Library is free software; you can redistribute it and/or
bdc76f
+   modify it under the terms of the GNU Lesser General Public
bdc76f
+   License as published by the Free Software Foundation; either
bdc76f
+   version 2.1 of the License, or (at your option) any later version.
bdc76f
+
bdc76f
+   The GNU C Library is distributed in the hope that it will be useful,
bdc76f
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
bdc76f
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
bdc76f
+   Lesser General Public License for more details.
bdc76f
+
bdc76f
+   You should have received a copy of the GNU Lesser General Public
bdc76f
+   License along with the GNU C Library; if not, see
bdc76f
+   <http://www.gnu.org/licenses/>.  */
bdc76f
+
bdc76f
+#if defined SHARED && defined USE_MULTIARCH && IS_IN (libc)	\
bdc76f
+  && ! defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
bdc76f
+# define HAVE_MEMCPY_IFUNC	1
bdc76f
+#else
bdc76f
+# define HAVE_MEMCPY_IFUNC	0
bdc76f
+#endif
bdc76f
+
bdc76f
+#if defined HAVE_S390_MIN_Z196_ZARCH_ASM_SUPPORT
bdc76f
+# define MEMCPY_DEFAULT		MEMCPY_Z196
bdc76f
+# define MEMPCPY_DEFAULT	MEMPCPY_Z196
bdc76f
+# define HAVE_MEMCPY_Z900_G5	0
bdc76f
+# define HAVE_MEMCPY_Z10	0
bdc76f
+# define HAVE_MEMCPY_Z196	1
bdc76f
+#elif defined HAVE_S390_MIN_Z10_ZARCH_ASM_SUPPORT
bdc76f
+# define MEMCPY_DEFAULT		MEMCPY_Z10
bdc76f
+# define MEMPCPY_DEFAULT	MEMPCPY_Z10
bdc76f
+# define HAVE_MEMCPY_Z900_G5	0
bdc76f
+# define HAVE_MEMCPY_Z10	1
bdc76f
+# define HAVE_MEMCPY_Z196	HAVE_MEMCPY_IFUNC
bdc76f
+#else
bdc76f
+# define MEMCPY_DEFAULT		MEMCPY_Z900_G5
bdc76f
+# define MEMPCPY_DEFAULT	MEMPCPY_Z900_G5
bdc76f
+# define HAVE_MEMCPY_Z900_G5	1
bdc76f
+# define HAVE_MEMCPY_Z10	HAVE_MEMCPY_IFUNC
bdc76f
+# define HAVE_MEMCPY_Z196	HAVE_MEMCPY_IFUNC
bdc76f
+#endif
bdc76f
+
bdc76f
+#if HAVE_MEMCPY_Z900_G5
bdc76f
+# define MEMCPY_Z900_G5		__memcpy_default
bdc76f
+# define MEMPCPY_Z900_G5	__mempcpy_default
bdc76f
+#else
bdc76f
+# define MEMCPY_Z900_G5		NULL
bdc76f
+# define MEMPCPY_Z900_G5	NULL
bdc76f
+#endif
bdc76f
+
bdc76f
+#if HAVE_MEMCPY_Z10
bdc76f
+# define MEMCPY_Z10		__memcpy_z10
bdc76f
+# define MEMPCPY_Z10		__mempcpy_z10
bdc76f
+#else
bdc76f
+# define MEMCPY_Z10		NULL
bdc76f
+# define MEMPCPY_Z10		NULL
bdc76f
+#endif
bdc76f
+
bdc76f
+#if HAVE_MEMCPY_Z196
bdc76f
+# define MEMCPY_Z196		__memcpy_z196
bdc76f
+# define MEMPCPY_Z196		__mempcpy_z196
bdc76f
+#else
bdc76f
+# define MEMCPY_Z196		NULL
bdc76f
+# define MEMPCPY_Z196		NULL
bdc76f
+#endif
bdc76f
diff --git a/sysdeps/s390/memcpy.S b/sysdeps/s390/memcpy-z900.S
bdc76f
similarity index 50%
bdc76f
rename from sysdeps/s390/memcpy.S
bdc76f
rename to sysdeps/s390/memcpy-z900.S
bdc76f
index 2a6c6b750377c7bb..3a50cf44d85d2417 100644
bdc76f
--- a/sysdeps/s390/memcpy.S
bdc76f
+++ b/sysdeps/s390/memcpy-z900.S
bdc76f
@@ -19,6 +19,7 @@
bdc76f
 
bdc76f
 #include <sysdep.h>
bdc76f
 #include "asm-syntax.h"
bdc76f
+#include <ifunc-memcpy.h>
bdc76f
 
bdc76f
 /* INPUT PARAMETERS
bdc76f
      %r2 = address of destination memory area
bdc76f
@@ -41,50 +42,46 @@
bdc76f
 # define BRCTG	brct
bdc76f
 #endif /* ! defined __s390x__  */
bdc76f
 
bdc76f
-ENTRY(__mempcpy)
bdc76f
-#if defined __s390x__
bdc76f
+#if HAVE_MEMCPY_Z900_G5
bdc76f
+ENTRY(MEMPCPY_Z900_G5)
bdc76f
+# if defined __s390x__
bdc76f
 	.machine "z900"
bdc76f
-#else
bdc76f
+# else
bdc76f
 	.machine "g5"
bdc76f
-#endif /* ! defined __s390x__  */
bdc76f
+# endif /* ! defined __s390x__  */
bdc76f
 	LGR     %r1,%r2             # Use as dest
bdc76f
 	la      %r2,0(%r4,%r2)      # Return dest + n
bdc76f
 	j	.L_Z900_G5_start
bdc76f
-END(__mempcpy)
bdc76f
-#ifndef USE_MULTIARCH
bdc76f
-libc_hidden_def (__mempcpy)
bdc76f
-weak_alias (__mempcpy, mempcpy)
bdc76f
-libc_hidden_builtin_def (mempcpy)
bdc76f
-#endif
bdc76f
+END(MEMPCPY_Z900_G5)
bdc76f
 
bdc76f
-ENTRY(memcpy)
bdc76f
-#if defined __s390x__
bdc76f
+ENTRY(MEMCPY_Z900_G5)
bdc76f
+# if defined __s390x__
bdc76f
 	.machine "z900"
bdc76f
-#else
bdc76f
+# else
bdc76f
 	.machine "g5"
bdc76f
-#endif /* ! defined __s390x__  */
bdc76f
+# endif /* ! defined __s390x__  */
bdc76f
 	LGR     %r1,%r2             # r1: Use as dest ; r2: Return dest
bdc76f
 .L_Z900_G5_start:
bdc76f
 	LTGR    %r4,%r4
bdc76f
 	je      .L_Z900_G5_4
bdc76f
 	AGHI    %r4,-1
bdc76f
-#if defined __s390x__
bdc76f
+# if defined __s390x__
bdc76f
 	srlg	%r5,%r4,8
bdc76f
-#else
bdc76f
+# else
bdc76f
 	lr	%r5,%r4
bdc76f
 	srl	%r5,8
bdc76f
-#endif /* ! defined __s390x__  */
bdc76f
+# endif /* ! defined __s390x__  */
bdc76f
 	LTGR    %r5,%r5
bdc76f
 	jne     .L_Z900_G5_13
bdc76f
 .L_Z900_G5_3:
bdc76f
-#if defined __s390x__
bdc76f
+# if defined __s390x__
bdc76f
 	larl    %r5,.L_Z900_G5_15
bdc76f
-# define Z900_G5_EX_D 0
bdc76f
-#else
bdc76f
+#  define Z900_G5_EX_D 0
bdc76f
+# else
bdc76f
 	basr    %r5,0
bdc76f
 .L_Z900_G5_14:
bdc76f
-# define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_14
bdc76f
-#endif /* ! defined __s390x__  */
bdc76f
+#  define Z900_G5_EX_D .L_Z900_G5_15-.L_Z900_G5_14
bdc76f
+# endif /* ! defined __s390x__  */
bdc76f
 	ex      %r4,Z900_G5_EX_D(%r5)
bdc76f
 .L_Z900_G5_4:
bdc76f
 	br      %r14
bdc76f
@@ -99,10 +96,8 @@ ENTRY(memcpy)
bdc76f
 	j       .L_Z900_G5_3
bdc76f
 .L_Z900_G5_15:
bdc76f
 	mvc     0(1,%r1),0(%r3)
bdc76f
-END(memcpy)
bdc76f
-#ifndef USE_MULTIARCH
bdc76f
-libc_hidden_builtin_def (memcpy)
bdc76f
-#endif
bdc76f
+END(MEMCPY_Z900_G5)
bdc76f
+#endif /* HAVE_MEMCPY_Z900_G5  */
bdc76f
 
bdc76f
 ENTRY(__memcpy_mvcle)
bdc76f
 	# Using as standalone function will result in unexpected
bdc76f
@@ -126,3 +121,104 @@ END(__memcpy_mvcle)
bdc76f
 #undef LGR
bdc76f
 #undef AGHI
bdc76f
 #undef BRCTG
bdc76f
+
bdc76f
+#if HAVE_MEMCPY_Z10
bdc76f
+ENTRY(MEMPCPY_Z10)
bdc76f
+	.machine "z10"
bdc76f
+	.machinemode "zarch_nohighgprs"
bdc76f
+	lgr     %r1,%r2         # Use as dest
bdc76f
+	la      %r2,0(%r4,%r2)  # Return dest + n
bdc76f
+	j	.L_Z10_start
bdc76f
+END(MEMPCPY_Z10)
bdc76f
+
bdc76f
+ENTRY(MEMCPY_Z10)
bdc76f
+	.machine "z10"
bdc76f
+	.machinemode "zarch_nohighgprs"
bdc76f
+	lgr     %r1,%r2         # r1: Use as dest ; r2: Return dest
bdc76f
+.L_Z10_start:
bdc76f
+# if !defined __s390x__
bdc76f
+	llgfr	%r4,%r4
bdc76f
+# endif /* !defined __s390x__  */
bdc76f
+	cgije   %r4,0,.L_Z10_4
bdc76f
+	aghi    %r4,-1
bdc76f
+	srlg    %r5,%r4,8
bdc76f
+	cgijlh  %r5,0,.L_Z10_13
bdc76f
+.L_Z10_3:
bdc76f
+	exrl    %r4,.L_Z10_15
bdc76f
+.L_Z10_4:
bdc76f
+	br      %r14
bdc76f
+.L_Z10_13:
bdc76f
+	cgfi    %r5,65535	# Switch to mvcle for copies >16MB
bdc76f
+	jh      __memcpy_mvcle
bdc76f
+.L_Z10_12:
bdc76f
+	pfd     1,768(%r3)
bdc76f
+	pfd     2,768(%r1)
bdc76f
+	mvc     0(256,%r1),0(%r3)
bdc76f
+	la      %r1,256(%r1)
bdc76f
+	la      %r3,256(%r3)
bdc76f
+	brctg   %r5,.L_Z10_12
bdc76f
+	j       .L_Z10_3
bdc76f
+.L_Z10_15:
bdc76f
+	mvc     0(1,%r1),0(%r3)
bdc76f
+END(MEMCPY_Z10)
bdc76f
+#endif /* HAVE_MEMCPY_Z10  */
bdc76f
+
bdc76f
+#if HAVE_MEMCPY_Z196
bdc76f
+ENTRY(MEMPCPY_Z196)
bdc76f
+	.machine "z196"
bdc76f
+	.machinemode "zarch_nohighgprs"
bdc76f
+	lgr     %r1,%r2         # Use as dest
bdc76f
+	la      %r2,0(%r4,%r2)  # Return dest + n
bdc76f
+	j	.L_Z196_start
bdc76f
+END(MEMPCPY_Z196)
bdc76f
+
bdc76f
+ENTRY(MEMCPY_Z196)
bdc76f
+	.machine "z196"
bdc76f
+	.machinemode "zarch_nohighgprs"
bdc76f
+	lgr     %r1,%r2         # r1: Use as dest ; r2: Return dest
bdc76f
+.L_Z196_start:
bdc76f
+# if !defined __s390x__
bdc76f
+	llgfr	%r4,%r4
bdc76f
+# endif /* !defined __s390x__  */
bdc76f
+	ltgr    %r4,%r4
bdc76f
+	je      .L_Z196_4
bdc76f
+	aghi    %r4,-1
bdc76f
+	srlg    %r5,%r4,8
bdc76f
+	ltgr    %r5,%r5
bdc76f
+	jne     .L_Z196_5
bdc76f
+.L_Z196_3:
bdc76f
+	exrl    %r4,.L_Z196_14
bdc76f
+.L_Z196_4:
bdc76f
+	br      %r14
bdc76f
+.L_Z196_5:
bdc76f
+	cgfi    %r5,262144      # Switch to mvcle for copies >64MB
bdc76f
+	jh      __memcpy_mvcle
bdc76f
+.L_Z196_2:
bdc76f
+	pfd     1,768(%r3)
bdc76f
+	pfd     2,768(%r1)
bdc76f
+	mvc     0(256,%r1),0(%r3)
bdc76f
+	aghi    %r5,-1
bdc76f
+	la      %r1,256(%r1)
bdc76f
+	la      %r3,256(%r3)
bdc76f
+	jne     .L_Z196_2
bdc76f
+	j       .L_Z196_3
bdc76f
+.L_Z196_14:
bdc76f
+	mvc     0(1,%r1),0(%r3)
bdc76f
+END(MEMCPY_Z196)
bdc76f
+#endif /* HAVE_MEMCPY_Z196  */
bdc76f
+
bdc76f
+#if ! HAVE_MEMCPY_IFUNC
bdc76f
+/* If we don't use ifunc, define an alias for mem[p]cpy here.
bdc76f
+   Otherwise see sysdeps/s390/mem[p]cpy.c.  */
bdc76f
+strong_alias (MEMCPY_DEFAULT, memcpy)
bdc76f
+strong_alias (MEMPCPY_DEFAULT, __mempcpy)
bdc76f
+weak_alias (__mempcpy, mempcpy)
bdc76f
+#endif
bdc76f
+
bdc76f
+#if defined SHARED && IS_IN (libc)
bdc76f
+/* Defines the internal symbols.
bdc76f
+   Compare to libc_hidden_[builtin_]def (mem[p]cpy) in string/mem[p]cpy.c.  */
bdc76f
+strong_alias (MEMCPY_DEFAULT, __GI_memcpy)
bdc76f
+strong_alias (MEMPCPY_DEFAULT, __GI_mempcpy)
bdc76f
+strong_alias (MEMPCPY_DEFAULT, __GI___mempcpy)
bdc76f
+#endif
bdc76f
diff --git a/sysdeps/s390/multiarch/memcpy.c b/sysdeps/s390/memcpy.c
bdc76f
similarity index 60%
bdc76f
rename from sysdeps/s390/multiarch/memcpy.c
bdc76f
rename to sysdeps/s390/memcpy.c
bdc76f
index c9577a854a0c7e68..90a53ac27d4be755 100644
bdc76f
--- a/sysdeps/s390/multiarch/memcpy.c
bdc76f
+++ b/sysdeps/s390/memcpy.c
bdc76f
@@ -16,12 +16,34 @@
bdc76f
    License along with the GNU C Library; if not, see
bdc76f
    <http://www.gnu.org/licenses/>.  */
bdc76f
 
bdc76f
-/* In the static lib memcpy is needed before the reloc is resolved.  */
bdc76f
-#if defined SHARED && IS_IN (libc)
bdc76f
+#include <ifunc-memcpy.h>
bdc76f
+
bdc76f
+#if HAVE_MEMCPY_IFUNC
bdc76f
 # define memcpy __redirect_memcpy
bdc76f
 # include <string.h>
bdc76f
 # undef memcpy
bdc76f
 # include <ifunc-resolve.h>
bdc76f
 
bdc76f
-s390_libc_ifunc (__redirect_memcpy, __memcpy, memcpy)
bdc76f
+# if HAVE_MEMCPY_Z900_G5
bdc76f
+extern __typeof (__redirect_memcpy) MEMCPY_Z900_G5 attribute_hidden;
bdc76f
+# endif
bdc76f
+
bdc76f
+# if HAVE_MEMCPY_Z10
bdc76f
+extern __typeof (__redirect_memcpy) MEMCPY_Z10 attribute_hidden;
bdc76f
+# endif
bdc76f
+
bdc76f
+# if HAVE_MEMCPY_Z196
bdc76f
+extern __typeof (__redirect_memcpy) MEMCPY_Z196 attribute_hidden;
bdc76f
+# endif
bdc76f
+
bdc76f
+s390_libc_ifunc_expr (__redirect_memcpy, memcpy,
bdc76f
+		      ({
bdc76f
+			s390_libc_ifunc_init ();
bdc76f
+			(HAVE_MEMCPY_Z196 && S390_IS_Z196 (stfle_bits))
bdc76f
+			  ? MEMCPY_Z196
bdc76f
+			  : (HAVE_MEMCPY_Z10 && S390_IS_Z10 (stfle_bits))
bdc76f
+			  ? MEMCPY_Z10
bdc76f
+			  : MEMCPY_DEFAULT;
bdc76f
+		      })
bdc76f
+		      )
bdc76f
 #endif
bdc76f
diff --git a/sysdeps/s390/mempcpy.S b/sysdeps/s390/mempcpy.S
bdc76f
deleted file mode 100644
bdc76f
index 18ef29213e26e76d..0000000000000000
bdc76f
--- a/sysdeps/s390/mempcpy.S
bdc76f
+++ /dev/null
bdc76f
@@ -1,19 +0,0 @@
bdc76f
-/* CPU specific mempcpy without multiarch - 32/64 bit S/390 version.
bdc76f
-   Copyright (C) 2016-2018 Free Software Foundation, Inc.
bdc76f
-   This file is part of the GNU C Library.
bdc76f
-
bdc76f
-   The GNU C Library is free software; you can redistribute it and/or
bdc76f
-   modify it under the terms of the GNU Lesser General Public
bdc76f
-   License as published by the Free Software Foundation; either
bdc76f
-   version 2.1 of the License, or (at your option) any later version.
bdc76f
-
bdc76f
-   The GNU C Library is distributed in the hope that it will be useful,
bdc76f
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
bdc76f
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
bdc76f
-   Lesser General Public License for more details.
bdc76f
-
bdc76f
-   You should have received a copy of the GNU Lesser General Public
bdc76f
-   License along with the GNU C Library; if not, see
bdc76f
-   <http://www.gnu.org/licenses/>.  */
bdc76f
-
bdc76f
-/* mempcpy is implemented in memcpy.S.  */
bdc76f
diff --git a/sysdeps/s390/multiarch/mempcpy.c b/sysdeps/s390/mempcpy.c
bdc76f
similarity index 63%
bdc76f
rename from sysdeps/s390/multiarch/mempcpy.c
bdc76f
rename to sysdeps/s390/mempcpy.c
bdc76f
index 363fe47aefb80978..a6a237312659c2c1 100644
bdc76f
--- a/sysdeps/s390/multiarch/mempcpy.c
bdc76f
+++ b/sysdeps/s390/mempcpy.c
bdc76f
@@ -16,8 +16,9 @@
bdc76f
    License along with the GNU C Library; if not, see
bdc76f
    <http://www.gnu.org/licenses/>.  */
bdc76f
 
bdc76f
+#include <ifunc-memcpy.h>
bdc76f
 
bdc76f
-#if defined SHARED && IS_IN (libc)
bdc76f
+#if HAVE_MEMCPY_IFUNC
bdc76f
 # define mempcpy __redirect_mempcpy
bdc76f
 # define __mempcpy __redirect___mempcpy
bdc76f
 # define __NO_STRING_INLINES
bdc76f
@@ -27,6 +28,27 @@
bdc76f
 # undef __mempcpy
bdc76f
 # include <ifunc-resolve.h>
bdc76f
 
bdc76f
-s390_libc_ifunc (__redirect___mempcpy, ____mempcpy, __mempcpy)
bdc76f
+# if HAVE_MEMCPY_Z900_G5
bdc76f
+extern __typeof (__redirect___mempcpy) MEMPCPY_Z900_G5 attribute_hidden;
bdc76f
+# endif
bdc76f
+
bdc76f
+# if HAVE_MEMCPY_Z10
bdc76f
+extern __typeof (__redirect___mempcpy) MEMPCPY_Z10 attribute_hidden;
bdc76f
+# endif
bdc76f
+
bdc76f
+# if HAVE_MEMCPY_Z196
bdc76f
+extern __typeof (__redirect___mempcpy) MEMPCPY_Z196 attribute_hidden;
bdc76f
+# endif
bdc76f
+
bdc76f
+s390_libc_ifunc_expr (__redirect___mempcpy, __mempcpy,
bdc76f
+		      ({
bdc76f
+			s390_libc_ifunc_init ();
bdc76f
+			(HAVE_MEMCPY_Z196 && S390_IS_Z196 (stfle_bits))
bdc76f
+			  ? MEMPCPY_Z196
bdc76f
+			  : (HAVE_MEMCPY_Z10 && S390_IS_Z10 (stfle_bits))
bdc76f
+			  ? MEMPCPY_Z10
bdc76f
+			  : MEMPCPY_DEFAULT;
bdc76f
+		      })
bdc76f
+		      )
bdc76f
 weak_alias (__mempcpy, mempcpy);
bdc76f
 #endif
bdc76f
diff --git a/sysdeps/s390/multiarch/Makefile b/sysdeps/s390/multiarch/Makefile
bdc76f
index 3cbd5fad69e355a5..24949cd3a88b8015 100644
bdc76f
--- a/sysdeps/s390/multiarch/Makefile
bdc76f
+++ b/sysdeps/s390/multiarch/Makefile
bdc76f
@@ -18,8 +18,7 @@ sysdep_routines += strlen strlen-vx strlen-c \
bdc76f
 		   memchr memchr-vx \
bdc76f
 		   rawmemchr rawmemchr-vx rawmemchr-c \
bdc76f
 		   memccpy memccpy-vx memccpy-c \
bdc76f
-		   memrchr memrchr-vx memrchr-c \
bdc76f
-		   mempcpy memcpy memcpy-s390x
bdc76f
+		   memrchr memrchr-vx memrchr-c
bdc76f
 endif
bdc76f
 
bdc76f
 ifeq ($(subdir),wcsmbs)
bdc76f
diff --git a/sysdeps/s390/multiarch/ifunc-impl-list.c b/sysdeps/s390/multiarch/ifunc-impl-list.c
bdc76f
index 2e57d01abc21522e..6969c480cc40e0e2 100644
bdc76f
--- a/sysdeps/s390/multiarch/ifunc-impl-list.c
bdc76f
+++ b/sysdeps/s390/multiarch/ifunc-impl-list.c
bdc76f
@@ -23,6 +23,7 @@
bdc76f
 #include <ifunc-resolve.h>
bdc76f
 #include <ifunc-memset.h>
bdc76f
 #include <ifunc-memcmp.h>
bdc76f
+#include <ifunc-memcpy.h>
bdc76f
 
bdc76f
 /* Maximum number of IFUNC implementations.  */
bdc76f
 #define MAX_IFUNC	3
bdc76f
@@ -95,23 +96,35 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
bdc76f
 	      )
bdc76f
 #endif /* HAVE_MEMCMP_IFUNC */
bdc76f
 
bdc76f
-#ifdef SHARED
bdc76f
-
bdc76f
+#if HAVE_MEMCPY_IFUNC
bdc76f
   IFUNC_IMPL (i, name, memcpy,
bdc76f
+# if HAVE_MEMCPY_Z196
bdc76f
 	      IFUNC_IMPL_ADD (array, i, memcpy,
bdc76f
-			      S390_IS_Z196 (stfle_bits), __memcpy_z196)
bdc76f
+			      S390_IS_Z196 (stfle_bits), MEMCPY_Z196)
bdc76f
+# endif
bdc76f
+# if HAVE_MEMCPY_Z10
bdc76f
 	      IFUNC_IMPL_ADD (array, i, memcpy,
bdc76f
-			      S390_IS_Z10 (stfle_bits), __memcpy_z10)
bdc76f
-	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_default))
bdc76f
+			      S390_IS_Z10 (stfle_bits), MEMCPY_Z10)
bdc76f
+# endif
bdc76f
+# if HAVE_MEMCPY_Z900_G5
bdc76f
+	      IFUNC_IMPL_ADD (array, i, memcpy, 1, MEMCPY_Z900_G5)
bdc76f
+# endif
bdc76f
+	      )
bdc76f
 
bdc76f
   IFUNC_IMPL (i, name, mempcpy,
bdc76f
+# if HAVE_MEMCPY_Z196
bdc76f
 	      IFUNC_IMPL_ADD (array, i, mempcpy,
bdc76f
-			      S390_IS_Z196 (stfle_bits), ____mempcpy_z196)
bdc76f
+			      S390_IS_Z196 (stfle_bits), MEMPCPY_Z196)
bdc76f
+# endif
bdc76f
+# if HAVE_MEMCPY_Z10
bdc76f
 	      IFUNC_IMPL_ADD (array, i, mempcpy,
bdc76f
-			      S390_IS_Z10 (stfle_bits), ____mempcpy_z10)
bdc76f
-	      IFUNC_IMPL_ADD (array, i, mempcpy, 1, ____mempcpy_default))
bdc76f
-
bdc76f
-#endif /* SHARED */
bdc76f
+			      S390_IS_Z10 (stfle_bits), MEMPCPY_Z10)
bdc76f
+# endif
bdc76f
+# if HAVE_MEMCPY_Z900_G5
bdc76f
+	      IFUNC_IMPL_ADD (array, i, mempcpy, 1, MEMPCPY_Z900_G5)
bdc76f
+# endif
bdc76f
+	      )
bdc76f
+#endif /* HAVE_MEMCPY_IFUNC  */
bdc76f
 
bdc76f
 #ifdef HAVE_S390_VX_ASM_SUPPORT
bdc76f
 
bdc76f
diff --git a/sysdeps/s390/multiarch/memcpy-s390x.S b/sysdeps/s390/multiarch/memcpy-s390x.S
bdc76f
deleted file mode 100644
bdc76f
index b38caac72b8742e6..0000000000000000
bdc76f
--- a/sysdeps/s390/multiarch/memcpy-s390x.S
bdc76f
+++ /dev/null
bdc76f
@@ -1,132 +0,0 @@
bdc76f
-/* CPU specific memcpy implementations.  31/64 bit S/390 version.
bdc76f
-   Copyright (C) 2012-2018 Free Software Foundation, Inc.
bdc76f
-   This file is part of the GNU C Library.
bdc76f
-
bdc76f
-   The GNU C Library is free software; you can redistribute it and/or
bdc76f
-   modify it under the terms of the GNU Lesser General Public
bdc76f
-   License as published by the Free Software Foundation; either
bdc76f
-   version 2.1 of the License, or (at your option) any later version.
bdc76f
-
bdc76f
-   The GNU C Library is distributed in the hope that it will be useful,
bdc76f
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
bdc76f
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
bdc76f
-   Lesser General Public License for more details.
bdc76f
-
bdc76f
-   You should have received a copy of the GNU Lesser General Public
bdc76f
-   License along with the GNU C Library; if not, see
bdc76f
-   <http://www.gnu.org/licenses/>.  */
bdc76f
-
bdc76f
-
bdc76f
-#include "sysdep.h"
bdc76f
-#include "asm-syntax.h"
bdc76f
-
bdc76f
-/* INPUT PARAMETERS
bdc76f
-     %r2 = target operands address
bdc76f
-     %r3 = source operands address
bdc76f
-     %r4 = number of bytes to copy.  */
bdc76f
-
bdc76f
-       .text
bdc76f
-
bdc76f
-#if defined SHARED && IS_IN (libc)
bdc76f
-
bdc76f
-ENTRY(____mempcpy_z196)
bdc76f
-	.machine "z196"
bdc76f
-	.machinemode "zarch_nohighgprs"
bdc76f
-	lgr     %r1,%r2         # Use as dest
bdc76f
-	la      %r2,0(%r4,%r2)  # Return dest + n
bdc76f
-	j	.L_Z196_start
bdc76f
-END(____mempcpy_z196)
bdc76f
-
bdc76f
-ENTRY(__memcpy_z196)
bdc76f
-	.machine "z196"
bdc76f
-	.machinemode "zarch_nohighgprs"
bdc76f
-	lgr     %r1,%r2         # r1: Use as dest ; r2: Return dest
bdc76f
-.L_Z196_start:
bdc76f
-# if !defined __s390x__
bdc76f
-	llgfr	%r4,%r4
bdc76f
-# endif /* !defined __s390x__  */
bdc76f
-	ltgr    %r4,%r4
bdc76f
-	je      .L_Z196_4
bdc76f
-	aghi    %r4,-1
bdc76f
-	srlg    %r5,%r4,8
bdc76f
-	ltgr    %r5,%r5
bdc76f
-	jne     .L_Z196_5
bdc76f
-.L_Z196_3:
bdc76f
-	exrl    %r4,.L_Z196_14
bdc76f
-.L_Z196_4:
bdc76f
-	br      %r14
bdc76f
-.L_Z196_5:
bdc76f
-	cgfi    %r5,262144      # Switch to mvcle for copies >64MB
bdc76f
-	jh      __memcpy_mvcle
bdc76f
-.L_Z196_2:
bdc76f
-	pfd     1,768(%r3)
bdc76f
-	pfd     2,768(%r1)
bdc76f
-	mvc     0(256,%r1),0(%r3)
bdc76f
-	aghi    %r5,-1
bdc76f
-	la      %r1,256(%r1)
bdc76f
-	la      %r3,256(%r3)
bdc76f
-	jne     .L_Z196_2
bdc76f
-	j       .L_Z196_3
bdc76f
-.L_Z196_14:
bdc76f
-	mvc     0(1,%r1),0(%r3)
bdc76f
-END(__memcpy_z196)
bdc76f
-
bdc76f
-ENTRY(____mempcpy_z10)
bdc76f
-	.machine "z10"
bdc76f
-	.machinemode "zarch_nohighgprs"
bdc76f
-	lgr     %r1,%r2         # Use as dest
bdc76f
-	la      %r2,0(%r4,%r2)  # Return dest + n
bdc76f
-	j	.L_Z10_start
bdc76f
-END(____mempcpy_z10)
bdc76f
-
bdc76f
-ENTRY(__memcpy_z10)
bdc76f
-	.machine "z10"
bdc76f
-	.machinemode "zarch_nohighgprs"
bdc76f
-	lgr     %r1,%r2         # r1: Use as dest ; r2: Return dest
bdc76f
-.L_Z10_start:
bdc76f
-# if !defined __s390x__
bdc76f
-	llgfr	%r4,%r4
bdc76f
-# endif /* !defined __s390x__  */
bdc76f
-	cgije   %r4,0,.L_Z10_4
bdc76f
-	aghi    %r4,-1
bdc76f
-	srlg    %r5,%r4,8
bdc76f
-	cgijlh  %r5,0,.L_Z10_13
bdc76f
-.L_Z10_3:
bdc76f
-	exrl    %r4,.L_Z10_15
bdc76f
-.L_Z10_4:
bdc76f
-	br      %r14
bdc76f
-.L_Z10_13:
bdc76f
-	cgfi    %r5,65535	# Switch to mvcle for copies >16MB
bdc76f
-	jh      __memcpy_mvcle
bdc76f
-.L_Z10_12:
bdc76f
-	pfd     1,768(%r3)
bdc76f
-	pfd     2,768(%r1)
bdc76f
-	mvc     0(256,%r1),0(%r3)
bdc76f
-	la      %r1,256(%r1)
bdc76f
-	la      %r3,256(%r3)
bdc76f
-	brctg   %r5,.L_Z10_12
bdc76f
-	j       .L_Z10_3
bdc76f
-.L_Z10_15:
bdc76f
-	mvc     0(1,%r1),0(%r3)
bdc76f
-END(__memcpy_z10)
bdc76f
-
bdc76f
-# define __mempcpy ____mempcpy_default
bdc76f
-#endif /* SHARED && IS_IN (libc) */
bdc76f
-
bdc76f
-#define memcpy __memcpy_default
bdc76f
-#include "../memcpy.S"
bdc76f
-#undef memcpy
bdc76f
-
bdc76f
-#if defined SHARED && IS_IN (libc)
bdc76f
-.globl   __GI_memcpy
bdc76f
-.set     __GI_memcpy,__memcpy_default
bdc76f
-.globl   __GI_mempcpy
bdc76f
-.set     __GI_mempcpy,____mempcpy_default
bdc76f
-.globl   __GI___mempcpy
bdc76f
-.set     __GI___mempcpy,____mempcpy_default
bdc76f
-#else
bdc76f
-.globl   memcpy
bdc76f
-.set     memcpy,__memcpy_default
bdc76f
-.weak    mempcpy
bdc76f
-.set     mempcpy,__mempcpy
bdc76f
-#endif