about summary refs log tree commit diff
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-08-20 12:05:50 -0700
committerH.J. Lu <hjl.tools@gmail.com>2015-08-27 09:35:11 -0700
commit4fadad5ce5208d12fd65538ecbec1b97ae83b440 (patch)
tree78866f58140f82a6332733a99fc9ab17de32d904
parent377adacbaaa3974408b708a20912474e45cd383b (diff)
downloadglibc-4fadad5ce5208d12fd65538ecbec1b97ae83b440.tar.gz
glibc-4fadad5ce5208d12fd65538ecbec1b97ae83b440.tar.xz
glibc-4fadad5ce5208d12fd65538ecbec1b97ae83b440.zip
Add i386 strcpy family multiarch functions
-rw-r--r--sysdeps/i386/i586/multiarch/rtld-stpcpy.S19
-rw-r--r--sysdeps/i386/i586/multiarch/stpcpy-i386.S8
-rw-r--r--sysdeps/i386/i586/multiarch/stpcpy-i586.S7
-rw-r--r--sysdeps/i386/i586/multiarch/stpcpy.c1
-rw-r--r--sysdeps/i386/i586/multiarch/strcpy-i586.S7
-rw-r--r--sysdeps/i386/i586/multiarch/strcpy.c1
-rw-r--r--sysdeps/i386/i686/multiarch/Makefile5
-rw-r--r--sysdeps/i386/i686/multiarch/stpcpy.S9
-rw-r--r--sysdeps/i386/i686/multiarch/stpncpy.S8
-rw-r--r--sysdeps/i386/i686/multiarch/strcpy.S116
-rw-r--r--sysdeps/i386/i686/multiarch/strncpy-c.c8
-rw-r--r--sysdeps/i386/i686/multiarch/strncpy.S5
-rw-r--r--sysdeps/i386/multiarch/Makefile6
-rw-r--r--sysdeps/i386/multiarch/ifunc-impl-list.c22
-rw-r--r--sysdeps/i386/multiarch/rtld-stpcpy.S19
-rw-r--r--sysdeps/i386/multiarch/stpcpy-i386.S7
-rw-r--r--sysdeps/i386/multiarch/stpcpy-i586.S8
-rw-r--r--sysdeps/i386/multiarch/stpcpy-sse2.S (renamed from sysdeps/i386/i686/multiarch/stpcpy-sse2.S)0
-rw-r--r--sysdeps/i386/multiarch/stpcpy-ssse3.S (renamed from sysdeps/i386/i686/multiarch/stpcpy-ssse3.S)0
-rw-r--r--sysdeps/i386/multiarch/stpcpy.c59
-rw-r--r--sysdeps/i386/multiarch/stpncpy-i386.S12
-rw-r--r--sysdeps/i386/multiarch/stpncpy-sse2.S (renamed from sysdeps/i386/i686/multiarch/stpncpy-sse2.S)0
-rw-r--r--sysdeps/i386/multiarch/stpncpy-ssse3.S (renamed from sysdeps/i386/i686/multiarch/stpncpy-ssse3.S)0
-rw-r--r--sysdeps/i386/multiarch/stpncpy.c54
-rw-r--r--sysdeps/i386/multiarch/strcpy-i386.c11
-rw-r--r--sysdeps/i386/multiarch/strcpy-i586.S4
-rw-r--r--sysdeps/i386/multiarch/strcpy-sse2.S (renamed from sysdeps/i386/i686/multiarch/strcpy-sse2.S)0
-rw-r--r--sysdeps/i386/multiarch/strcpy-ssse3.S (renamed from sysdeps/i386/i686/multiarch/strcpy-ssse3.S)0
-rw-r--r--sysdeps/i386/multiarch/strcpy.c55
-rw-r--r--sysdeps/i386/multiarch/strncpy-i386.c12
-rw-r--r--sysdeps/i386/multiarch/strncpy-sse2.S (renamed from sysdeps/i386/i686/multiarch/strncpy-sse2.S)0
-rw-r--r--sysdeps/i386/multiarch/strncpy-ssse3.S (renamed from sysdeps/i386/i686/multiarch/strncpy-ssse3.S)0
-rw-r--r--sysdeps/i386/multiarch/strncpy.c52
33 files changed, 360 insertions, 155 deletions
diff --git a/sysdeps/i386/i586/multiarch/rtld-stpcpy.S b/sysdeps/i386/i586/multiarch/rtld-stpcpy.S
new file mode 100644
index 0000000000..dc0e337fcd
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/rtld-stpcpy.S
@@ -0,0 +1,19 @@
+/* stpcpy for ld.so
+   Copyright (C) 2015 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdeps/i386/i586/stpcpy.S>
diff --git a/sysdeps/i386/i586/multiarch/stpcpy-i386.S b/sysdeps/i386/i586/multiarch/stpcpy-i386.S
new file mode 100644
index 0000000000..80d8bea613
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/stpcpy-i386.S
@@ -0,0 +1,8 @@
+#define __stpcpy __stpcpy_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef libc_hidden_def
+#define libc_hidden_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/stpcpy.S>
diff --git a/sysdeps/i386/i586/multiarch/stpcpy-i586.S b/sysdeps/i386/i586/multiarch/stpcpy-i586.S
new file mode 100644
index 0000000000..ad942bf568
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/stpcpy-i586.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/stpcpy-i586.S>
+
+#ifdef SHARED
+	.globl __GI_stpcpy
+	.hidden __GI_stpcpy
+	__GI_stpcpy = __stpcpy_i586
+#endif
diff --git a/sysdeps/i386/i586/multiarch/stpcpy.c b/sysdeps/i386/i586/multiarch/stpcpy.c
new file mode 100644
index 0000000000..ab6cc065e1
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/stpcpy.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/stpcpy.c>
diff --git a/sysdeps/i386/i586/multiarch/strcpy-i586.S b/sysdeps/i386/i586/multiarch/strcpy-i586.S
new file mode 100644
index 0000000000..b9b15b5424
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strcpy-i586.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/strcpy-i586.S>
+
+#ifdef SHARED
+	.globl __GI_strcpy
+	.hidden __GI_strcpy
+	__GI_strcpy = __strcpy_i586
+#endif
diff --git a/sysdeps/i386/i586/multiarch/strcpy.c b/sysdeps/i386/i586/multiarch/strcpy.c
new file mode 100644
index 0000000000..65f5398e2c
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strcpy.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/strcpy.c>
diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 101bb7d4c3..2a14fe8983 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -2,9 +2,8 @@ ifeq ($(subdir),string)
 sysdep_routines += strcmp-ssse3 \
 		   strcmp-sse4 strncmp-c strncmp-ssse3 strncmp-sse4 \
 		   varshift \
-		   strlen-sse2 strlen-sse2-bsf strncpy-c strcpy-ssse3 \
-		   strncpy-ssse3 stpcpy-ssse3 stpncpy-ssse3 strcpy-sse2 \
-		   strncpy-sse2 stpcpy-sse2 stpncpy-sse2 strcat-ssse3 \
+		   strlen-sse2 strlen-sse2-bsf \
+		   strcat-ssse3 \
 		   strcat-sse2 strncat-ssse3 strncat-sse2 strncat-c \
 		   strchr-sse2 strrchr-sse2 strchr-sse2-bsf strrchr-sse2-bsf \
 		   strnlen-sse2 strnlen-c \
diff --git a/sysdeps/i386/i686/multiarch/stpcpy.S b/sysdeps/i386/i686/multiarch/stpcpy.S
deleted file mode 100644
index ee81ab6ae3..0000000000
--- a/sysdeps/i386/i686/multiarch/stpcpy.S
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Multiple versions of stpcpy
-   All versions must be listed in ifunc-impl-list.c.  */
-#define USE_AS_STPCPY
-#define STRCPY __stpcpy
-#include "strcpy.S"
-
-weak_alias (__stpcpy, stpcpy)
-libc_hidden_def (__stpcpy)
-libc_hidden_builtin_def (stpcpy)
diff --git a/sysdeps/i386/i686/multiarch/stpncpy.S b/sysdeps/i386/i686/multiarch/stpncpy.S
deleted file mode 100644
index 2698ca6a8c..0000000000
--- a/sysdeps/i386/i686/multiarch/stpncpy.S
+++ /dev/null
@@ -1,8 +0,0 @@
-/* Multiple versions of stpncpy
-   All versions must be listed in ifunc-impl-list.c.  */
-#define STRCPY __stpncpy
-#define USE_AS_STPCPY
-#define USE_AS_STRNCPY
-#include "strcpy.S"
-
-weak_alias (__stpncpy, stpncpy)
diff --git a/sysdeps/i386/i686/multiarch/strcpy.S b/sysdeps/i386/i686/multiarch/strcpy.S
deleted file mode 100644
index e9db766347..0000000000
--- a/sysdeps/i386/i686/multiarch/strcpy.S
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Multiple versions of strcpy
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   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
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if !defined (USE_AS_STPCPY) && !defined (USE_AS_STRNCPY)
-# ifndef STRCPY
-#  define STRCPY strcpy
-# endif
-#endif
-
-#ifdef USE_AS_STPCPY
-# ifdef USE_AS_STRNCPY
-#  define STRCPY_SSSE3	__stpncpy_ssse3
-#  define STRCPY_SSE2		__stpncpy_sse2
-#  define STRCPY_IA32		__stpncpy_ia32
-#  define __GI_STRCPY		__GI_stpncpy
-#  define __GI___STRCPY		__GI___stpncpy
-# else
-#  define STRCPY_SSSE3	__stpcpy_ssse3
-#  define STRCPY_SSE2		__stpcpy_sse2
-#  define STRCPY_IA32		__stpcpy_ia32
-#  define __GI_STRCPY		__GI_stpcpy
-#  define __GI___STRCPY		__GI___stpcpy
-# endif
-#else
-# ifdef USE_AS_STRNCPY
-#  define STRCPY_SSSE3	__strncpy_ssse3
-#  define STRCPY_SSE2		__strncpy_sse2
-#  define STRCPY_IA32		__strncpy_ia32
-#  define __GI_STRCPY		__GI_strncpy
-# else
-#  define STRCPY_SSSE3	__strcpy_ssse3
-#  define STRCPY_SSE2		__strcpy_sse2
-#  define STRCPY_IA32		__strcpy_ia32
-#  define __GI_STRCPY		__GI_strcpy
-# endif
-#endif
-
-
-/* Define multiple versions only for the definition in libc.  Don't
-   define multiple versions for strncpy in static library since we
-   need strncpy before the initialization happened.  */
-#if IS_IN (libc)
-
-	.text
-ENTRY(STRCPY)
-	.type	STRCPY, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (STRCPY_IA32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCPY_SSE2)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCPY_SSSE3)
-2:	ret
-END(STRCPY)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type STRCPY_IA32, @function; \
-	.align 16; \
-	.globl STRCPY_IA32; \
-	.hidden STRCPY_IA32; \
-	STRCPY_IA32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size STRCPY_IA32, .-STRCPY_IA32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* It doesn't make sense to send libc-internal strcpy calls through a PLT.
-   The speedup we get from using SSSE3 instruction is likely eaten away
-   by the indirect call in the PLT.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_STRCPY; __GI_STRCPY = STRCPY_IA32
-#  undef libc_hidden_def
-#  define libc_hidden_def(name) \
-	.globl __GI___STRCPY; __GI___STRCPY = STRCPY_IA32
-
-# endif
-#endif
-
-#ifdef USE_AS_STPCPY
-# ifdef USE_AS_STRNCPY
-#  include "../../stpncpy.S"
-# else
-#  include "../../i586/stpcpy.S"
-# endif
-#else
-# ifndef USE_AS_STRNCPY
-#  include "../../i586/strcpy.S"
-# endif
-#endif
diff --git a/sysdeps/i386/i686/multiarch/strncpy-c.c b/sysdeps/i386/i686/multiarch/strncpy-c.c
deleted file mode 100644
index 201e3f98b3..0000000000
--- a/sysdeps/i386/i686/multiarch/strncpy-c.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#define STRNCPY __strncpy_ia32
-#ifdef SHARED
-# undef libc_hidden_builtin_def
-# define libc_hidden_builtin_def(name)  \
-    __hidden_ver1 (__strncpy_ia32, __GI_strncpy, __strncpy_ia32);
-#endif
-
-#include "string/strncpy.c"
diff --git a/sysdeps/i386/i686/multiarch/strncpy.S b/sysdeps/i386/i686/multiarch/strncpy.S
deleted file mode 100644
index 9c257efc6e..0000000000
--- a/sysdeps/i386/i686/multiarch/strncpy.S
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Multiple versions of strncpy
-   All versions must be listed in ifunc-impl-list.c.  */
-#define USE_AS_STRNCPY
-#define STRCPY strncpy
-#include "strcpy.S"
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 32d37832f4..1518caed7d 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -21,7 +21,11 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   memchr-sse2-bsf memchr-sse2 \
 		   memcmp-i386 memcmp-i686 memcmp-ssse3 memcmp-sse4 \
 		   memrchr-i386 memrchr-sse2-bsf memrchr-sse2 \
-		   rawmemchr-sse2-bsf rawmemchr-sse2
+		   rawmemchr-sse2-bsf rawmemchr-sse2 \
+		   stpcpy-i386 stpcpy-i586 stpcpy-sse2 stpcpy-ssse3 \
+		   stpncpy-i386 stpncpy-sse2 stpncpy-ssse3 \
+		   strcpy-i386 strcpy-i586 strcpy-sse2 strcpy-ssse3 \
+		   strncpy-i386 strncpy-sse2 strncpy-ssse3
 endif
 
 ifeq (mathyes,$(subdir)$(config-cflags-avx))
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index ce5abeb335..412f227457 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -165,14 +165,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __rawmemchr_sse2)
 	      IFUNC_IMPL_ADD (array, i, rawmemchr, 1, __rawmemchr_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/stpncpy.S.  */
   IFUNC_IMPL (i, name, stpncpy,
 	      IFUNC_IMPL_ADD (array, i, stpncpy, HAS_CPU_FEATURE (SSSE3),
 			      __stpncpy_ssse3)
 	      IFUNC_IMPL_ADD (array, i, stpncpy, HAS_CPU_FEATURE (SSE2),
 			      __stpncpy_sse2)
-	      IFUNC_IMPL_ADD (array, i, stpncpy, 1, __stpncpy_ia32))
+	      IFUNC_IMPL_ADD (array, i, stpncpy, 1, __stpncpy_i386))
 
   /* Support sysdeps/i386/i686/multiarch/stpcpy.S.  */
   IFUNC_IMPL (i, name, stpcpy,
@@ -180,8 +179,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __stpcpy_ssse3)
 	      IFUNC_IMPL_ADD (array, i, stpcpy, HAS_CPU_FEATURE (SSE2),
 			      __stpcpy_sse2)
-	      IFUNC_IMPL_ADD (array, i, stpcpy, 1, __stpcpy_ia32))
+	      IFUNC_IMPL_ADD (array, i, stpcpy, HAS_I586, __stpcpy_i586)
+#if MINIMUM_ISA < 586
+	      IFUNC_IMPL_ADD (array, i, stpcpy, 1, __stpcpy_i386)
+#endif
+	     )
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strcasecmp.S.  */
   IFUNC_IMPL (i, name, strcasecmp,
 	      IFUNC_IMPL_ADD (array, i, strcasecmp,
@@ -226,6 +230,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSSE3),
 			      __strcmp_ssse3)
 	      IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/strcpy.S.  */
   IFUNC_IMPL (i, name, strcpy,
@@ -233,8 +238,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strcpy_ssse3)
 	      IFUNC_IMPL_ADD (array, i, strcpy, HAS_CPU_FEATURE (SSE2),
 			      __strcpy_sse2)
-	      IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_ia32))
+	      IFUNC_IMPL_ADD (array, i, strcpy, HAS_I586, __strcpy_i586)
+#if MINIMUM_ISA < 586
+	      IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_i386)
+#endif
+	     )
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strcspn.S.  */
   IFUNC_IMPL (i, name, strcspn,
 	      IFUNC_IMPL_ADD (array, i, strcspn, HAS_CPU_FEATURE (SSE4_2),
@@ -270,6 +280,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSE2),
 			      __strncat_sse2)
 	      IFUNC_IMPL_ADD (array, i, strncat, 1, __strncat_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/strncpy.S.  */
   IFUNC_IMPL (i, name, strncpy,
@@ -277,8 +288,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strncpy_ssse3)
 	      IFUNC_IMPL_ADD (array, i, strncpy, HAS_CPU_FEATURE (SSE2),
 			      __strncpy_sse2)
-	      IFUNC_IMPL_ADD (array, i, strncpy, 1, __strncpy_ia32))
+	      IFUNC_IMPL_ADD (array, i, strncpy, 1, __strncpy_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strnlen.S.  */
   IFUNC_IMPL (i, name, strnlen,
 	      IFUNC_IMPL_ADD (array, i, strnlen, HAS_CPU_FEATURE (SSE2),
diff --git a/sysdeps/i386/multiarch/rtld-stpcpy.S b/sysdeps/i386/multiarch/rtld-stpcpy.S
new file mode 100644
index 0000000000..5a49821430
--- /dev/null
+++ b/sysdeps/i386/multiarch/rtld-stpcpy.S
@@ -0,0 +1,19 @@
+/* stpcpy for ld.so
+   Copyright (C) 2015 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
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdeps/i386/stpcpy.S>
diff --git a/sysdeps/i386/multiarch/stpcpy-i386.S b/sysdeps/i386/multiarch/stpcpy-i386.S
new file mode 100644
index 0000000000..ef1ff41568
--- /dev/null
+++ b/sysdeps/i386/multiarch/stpcpy-i386.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/i586/multiarch/stpcpy-i386.S>
+
+#ifdef SHARED
+	.globl __GI_stpcpy
+	.hidden __GI_stpcpy
+	__GI_stpcpy = __stpcpy_i386
+#endif
diff --git a/sysdeps/i386/multiarch/stpcpy-i586.S b/sysdeps/i386/multiarch/stpcpy-i586.S
new file mode 100644
index 0000000000..f797959103
--- /dev/null
+++ b/sysdeps/i386/multiarch/stpcpy-i586.S
@@ -0,0 +1,8 @@
+#define __stpcpy __stpcpy_i586
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef libc_hidden_def
+#define libc_hidden_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/i586/stpcpy.S>
diff --git a/sysdeps/i386/i686/multiarch/stpcpy-sse2.S b/sysdeps/i386/multiarch/stpcpy-sse2.S
index 46ca1b3074..46ca1b3074 100644
--- a/sysdeps/i386/i686/multiarch/stpcpy-sse2.S
+++ b/sysdeps/i386/multiarch/stpcpy-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/stpcpy-ssse3.S b/sysdeps/i386/multiarch/stpcpy-ssse3.S
index d971c2da38..d971c2da38 100644
--- a/sysdeps/i386/i686/multiarch/stpcpy-ssse3.S
+++ b/sysdeps/i386/multiarch/stpcpy-ssse3.S
diff --git a/sysdeps/i386/multiarch/stpcpy.c b/sysdeps/i386/multiarch/stpcpy.c
new file mode 100644
index 0000000000..58a54fc386
--- /dev/null
+++ b/sysdeps/i386/multiarch/stpcpy.c
@@ -0,0 +1,59 @@
+/* Multiple versions of stpcpy.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 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
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define _HAVE_STRING_ARCH_stpcpy
+# define NO_MEMPCPY_STPCPY_REDIRECT
+/* Redefine stpcpy so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef stpcpy
+# define stpcpy __redirect_stpcpy
+# include <string.h>
+# undef stpcpy
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_stpcpy) __stpcpy_i386 attribute_hidden;
+extern __typeof (__redirect_stpcpy) __stpcpy_i586 attribute_hidden;
+extern __typeof (__redirect_stpcpy) __stpcpy_sse2 attribute_hidden;
+extern __typeof (__redirect_stpcpy) __stpcpy_ssse3 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_stpcpy) __stpcpy;
+extern void *stpcpy_ifunc (void) __asm__ ("__stpcpy");
+
+void *
+stpcpy_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    return __stpcpy_ssse3;
+  else if (HAS_CPU_FEATURE (SSE2))
+    return __stpcpy_sse2;
+
+  if (USE_I586)
+    return __stpcpy_i586;
+  else
+    return __stpcpy_i386;
+}
+__asm__ (".type __stpcpy, %gnu_indirect_function");
+
+weak_alias (__stpcpy, stpcpy)
+#endif
diff --git a/sysdeps/i386/multiarch/stpncpy-i386.S b/sysdeps/i386/multiarch/stpncpy-i386.S
new file mode 100644
index 0000000000..3cd0903508
--- /dev/null
+++ b/sysdeps/i386/multiarch/stpncpy-i386.S
@@ -0,0 +1,12 @@
+#define __stpncpy __stpncpy_i386
+#undef libc_hidden_def
+#define libc_hidden_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/stpncpy.S>
+
+#ifdef SHARED
+	.globl __GI___stpncpy
+	.hidden __GI___stpncpy
+	__GI___stpncpy = __stpncpy_i386
+#endif
diff --git a/sysdeps/i386/i686/multiarch/stpncpy-sse2.S b/sysdeps/i386/multiarch/stpncpy-sse2.S
index 37a703cb76..37a703cb76 100644
--- a/sysdeps/i386/i686/multiarch/stpncpy-sse2.S
+++ b/sysdeps/i386/multiarch/stpncpy-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/stpncpy-ssse3.S b/sysdeps/i386/multiarch/stpncpy-ssse3.S
index 14ed16f6b5..14ed16f6b5 100644
--- a/sysdeps/i386/i686/multiarch/stpncpy-ssse3.S
+++ b/sysdeps/i386/multiarch/stpncpy-ssse3.S
diff --git a/sysdeps/i386/multiarch/stpncpy.c b/sysdeps/i386/multiarch/stpncpy.c
new file mode 100644
index 0000000000..609d8d4109
--- /dev/null
+++ b/sysdeps/i386/multiarch/stpncpy.c
@@ -0,0 +1,54 @@
+/* Multiple versions of stpncpy.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 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
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define _HAVE_STRING_ARCH_stpncpy
+/* Redefine stpncpy so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef stpncpy
+# define stpncpy __redirect_stpncpy
+# include <string.h>
+# undef stpncpy
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_stpncpy) __stpncpy_i386 attribute_hidden;
+extern __typeof (__redirect_stpncpy) __stpncpy_sse2 attribute_hidden;
+extern __typeof (__redirect_stpncpy) __stpncpy_ssse3 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_stpncpy) __stpncpy;
+extern void *stpncpy_ifunc (void) __asm__ ("__stpncpy");
+
+void *
+stpncpy_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    return __stpncpy_ssse3;
+  else if (HAS_CPU_FEATURE (SSE2))
+    return __stpncpy_sse2;
+
+  return __stpncpy_i386;
+}
+__asm__ (".type __stpncpy, %gnu_indirect_function");
+
+weak_alias (__stpncpy, stpncpy)
+#endif
diff --git a/sysdeps/i386/multiarch/strcpy-i386.c b/sysdeps/i386/multiarch/strcpy-i386.c
new file mode 100644
index 0000000000..e577628fd4
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcpy-i386.c
@@ -0,0 +1,11 @@
+#include <init-arch.h>
+#undef libc_hidden_builtin_def
+#if defined SHARED && MINIMUM_ISA != 586
+# define libc_hidden_builtin_def(name)  \
+   __hidden_ver1 (__strcpy_i386, __GI_strcpy, __strcpy_i386);
+#else
+# define libc_hidden_builtin_def(name)
+#endif
+
+#define STRCPY __strcpy_i386
+#include "string/strcpy.c"
diff --git a/sysdeps/i386/multiarch/strcpy-i586.S b/sysdeps/i386/multiarch/strcpy-i586.S
new file mode 100644
index 0000000000..65e064191b
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcpy-i586.S
@@ -0,0 +1,4 @@
+#define strcpy __strcpy_i586
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/i586/strcpy.S>
diff --git a/sysdeps/i386/i686/multiarch/strcpy-sse2.S b/sysdeps/i386/multiarch/strcpy-sse2.S
index a37c44530d..a37c44530d 100644
--- a/sysdeps/i386/i686/multiarch/strcpy-sse2.S
+++ b/sysdeps/i386/multiarch/strcpy-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/strcpy-ssse3.S b/sysdeps/i386/multiarch/strcpy-ssse3.S
index 9f88e7735d..9f88e7735d 100644
--- a/sysdeps/i386/i686/multiarch/strcpy-ssse3.S
+++ b/sysdeps/i386/multiarch/strcpy-ssse3.S
diff --git a/sysdeps/i386/multiarch/strcpy.c b/sysdeps/i386/multiarch/strcpy.c
new file mode 100644
index 0000000000..ede627c593
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcpy.c
@@ -0,0 +1,55 @@
+/* Multiple versions of strcpy.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 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
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+/* Redefine strcpy so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strcpy
+# define strcpy __redirect_strcpy
+# include <string.h>
+# undef strcpy
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strcpy) __strcpy_i386 attribute_hidden;
+extern __typeof (__redirect_strcpy) __strcpy_i586 attribute_hidden;
+extern __typeof (__redirect_strcpy) __strcpy_sse2 attribute_hidden;
+extern __typeof (__redirect_strcpy) __strcpy_ssse3 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strcpy) strcpy;
+extern void *strcpy_ifunc (void) __asm__ ("strcpy");
+
+void *
+strcpy_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    return __strcpy_ssse3;
+  else if (HAS_CPU_FEATURE (SSE2))
+    return __strcpy_sse2;
+
+  if (USE_I586)
+    return __strcpy_i586;
+  else
+    return __strcpy_i386;
+}
+__asm__ (".type strcpy, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/multiarch/strncpy-i386.c b/sysdeps/i386/multiarch/strncpy-i386.c
new file mode 100644
index 0000000000..b584d83470
--- /dev/null
+++ b/sysdeps/i386/multiarch/strncpy-i386.c
@@ -0,0 +1,12 @@
+#include <init-arch.h>
+#undef libc_hidden_builtin_def
+#ifdef SHARED
+# define libc_hidden_builtin_def(name)  \
+    __hidden_ver1 (__strncpy_i386, __GI_strncpy, __strncpy_i386);
+#else
+# define libc_hidden_builtin_def(name)
+#endif
+
+#define _HAVE_STRING_ARCH_strncpy
+#define STRNCPY __strncpy_i386
+#include "string/strncpy.c"
diff --git a/sysdeps/i386/i686/multiarch/strncpy-sse2.S b/sysdeps/i386/multiarch/strncpy-sse2.S
index bdd99239a4..bdd99239a4 100644
--- a/sysdeps/i386/i686/multiarch/strncpy-sse2.S
+++ b/sysdeps/i386/multiarch/strncpy-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/strncpy-ssse3.S b/sysdeps/i386/multiarch/strncpy-ssse3.S
index bf82ee447d..bf82ee447d 100644
--- a/sysdeps/i386/i686/multiarch/strncpy-ssse3.S
+++ b/sysdeps/i386/multiarch/strncpy-ssse3.S
diff --git a/sysdeps/i386/multiarch/strncpy.c b/sysdeps/i386/multiarch/strncpy.c
new file mode 100644
index 0000000000..aa98708c3c
--- /dev/null
+++ b/sysdeps/i386/multiarch/strncpy.c
@@ -0,0 +1,52 @@
+/* Multiple versions of strncpy.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 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
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define _HAVE_STRING_ARCH_strncpy
+/* Redefine strncpy so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strncpy
+# define strncpy __redirect_strncpy
+# include <string.h>
+# undef strncpy
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strncpy) __strncpy_i386 attribute_hidden;
+extern __typeof (__redirect_strncpy) __strncpy_sse2 attribute_hidden;
+extern __typeof (__redirect_strncpy) __strncpy_ssse3 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strncpy) strncpy;
+extern void *strncpy_ifunc (void) __asm__ ("strncpy");
+
+void *
+strncpy_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    return __strncpy_ssse3;
+  else if (HAS_CPU_FEATURE (SSE2))
+    return __strncpy_sse2;
+
+  return __strncpy_i386;
+}
+__asm__ (".type strncpy, %gnu_indirect_function");
+#endif