This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch hjl/i486/multiarch created. glibc-2.22-152-g536b8e1


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, hjl/i486/multiarch has been created
        at  536b8e1ceb50633d59fb386af6b7c295cee49e40 (commit)

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=536b8e1ceb50633d59fb386af6b7c295cee49e40

commit 536b8e1ceb50633d59fb386af6b7c295cee49e40
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Aug 25 06:24:16 2015 -0700

    Add i386 wcscpy multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index a9d032f..57cd608 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,5 +1,4 @@
 ifeq ($(subdir),wcsmbs)
 sysdep_routines += wcslen-sse2 wcslen-c \
-		   wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c \
-		   wcscpy-ssse3 wcscpy-c
+		   wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c
 endif
diff --git a/sysdeps/i386/i686/multiarch/wcscpy.S b/sysdeps/i386/i686/multiarch/wcscpy.S
deleted file mode 100644
index 5f14970..0000000
--- a/sysdeps/i386/i686/multiarch/wcscpy.S
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Multiple versions of wcscpy
-   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>
-
-/* Define multiple versions only for the definition in libc. */
-#if IS_IN (libc)
-	.text
-ENTRY(wcscpy)
-	.type	wcscpy, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcscpy_ia32)
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcscpy_ssse3)
-2:	ret
-END(wcscpy)
-#endif
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 0792f1d..76e0820 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -51,7 +51,7 @@ endif
 
 ifeq ($(subdir),wcsmbs)
 sysdep_routines += wcschr-i386 wcschr-sse2 wcsrchr-i386 wcsrchr-sse2 \
-		   wcscmp-i386 wcscmp-sse2
+		   wcscmp-i386 wcscmp-sse2 wcscpy-i386 wcscpy-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 34f2a93..795771d 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -330,13 +330,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __wcscmp_sse2)
 	      IFUNC_IMPL_ADD (array, i, wcscmp, 1, __wcscmp_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/wcscpy.S.  */
   IFUNC_IMPL (i, name, wcscpy,
 	      IFUNC_IMPL_ADD (array, i, wcscpy, HAS_CPU_FEATURE (SSSE3),
 			      __wcscpy_ssse3)
-	      IFUNC_IMPL_ADD (array, i, wcscpy, 1, __wcscpy_ia32))
+	      IFUNC_IMPL_ADD (array, i, wcscpy, 1, __wcscpy_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/wcslen.S.  */
   IFUNC_IMPL (i, name, wcslen,
 	      IFUNC_IMPL_ADD (array, i, wcslen, HAS_CPU_FEATURE (SSE2),
diff --git a/sysdeps/i386/i686/multiarch/wcscpy-c.c b/sysdeps/i386/multiarch/wcscpy-i386.c
similarity index 62%
rename from sysdeps/i386/i686/multiarch/wcscpy-c.c
rename to sysdeps/i386/multiarch/wcscpy-i386.c
index fb30003..3207110 100644
--- a/sysdeps/i386/i686/multiarch/wcscpy-c.c
+++ b/sysdeps/i386/multiarch/wcscpy-i386.c
@@ -1,5 +1,5 @@
 #if IS_IN (libc)
-# define wcscpy  __wcscpy_ia32
+# define wcscpy  __wcscpy_i386
 #endif
 
 #include "wcsmbs/wcscpy.c"
diff --git a/sysdeps/i386/i686/multiarch/wcscpy-ssse3.S b/sysdeps/i386/multiarch/wcscpy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/wcscpy-ssse3.S
rename to sysdeps/i386/multiarch/wcscpy-ssse3.S
diff --git a/sysdeps/i386/multiarch/wcscpy.c b/sysdeps/i386/multiarch/wcscpy.c
new file mode 100644
index 0000000..ac5f3e5
--- /dev/null
+++ b/sysdeps/i386/multiarch/wcscpy.c
@@ -0,0 +1,48 @@
+/* Multiple versions of wcscpy.
+   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 wcscpy so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef wcscpy
+# define wcscpy __redirect_wcscpy
+# include <wchar.h>
+# undef wcscpy
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_wcscpy) __wcscpy_i386 attribute_hidden;
+extern __typeof (__redirect_wcscpy) __wcscpy_ssse3 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_wcscpy) wcscpy;
+extern void *wcscpy_ifunc (void) __asm__ ("wcscpy");
+
+void *
+wcscpy_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    return __wcscpy_ssse3;
+
+  return __wcscpy_i386;
+}
+__asm__ (".type wcscpy, %gnu_indirect_function");
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=ea1d64156d574bdc6055369ffde07462d0f36a80

commit ea1d64156d574bdc6055369ffde07462d0f36a80
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Aug 25 06:12:47 2015 -0700

    Add i386 wcscmp multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 289f0f9..a9d032f 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,5 +1,5 @@
 ifeq ($(subdir),wcsmbs)
-sysdep_routines += wcscmp-sse2 wcscmp-c wcslen-sse2 wcslen-c \
+sysdep_routines += wcslen-sse2 wcslen-c \
 		   wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c \
 		   wcscpy-ssse3 wcscpy-c
 endif
diff --git a/sysdeps/i386/i686/multiarch/wcscmp.S b/sysdeps/i386/i686/multiarch/wcscmp.S
deleted file mode 100644
index db9c05a..0000000
--- a/sysdeps/i386/i686/multiarch/wcscmp.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Multiple versions of wcscmp
-   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>
-
-/* Define multiple versions only for the definition in libc and for the
-   DSO.  In static binaries, we need wcscmp before the initialization
-   happened.  */
-#if IS_IN (libc)
-	.text
-ENTRY(__wcscmp)
-	.type	__wcscmp, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcscmp_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcscmp_sse2)
-2:	ret
-END(__wcscmp)
-weak_alias (__wcscmp, wcscmp)
-#endif
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index f28f0ba..0792f1d 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -50,7 +50,8 @@ endif
 endif
 
 ifeq ($(subdir),wcsmbs)
-sysdep_routines += wcschr-i386 wcschr-sse2 wcsrchr-i386 wcsrchr-sse2
+sysdep_routines += wcschr-i386 wcschr-sse2 wcsrchr-i386 wcsrchr-sse2 \
+		   wcscmp-i386 wcscmp-sse2
 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 23a3958..34f2a93 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -324,13 +324,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __wcschr_sse2)
 	      IFUNC_IMPL_ADD (array, i, wcschr, 1, __wcschr_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/wcscmp.S.  */
   IFUNC_IMPL (i, name, wcscmp,
 	      IFUNC_IMPL_ADD (array, i, wcscmp, HAS_CPU_FEATURE (SSE2),
 			      __wcscmp_sse2)
-	      IFUNC_IMPL_ADD (array, i, wcscmp, 1, __wcscmp_ia32))
+	      IFUNC_IMPL_ADD (array, i, wcscmp, 1, __wcscmp_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/wcscpy.S.  */
   IFUNC_IMPL (i, name, wcscpy,
 	      IFUNC_IMPL_ADD (array, i, wcscpy, HAS_CPU_FEATURE (SSSE3),
diff --git a/sysdeps/i386/i686/multiarch/wcscmp-c.c b/sysdeps/i386/multiarch/wcscmp-i386.c
similarity index 57%
rename from sysdeps/i386/i686/multiarch/wcscmp-c.c
rename to sysdeps/i386/multiarch/wcscmp-i386.c
index e3337d7..538a823 100644
--- a/sysdeps/i386/i686/multiarch/wcscmp-c.c
+++ b/sysdeps/i386/multiarch/wcscmp-i386.c
@@ -1,14 +1,14 @@
 #include <wchar.h>
 
-#define WCSCMP __wcscmp_ia32
+#define WCSCMP __wcscmp_i386
 #ifdef SHARED
 # undef libc_hidden_def
 # define libc_hidden_def(name) \
-  __hidden_ver1 (__wcscmp_ia32, __GI___wcscmp, __wcscmp_ia32);
+  __hidden_ver1 (__wcscmp_i386, __GI___wcscmp, __wcscmp_i386);
 #endif
 #undef weak_alias
 #define weak_alias(name, alias)
 
-extern __typeof (wcscmp) __wcscmp_ia32;
+extern __typeof (wcscmp) __wcscmp_i386;
 
 #include "wcsmbs/wcscmp.c"
diff --git a/sysdeps/i386/i686/multiarch/wcscmp-sse2.S b/sysdeps/i386/multiarch/wcscmp-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/wcscmp-sse2.S
rename to sysdeps/i386/multiarch/wcscmp-sse2.S
diff --git a/sysdeps/i386/multiarch/wcscmp.c b/sysdeps/i386/multiarch/wcscmp.c
new file mode 100644
index 0000000..48b56f8
--- /dev/null
+++ b/sysdeps/i386/multiarch/wcscmp.c
@@ -0,0 +1,50 @@
+/* Multiple versions of wcscmp.
+   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 wcscmp so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef wcscmp
+# define wcscmp __redirect_wcscmp
+# include <wchar.h>
+# undef wcscmp
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_wcscmp) __wcscmp_i386 attribute_hidden;
+extern __typeof (__redirect_wcscmp) __wcscmp_sse2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_wcscmp) __wcscmp;
+extern void *wcscmp_ifunc (void) __asm__ ("__wcscmp");
+
+void *
+wcscmp_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    return __wcscmp_sse2;
+
+  return __wcscmp_i386;
+}
+__asm__ (".type __wcscmp, %gnu_indirect_function");
+
+weak_alias (__wcscmp, wcscmp)
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=0a9625e8a3bd2892af1c9c6ebad74330ae69283d

commit 0a9625e8a3bd2892af1c9c6ebad74330ae69283d
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Aug 25 06:06:30 2015 -0700

    Add i386 wcschr/wcsrchr multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index ff54ee9..289f0f9 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,5 +1,5 @@
 ifeq ($(subdir),wcsmbs)
 sysdep_routines += wcscmp-sse2 wcscmp-c wcslen-sse2 wcslen-c \
-		   wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c wcschr-sse2 \
-		   wcschr-c wcsrchr-sse2 wcsrchr-c wcscpy-ssse3 wcscpy-c
+		   wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c \
+		   wcscpy-ssse3 wcscpy-c
 endif
diff --git a/sysdeps/i386/i686/multiarch/wcschr.S b/sysdeps/i386/i686/multiarch/wcschr.S
deleted file mode 100644
index 5918b12..0000000
--- a/sysdeps/i386/i686/multiarch/wcschr.S
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Multiple versions of wcschr
-   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 IS_IN (libc)
-	.text
-ENTRY(__wcschr)
-	.type	wcschr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcschr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcschr_sse2)
-2:	ret
-END(__wcschr)
-weak_alias (__wcschr, wcschr)
-#endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/wcsrchr.S
deleted file mode 100644
index 9ed6810..0000000
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Multiple versions of wcsrchr
-   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 IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
-#endif
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 8e38096..f28f0ba 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -49,6 +49,10 @@ CFLAGS-strspn-sse4.c += -msse4
 endif
 endif
 
+ifeq ($(subdir),wcsmbs)
+sysdep_routines += wcschr-i386 wcschr-sse2 wcsrchr-i386 wcsrchr-sse2
+endif
+
 ifeq (mathyes,$(subdir)$(config-cflags-avx))
 libm-sysdep_routines += s_fma-fma s_fmaf-fma
 CFLAGS-s_fma-fma.c += -mavx -mfpmath=sse
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 191a9e2..23a3958 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -318,13 +318,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strspn_sse42)
 	      IFUNC_IMPL_ADD (array, i, strspn, 1, __strspn_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/wcschr.S.  */
   IFUNC_IMPL (i, name, wcschr,
 	      IFUNC_IMPL_ADD (array, i, wcschr, HAS_CPU_FEATURE (SSE2),
 			      __wcschr_sse2)
-	      IFUNC_IMPL_ADD (array, i, wcschr, 1, __wcschr_ia32))
+	      IFUNC_IMPL_ADD (array, i, wcschr, 1, __wcschr_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/wcscmp.S.  */
   IFUNC_IMPL (i, name, wcscmp,
 	      IFUNC_IMPL_ADD (array, i, wcscmp, HAS_CPU_FEATURE (SSE2),
@@ -342,13 +342,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, wcslen, HAS_CPU_FEATURE (SSE2),
 			      __wcslen_sse2)
 	      IFUNC_IMPL_ADD (array, i, wcslen, 1, __wcslen_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/wcsrchr.S.  */
   IFUNC_IMPL (i, name, wcsrchr,
 	      IFUNC_IMPL_ADD (array, i, wcsrchr, HAS_CPU_FEATURE (SSE2),
 			      __wcsrchr_sse2)
-	      IFUNC_IMPL_ADD (array, i, wcsrchr, 1, __wcsrchr_ia32))
+	      IFUNC_IMPL_ADD (array, i, wcsrchr, 1, __wcsrchr_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/wmemcmp.S.  */
   IFUNC_IMPL (i, name, wmemcmp,
 	      IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSE4_2),
diff --git a/sysdeps/i386/i686/multiarch/wcschr-c.c b/sysdeps/i386/multiarch/wcschr-i386.c
similarity index 51%
rename from sysdeps/i386/i686/multiarch/wcschr-c.c
rename to sysdeps/i386/multiarch/wcschr-i386.c
index 38d41d0..de06c24 100644
--- a/sysdeps/i386/i686/multiarch/wcschr-c.c
+++ b/sysdeps/i386/multiarch/wcschr-i386.c
@@ -10,13 +10,13 @@
 # ifdef SHARED
 #  undef libc_hidden_def
 #  define libc_hidden_def(name) \
-   __hidden_ver1 (__wcschr_ia32, __GI_wcschr, __wcschr_ia32); \
-   strong_alias (__wcschr_ia32, __wcschr_ia32_1); \
-   __hidden_ver1 (__wcschr_ia32_1, __GI___wcschr, __wcschr_ia32_1);
+   __hidden_ver1 (__wcschr_i386, __GI_wcschr, __wcschr_i386); \
+   strong_alias (__wcschr_i386, __wcschr_i386_1); \
+   __hidden_ver1 (__wcschr_i386_1, __GI___wcschr, __wcschr_i386_1);
 # endif
 #endif
 
-extern __typeof (wcschr) __wcschr_ia32;
+extern __typeof (wcschr) __wcschr_i386;
 
-#define WCSCHR  __wcschr_ia32
+#define WCSCHR  __wcschr_i386
 #include <wcsmbs/wcschr.c>
diff --git a/sysdeps/i386/i686/multiarch/wcschr-sse2.S b/sysdeps/i386/multiarch/wcschr-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/wcschr-sse2.S
rename to sysdeps/i386/multiarch/wcschr-sse2.S
diff --git a/sysdeps/i386/multiarch/wcschr.c b/sysdeps/i386/multiarch/wcschr.c
new file mode 100644
index 0000000..25cc0db
--- /dev/null
+++ b/sysdeps/i386/multiarch/wcschr.c
@@ -0,0 +1,50 @@
+/* Multiple versions of wcschr.
+   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 wcschr so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef wcschr
+# define wcschr __redirect_wcschr
+# include <wchar.h>
+# undef wcschr
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_wcschr) __wcschr_i386 attribute_hidden;
+extern __typeof (__redirect_wcschr) __wcschr_sse2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_wcschr) __wcschr;
+extern void *wcschr_ifunc (void) __asm__ ("__wcschr");
+
+void *
+wcschr_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    return __wcschr_sse2;
+
+  return __wcschr_i386;
+}
+__asm__ (".type __wcschr, %gnu_indirect_function");
+
+weak_alias (__wcschr, wcschr)
+#endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr-c.c b/sysdeps/i386/multiarch/wcsrchr-i386.c
similarity index 61%
rename from sysdeps/i386/i686/multiarch/wcsrchr-c.c
rename to sysdeps/i386/multiarch/wcsrchr-i386.c
index 8d8a335..1f7583a 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr-c.c
+++ b/sysdeps/i386/multiarch/wcsrchr-i386.c
@@ -1,5 +1,5 @@
 #if IS_IN (libc)
-# define wcsrchr  __wcsrchr_ia32
+# define wcsrchr  __wcsrchr_i386
 #endif
 
 #include "wcsmbs/wcsrchr.c"
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr-sse2.S b/sysdeps/i386/multiarch/wcsrchr-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/wcsrchr-sse2.S
rename to sysdeps/i386/multiarch/wcsrchr-sse2.S
diff --git a/sysdeps/i386/multiarch/wcsrchr.c b/sysdeps/i386/multiarch/wcsrchr.c
new file mode 100644
index 0000000..1420690
--- /dev/null
+++ b/sysdeps/i386/multiarch/wcsrchr.c
@@ -0,0 +1,48 @@
+/* Multiple versions of wcsrchr.
+   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 wcsrchr so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef wcsrchr
+# define wcsrchr __redirect_wcsrchr
+# include <wchar.h>
+# undef wcsrchr
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_wcsrchr) __wcsrchr_i386 attribute_hidden;
+extern __typeof (__redirect_wcsrchr) __wcsrchr_sse2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_wcsrchr) wcsrchr;
+extern void *wcsrchr_ifunc (void) __asm__ ("wcsrchr");
+
+void *
+wcsrchr_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    return __wcsrchr_sse2;
+
+  return __wcsrchr_i386;
+}
+__asm__ (".type wcsrchr, %gnu_indirect_function");
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=f483c163d9589d057e2f864eda400e8566fee3dd

commit f483c163d9589d057e2f864eda400e8566fee3dd
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Aug 24 16:03:28 2015 -0700

    Add i386 strspn multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 77f01df..ff54ee9 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,10 +1,3 @@
-ifeq ($(subdir),string)
-ifeq (yes,$(config-cflags-sse4))
-sysdep_routines += strspn-c
-CFLAGS-strspn-c.c += -msse4
-endif
-endif
-
 ifeq ($(subdir),wcsmbs)
 sysdep_routines += wcscmp-sse2 wcscmp-c wcslen-sse2 wcslen-c \
 		   wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c wcschr-sse2 \
diff --git a/sysdeps/i386/i686/multiarch/strspn.S b/sysdeps/i386/i686/multiarch/strspn.S
deleted file mode 100644
index 4ba87be..0000000
--- a/sysdeps/i386/i686/multiarch/strspn.S
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Multiple versions of strspn
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2009-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 <config.h>
-
-#ifdef HAVE_SSE4_SUPPORT
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in libc.  */
-#if IS_IN (libc)
-	.text
-ENTRY(strspn)
-	.type	strspn, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strspn_ia32)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strspn_sse42)
-2:	ret
-END(strspn)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __strspn_ia32, @function; \
-	.globl __strspn_ia32; \
-	.p2align 4; \
-__strspn_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __strspn_ia32, .-__strspn_ia32
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_strspn; __GI_strspn = __strspn_ia32
-#endif
-
-#endif /* HAVE_SSE4_SUPPORT */
-
-#include "../../strspn.S"
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index d0856ac..8e38096 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -38,12 +38,14 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   strcspn-i386 strpbrk-i386 \
 		   strlen-i486 strlen-i586 strlen-sse2 strlen-sse2-bsf \
 		   strnlen-sse2 strnlen-i386 static-strlen \
-		   strrchr-i386 strrchr-sse2-bsf strrchr-sse2
+		   strrchr-i386 strrchr-sse2-bsf strrchr-sse2 \
+		   strspn-i386 strspn-sse4
 ifeq (yes,$(config-cflags-sse4))
-sysdep_routines += varshift strcspn-sse4 strpbrk-sse4
+sysdep_routines += varshift strcspn-sse4 strpbrk-sse4 strspn-sse4
 CFLAGS-varshift.c += -msse4
 CFLAGS-strcspn-sse4.c += -msse4
 CFLAGS-strpbrk-sse4.c += -msse4
+CFLAGS-strspn-sse4.c += -msse4
 endif
 endif
 
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 858ace7..191a9e2 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -312,13 +312,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strrchr_sse2)
 	      IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/strspn.S.  */
   IFUNC_IMPL (i, name, strspn,
 	      IFUNC_IMPL_ADD (array, i, strspn, HAS_CPU_FEATURE (SSE4_2),
 			      __strspn_sse42)
-	      IFUNC_IMPL_ADD (array, i, strspn, 1, __strspn_ia32))
+	      IFUNC_IMPL_ADD (array, i, strspn, 1, __strspn_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/wcschr.S.  */
   IFUNC_IMPL (i, name, wcschr,
 	      IFUNC_IMPL_ADD (array, i, wcschr, HAS_CPU_FEATURE (SSE2),
diff --git a/sysdeps/i386/multiarch/strspn-i386.S b/sysdeps/i386/multiarch/strspn-i386.S
new file mode 100644
index 0000000..c6d4d67
--- /dev/null
+++ b/sysdeps/i386/multiarch/strspn-i386.S
@@ -0,0 +1,8 @@
+#define strspn __strspn_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/strspn.S>
+
+	.globl __GI_strspn
+	.hidden __GI_strspn
+	__GI_strspn = __strspn_i386
diff --git a/sysdeps/i386/i686/multiarch/strspn-c.c b/sysdeps/i386/multiarch/strspn-sse4.c
similarity index 56%
rename from sysdeps/i386/i686/multiarch/strspn-c.c
rename to sysdeps/i386/multiarch/strspn-sse4.c
index bea09de..fc84a3d 100644
--- a/sysdeps/i386/i686/multiarch/strspn-c.c
+++ b/sysdeps/i386/multiarch/strspn-sse4.c
@@ -1,2 +1,2 @@
-#define __strspn_sse2 __strspn_ia32
+#define __strspn_sse2 __strspn_i386
 #include <sysdeps/x86_64/multiarch/strspn-c.c>
diff --git a/sysdeps/i386/multiarch/strspn.c b/sysdeps/i386/multiarch/strspn.c
new file mode 100644
index 0000000..91d5a5f
--- /dev/null
+++ b/sysdeps/i386/multiarch/strspn.c
@@ -0,0 +1,49 @@
+/* Multiple versions of strspn.
+   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_strspn
+/* Redefine strspn so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strspn
+# define strspn __redirect_strspn
+# include <string.h>
+# undef strspn
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strspn) __strspn_i386 attribute_hidden;
+extern __typeof (__redirect_strspn) __strspn_sse42 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strspn) strspn;
+extern void *strspn_ifunc (void) __asm__ ("strspn");
+
+void *
+strspn_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE4_2))
+    return __strspn_sse42;
+
+  return __strspn_i386;
+}
+__asm__ (".type strspn, %gnu_indirect_function");
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=be01b50347609470a205ad28b5f786c470bc842f

commit be01b50347609470a205ad28b5f786c470bc842f
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Aug 24 13:01:12 2015 -0700

    Add i386 strlen family multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i486/multiarch/rtld-strlen.S
similarity index 59%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i486/multiarch/rtld-strlen.S
index baf21fc..303dda2 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i486/multiarch/rtld-strlen.S
@@ -1,7 +1,5 @@
-/* Multiple versions of strnlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* strlen 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
@@ -18,20 +16,4 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
-
-weak_alias(__strnlen, strnlen)
-#endif
+#include <sysdeps/i386/i486/strlen.S>
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i486/multiarch/static-strlen.S
similarity index 60%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i486/multiarch/static-strlen.S
index baf21fc..d63acbb 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i486/multiarch/static-strlen.S
@@ -1,7 +1,5 @@
-/* Multiple versions of strnlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* strlen for libc.a
+   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
@@ -18,20 +16,6 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
-
-weak_alias(__strnlen, strnlen)
+#if !defined SHARED && IS_IN (libc)
+# include <sysdeps/i386/i486/strlen.S>
 #endif
diff --git a/sysdeps/i386/i486/multiarch/strlen-i486.S b/sysdeps/i386/i486/multiarch/strlen-i486.S
new file mode 100644
index 0000000..61c08b2
--- /dev/null
+++ b/sysdeps/i386/i486/multiarch/strlen-i486.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/strlen-i486.S>
+
+#ifdef SHARED
+	.globl __GI_strlen
+	.hidden __GI_strlen
+	__GI_strlen = __strlen_i486
+#endif
diff --git a/sysdeps/i386/i486/multiarch/strlen.c b/sysdeps/i386/i486/multiarch/strlen.c
new file mode 100644
index 0000000..fb40868
--- /dev/null
+++ b/sysdeps/i386/i486/multiarch/strlen.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/strlen.c>
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i586/multiarch/rtld-strlen.S
similarity index 59%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i586/multiarch/rtld-strlen.S
index baf21fc..70fc5f3 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i586/multiarch/rtld-strlen.S
@@ -1,7 +1,5 @@
-/* Multiple versions of strnlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* strlen 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
@@ -18,20 +16,4 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
-
-weak_alias(__strnlen, strnlen)
-#endif
+#include <sysdeps/i386/i586/strlen.S>
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i586/multiarch/static-strlen.S
similarity index 60%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i586/multiarch/static-strlen.S
index baf21fc..96befd4 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i586/multiarch/static-strlen.S
@@ -1,7 +1,5 @@
-/* Multiple versions of strnlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* strlen for libc.a
+   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
@@ -18,20 +16,6 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
-
-weak_alias(__strnlen, strnlen)
+#if !defined SHARED && IS_IN (libc)
+# include <sysdeps/i386/i586/strlen.S>
 #endif
diff --git a/sysdeps/i386/i586/multiarch/strlen-i486.S b/sysdeps/i386/i586/multiarch/strlen-i486.S
new file mode 100644
index 0000000..29566d8
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strlen-i486.S
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/strlen-i486.S>
diff --git a/sysdeps/i386/i586/multiarch/strlen-i586.S b/sysdeps/i386/i586/multiarch/strlen-i586.S
new file mode 100644
index 0000000..69c3170
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strlen-i586.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/strlen-i586.S>
+
+#ifdef SHARED
+	.globl __GI_strlen
+	.hidden __GI_strlen
+	__GI_strlen = __strlen_i586
+#endif
diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 2733c2a..77f01df 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,6 +1,4 @@
 ifeq ($(subdir),string)
-sysdep_routines += strlen-sse2 strlen-sse2-bsf \
-		   strnlen-sse2 strnlen-c
 ifeq (yes,$(config-cflags-sse4))
 sysdep_routines += strspn-c
 CFLAGS-strspn-c.c += -msse4
diff --git a/sysdeps/i386/i686/multiarch/strlen.S b/sysdeps/i386/i686/multiarch/strlen.S
deleted file mode 100644
index 613559c..0000000
--- a/sysdeps/i386/i686/multiarch/strlen.S
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Multiple versions of strlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2009-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>
-
-/* Define multiple versions only for the definition in libc and for the
-   DSO.  In static binaries, we need strlen before the initialization
-   happened.  */
-#if defined SHARED && IS_IN (libc)
-	.text
-ENTRY(strlen)
-	.type	strlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strlen_sse2_bsf)
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strlen_sse2)
-2:	ret
-END(strlen)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __strlen_ia32, @function; \
-	.globl __strlen_ia32; \
-	.p2align 4; \
-	__strlen_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __strlen_ia32, .-__strlen_ia32
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_strlen; __GI_strlen = __strlen_ia32
-#endif
-
-#include "../../i586/strlen.S"
diff --git a/sysdeps/i386/i686/multiarch/strnlen-c.c b/sysdeps/i386/i686/multiarch/strnlen-c.c
deleted file mode 100644
index 351e939..0000000
--- a/sysdeps/i386/i686/multiarch/strnlen-c.c
+++ /dev/null
@@ -1,10 +0,0 @@
-#define STRNLEN  __strnlen_ia32
-#ifdef SHARED
-# undef libc_hidden_def
-# define libc_hidden_def(name)  \
-    __hidden_ver1 (__strnlen_ia32, __GI_strnlen, __strnlen_ia32); \
-    strong_alias (__strnlen_ia32, __strnlen_ia32_1); \
-    __hidden_ver1 (__strnlen_ia32_1, __GI___strnlen, __strnlen_ia32_1);
-#endif
-
-#include "string/strnlen.c"
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 49bdf25..d0856ac 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -36,6 +36,8 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   strncat-i386 strncat-sse2 strncat-ssse3 \
 		   strchr-i386 strchr-i586 strchr-sse2-bsf strchr-sse2 \
 		   strcspn-i386 strpbrk-i386 \
+		   strlen-i486 strlen-i586 strlen-sse2 strlen-sse2-bsf \
+		   strnlen-sse2 strnlen-i386 static-strlen \
 		   strrchr-i386 strrchr-sse2-bsf strrchr-sse2
 ifeq (yes,$(config-cflags-sse4))
 sysdep_routines += varshift strcspn-sse4 strpbrk-sse4
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index a464d26..858ace7 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -292,13 +292,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strncpy_sse2)
 	      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),
 			      __strnlen_sse2)
-	      IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_ia32))
-#endif
+	      IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_i386))
 
   /* Support sysdeps/i386/i686/multiarch/strpbrk.S.  */
   IFUNC_IMPL (i, name, strpbrk,
@@ -433,15 +431,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 # endif
 	      )
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/strlen.S.  */
   IFUNC_IMPL (i, name, strlen,
 	      IFUNC_IMPL_ADD (array, i, strlen, HAS_CPU_FEATURE (SSE2),
 			      __strlen_sse2_bsf)
 	      IFUNC_IMPL_ADD (array, i, strlen, HAS_CPU_FEATURE (SSE2),
 			      __strlen_sse2)
-	      IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_ia32))
-#endif
+	      IFUNC_IMPL_ADD (array, i, strlen, HAS_I586, __strlen_i586)
+	      IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_i486))
 
   /* Support sysdeps/i386/i686/multiarch/strncmp.S.  */
   IFUNC_IMPL (i, name, strncmp,
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/multiarch/rtld-strlen.S
similarity index 59%
rename from sysdeps/i386/i686/multiarch/strnlen.S
rename to sysdeps/i386/multiarch/rtld-strlen.S
index baf21fc..9ee1dbc 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/multiarch/rtld-strlen.S
@@ -1,7 +1,5 @@
-/* Multiple versions of strnlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* strlen 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
@@ -18,20 +16,4 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
-
-weak_alias(__strnlen, strnlen)
-#endif
+#include <sysdeps/i386/strlen.S>
diff --git a/sysdeps/i386/i686/multiarch/rtld-strnlen.c b/sysdeps/i386/multiarch/rtld-strnlen.c
similarity index 100%
rename from sysdeps/i386/i686/multiarch/rtld-strnlen.c
rename to sysdeps/i386/multiarch/rtld-strnlen.c
diff --git a/sysdeps/i386/multiarch/strlen-i486.S b/sysdeps/i386/multiarch/strlen-i486.S
new file mode 100644
index 0000000..42d0a55
--- /dev/null
+++ b/sysdeps/i386/multiarch/strlen-i486.S
@@ -0,0 +1,4 @@
+#define strlen __strlen_i486
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/i486/strlen.S>
diff --git a/sysdeps/i386/multiarch/strlen-i586.S b/sysdeps/i386/multiarch/strlen-i586.S
new file mode 100644
index 0000000..2f53490
--- /dev/null
+++ b/sysdeps/i386/multiarch/strlen-i586.S
@@ -0,0 +1,6 @@
+#define strlen __strlen_i586
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/i586/strlen.S>
diff --git a/sysdeps/i386/i686/multiarch/strlen-sse2-bsf.S b/sysdeps/i386/multiarch/strlen-sse2-bsf.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strlen-sse2-bsf.S
rename to sysdeps/i386/multiarch/strlen-sse2-bsf.S
diff --git a/sysdeps/i386/multiarch/strlen.c b/sysdeps/i386/multiarch/strlen.c
new file mode 100644
index 0000000..99df89d
--- /dev/null
+++ b/sysdeps/i386/multiarch/strlen.c
@@ -0,0 +1,58 @@
+/* Multiple versions of strlen.
+   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 defined SHARED && IS_IN (libc)
+/* Redefine strlen so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strlen
+# define strlen __redirect_strlen
+# include <string.h>
+# undef strlen
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strlen) __strlen_i486 attribute_hidden;
+extern __typeof (__redirect_strlen) __strlen_i586 attribute_hidden;
+extern __typeof (__redirect_strlen) __strlen_sse2 attribute_hidden;
+extern __typeof (__redirect_strlen) __strlen_sse2_bsf attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strlen) strlen;
+extern void *strlen_ifunc (void) __asm__ ("strlen");
+
+void *
+strlen_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Slow_BSF))
+	return __strlen_sse2;
+      else
+	return __strlen_sse2_bsf;
+    }
+
+  if (USE_I586)
+    return __strlen_i586;
+  else
+    return __strlen_i486;
+}
+__asm__ (".type strlen, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/multiarch/strnlen-i386.c b/sysdeps/i386/multiarch/strnlen-i386.c
new file mode 100644
index 0000000..dd4dbda
--- /dev/null
+++ b/sysdeps/i386/multiarch/strnlen-i386.c
@@ -0,0 +1,10 @@
+#define STRNLEN  __strnlen_i386
+#ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name)  \
+    __hidden_ver1 (__strnlen_i386, __GI_strnlen, __strnlen_i386); \
+    strong_alias (__strnlen_i386, __strnlen_i386_1); \
+    __hidden_ver1 (__strnlen_i386_1, __GI___strnlen, __strnlen_i386_1);
+#endif
+
+#include "string/strnlen.c"
diff --git a/sysdeps/i386/i686/multiarch/strnlen-sse2.S b/sysdeps/i386/multiarch/strnlen-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strnlen-sse2.S
rename to sysdeps/i386/multiarch/strnlen-sse2.S
diff --git a/sysdeps/i386/multiarch/strnlen.c b/sysdeps/i386/multiarch/strnlen.c
new file mode 100644
index 0000000..3e97c9e
--- /dev/null
+++ b/sysdeps/i386/multiarch/strnlen.c
@@ -0,0 +1,50 @@
+/* Multiple versions of strnlen.
+   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 strnlen so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strnlen
+# define strnlen __redirect_strnlen
+# include <string.h>
+# undef strnlen
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strnlen) __strnlen_i386 attribute_hidden;
+extern __typeof (__redirect_strnlen) __strnlen_sse2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strnlen) __strnlen;
+extern void *strnlen_ifunc (void) __asm__ ("__strnlen");
+
+void *
+strnlen_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    return __strnlen_sse2;
+
+  return __strnlen_i386;
+}
+__asm__ (".type __strnlen, %gnu_indirect_function");
+
+weak_alias (__strnlen, strnlen)
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=498aeee3f44db0c0ba51d8682d60d4c56598fc44

commit 498aeee3f44db0c0ba51d8682d60d4c56598fc44
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Aug 24 11:41:57 2015 -0700

    Add i386 strrchr multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 8f8e450..2733c2a 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,6 +1,5 @@
 ifeq ($(subdir),string)
 sysdep_routines += strlen-sse2 strlen-sse2-bsf \
-		   strrchr-sse2 strrchr-sse2-bsf \
 		   strnlen-sse2 strnlen-c
 ifeq (yes,$(config-cflags-sse4))
 sysdep_routines += strspn-c
diff --git a/sysdeps/i386/i686/multiarch/strrchr.S b/sysdeps/i386/i686/multiarch/strrchr.S
deleted file mode 100644
index 6aa3321..0000000
--- a/sysdeps/i386/i686/multiarch/strrchr.S
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Multiple versions of strrchr
-   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 IS_IN (libc)
-	.text
-ENTRY(strrchr)
-	.type	strrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strrchr_sse2_bsf)
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strrchr_sse2)
-2:	ret
-END(strrchr)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __strrchr_ia32, @function; \
-	.globl __strrchr_ia32; \
-	.p2align 4; \
-	__strrchr_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __strrchr_ia32, .-__strrchr_ia32
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_strrchr; __GI_strrchr = __strrchr_ia32
-#endif
-
-#include "../../strrchr.S"
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 4641262..49bdf25 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -35,7 +35,8 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   strcat-i486 strcat-sse2 strcat-ssse3 \
 		   strncat-i386 strncat-sse2 strncat-ssse3 \
 		   strchr-i386 strchr-i586 strchr-sse2-bsf strchr-sse2 \
-		   strcspn-i386 strpbrk-i386
+		   strcspn-i386 strpbrk-i386 \
+		   strrchr-i386 strrchr-sse2-bsf strrchr-sse2
 ifeq (yes,$(config-cflags-sse4))
 sysdep_routines += varshift strcspn-sse4 strpbrk-sse4
 CFLAGS-varshift.c += -msse4
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 7d63013..a464d26 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -306,15 +306,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strpbrk_sse42)
 	      IFUNC_IMPL_ADD (array, i, strpbrk, 1, __strpbrk_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/strrchr.S.  */
   IFUNC_IMPL (i, name, strrchr,
 	      IFUNC_IMPL_ADD (array, i, strrchr, HAS_CPU_FEATURE (SSE2),
 			      __strrchr_sse2_bsf)
 	      IFUNC_IMPL_ADD (array, i, strrchr, HAS_CPU_FEATURE (SSE2),
 			      __strrchr_sse2)
-	      IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_ia32))
+	      IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strspn.S.  */
   IFUNC_IMPL (i, name, strspn,
 	      IFUNC_IMPL_ADD (array, i, strspn, HAS_CPU_FEATURE (SSE4_2),
diff --git a/sysdeps/i386/multiarch/strrchr-i386.S b/sysdeps/i386/multiarch/strrchr-i386.S
new file mode 100644
index 0000000..a7941e6
--- /dev/null
+++ b/sysdeps/i386/multiarch/strrchr-i386.S
@@ -0,0 +1,14 @@
+#define strrchr __strrchr_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/strrchr.S>
+
+#ifdef SHARED
+	.globl __GI_strrchr
+	.hidden __GI_strrchr
+	__GI_strrchr = __strrchr_i386
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strrchr-sse2-bsf.S b/sysdeps/i386/multiarch/strrchr-sse2-bsf.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strrchr-sse2-bsf.S
rename to sysdeps/i386/multiarch/strrchr-sse2-bsf.S
diff --git a/sysdeps/i386/i686/multiarch/strrchr-sse2.S b/sysdeps/i386/multiarch/strrchr-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strrchr-sse2.S
rename to sysdeps/i386/multiarch/strrchr-sse2.S
diff --git a/sysdeps/i386/multiarch/strrchr.c b/sysdeps/i386/multiarch/strrchr.c
new file mode 100644
index 0000000..995e007
--- /dev/null
+++ b/sysdeps/i386/multiarch/strrchr.c
@@ -0,0 +1,55 @@
+/* Multiple versions of strrchr
+   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 strrchr so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strrchr
+# define strrchr __redirect_strrchr
+# include <string.h>
+# undef strrchr
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strrchr) __strrchr_i386 attribute_hidden;
+extern __typeof (__redirect_strrchr) __strrchr_sse2 attribute_hidden;
+extern __typeof (__redirect_strrchr) __strrchr_sse2_bsf attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strrchr) strrchr;
+extern void *strrchr_ifunc (void) __asm__ ("strrchr");
+
+void *
+strrchr_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Slow_BSF))
+	return __strrchr_sse2;
+      else
+	return __strrchr_sse2_bsf;
+    }
+
+  return __strrchr_i386;
+}
+__asm__ (".type strrchr, %gnu_indirect_function");
+weak_alias (strrchr, rindex)
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b4b31a2d23ced811c0bfb4e8f0bafdf3afce8326

commit b4b31a2d23ced811c0bfb4e8f0bafdf3afce8326
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Aug 24 10:46:29 2015 -0700

    Add i386 strcspn family multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 788dccb..8f8e450 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,13 +1,9 @@
 ifeq ($(subdir),string)
-sysdep_routines += varshift \
-		   strlen-sse2 strlen-sse2-bsf \
+sysdep_routines += strlen-sse2 strlen-sse2-bsf \
 		   strrchr-sse2 strrchr-sse2-bsf \
 		   strnlen-sse2 strnlen-c
 ifeq (yes,$(config-cflags-sse4))
-sysdep_routines += strcspn-c strpbrk-c strspn-c
-CFLAGS-varshift.c += -msse4
-CFLAGS-strcspn-c.c += -msse4
-CFLAGS-strpbrk-c.c += -msse4
+sysdep_routines += strspn-c
 CFLAGS-strspn-c.c += -msse4
 endif
 endif
diff --git a/sysdeps/i386/i686/multiarch/strcspn.S b/sysdeps/i386/i686/multiarch/strcspn.S
deleted file mode 100644
index b669b97..0000000
--- a/sysdeps/i386/i686/multiarch/strcspn.S
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Multiple versions of strcspn
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2009-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 <config.h>
-
-#ifdef HAVE_SSE4_SUPPORT
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#ifdef USE_AS_STRPBRK
-#define STRCSPN_SSE42	__strpbrk_sse42
-#define STRCSPN_IA32	__strpbrk_ia32
-#define __GI_STRCSPN	__GI_strpbrk
-#else
-#ifndef STRCSPN
-#define STRCSPN		strcspn
-#define STRCSPN_SSE42	__strcspn_sse42
-#define STRCSPN_IA32	__strcspn_ia32
-#define __GI_STRCSPN	__GI_strcspn
-#endif
-#endif
-
-/* Define multiple versions only for the definition in libc.  Don't
-   define multiple versions for strpbrk in static library since we
-   need strpbrk before the initialization happened.  */
-#if (defined SHARED || !defined USE_AS_STRPBRK) && IS_IN (libc)
-	.text
-ENTRY(STRCSPN)
-	.type	STRCSPN, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (STRCSPN_IA32)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCSPN_SSE42)
-2:	ret
-END(STRCSPN)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type STRCSPN_IA32, @function; \
-	.globl STRCSPN_IA32; \
-	.p2align 4; \
-	STRCSPN_IA32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size STRCSPN_IA32, .-STRCSPN_IA32
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_STRCSPN; __GI_STRCSPN = STRCSPN_IA32
-#endif
-
-#endif /* HAVE_SSE4_SUPPORT */
-
-#ifdef USE_AS_STRPBRK
-#include "../../strpbrk.S"
-#else
-#include "../../strcspn.S"
-#endif
diff --git a/sysdeps/i386/i686/multiarch/strpbrk.S b/sysdeps/i386/i686/multiarch/strpbrk.S
deleted file mode 100644
index 7201d63..0000000
--- a/sysdeps/i386/i686/multiarch/strpbrk.S
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Multiple versions of strpbrk
-   All versions must be listed in ifunc-impl-list.c.  */
-#define STRCSPN strpbrk
-#define USE_AS_STRPBRK
-#include "strcspn.S"
diff --git a/sysdeps/i386/i686/multiarch/varshift.h b/sysdeps/i386/i686/multiarch/varshift.h
deleted file mode 100644
index 7c72c70..0000000
--- a/sysdeps/i386/i686/multiarch/varshift.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/x86_64/multiarch/varshift.h>
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 20c8166..4641262 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -34,7 +34,14 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   strncmp-i386 strncmp-ssse3 strncmp-sse4 \
 		   strcat-i486 strcat-sse2 strcat-ssse3 \
 		   strncat-i386 strncat-sse2 strncat-ssse3 \
-		   strchr-i386 strchr-i586 strchr-sse2-bsf strchr-sse2
+		   strchr-i386 strchr-i586 strchr-sse2-bsf strchr-sse2 \
+		   strcspn-i386 strpbrk-i386
+ifeq (yes,$(config-cflags-sse4))
+sysdep_routines += varshift strcspn-sse4 strpbrk-sse4
+CFLAGS-varshift.c += -msse4
+CFLAGS-strcspn-sse4.c += -msse4
+CFLAGS-strpbrk-sse4.c += -msse4
+endif
 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 3f81ed6..7d63013 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -246,13 +246,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 #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),
 			      __strcspn_sse42)
-	      IFUNC_IMPL_ADD (array, i, strcspn, 1, __strcspn_ia32))
-#endif
+	      IFUNC_IMPL_ADD (array, i, strcspn, 1, __strcspn_i386))
 
   /* Support sysdeps/i386/i686/multiarch/strncase.S.  */
   IFUNC_IMPL (i, name, strncasecmp,
@@ -300,13 +298,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strnlen, HAS_CPU_FEATURE (SSE2),
 			      __strnlen_sse2)
 	      IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/strpbrk.S.  */
   IFUNC_IMPL (i, name, strpbrk,
 	      IFUNC_IMPL_ADD (array, i, strpbrk, HAS_CPU_FEATURE (SSE4_2),
 			      __strpbrk_sse42)
-	      IFUNC_IMPL_ADD (array, i, strpbrk, 1, __strpbrk_ia32))
+	      IFUNC_IMPL_ADD (array, i, strpbrk, 1, __strpbrk_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strrchr.S.  */
   IFUNC_IMPL (i, name, strrchr,
 	      IFUNC_IMPL_ADD (array, i, strrchr, HAS_CPU_FEATURE (SSE2),
diff --git a/sysdeps/i386/multiarch/strcspn-i386.S b/sysdeps/i386/multiarch/strcspn-i386.S
new file mode 100644
index 0000000..fd8d97b
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcspn-i386.S
@@ -0,0 +1,8 @@
+#define strcspn __strcspn_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/strcspn.S>
+
+	.globl __GI_strcspn
+	.hidden __GI_strcspn
+	__GI_strcspn = __strcspn_i386
diff --git a/sysdeps/i386/i686/multiarch/strcspn-c.c b/sysdeps/i386/multiarch/strcspn-sse4.c
similarity index 55%
rename from sysdeps/i386/i686/multiarch/strcspn-c.c
rename to sysdeps/i386/multiarch/strcspn-sse4.c
index 6d61e19..920da4d 100644
--- a/sysdeps/i386/i686/multiarch/strcspn-c.c
+++ b/sysdeps/i386/multiarch/strcspn-sse4.c
@@ -1,2 +1,2 @@
-#define __strcspn_sse2 __strcspn_ia32
+#define __strcspn_sse2 __strcspn_i386
 #include <sysdeps/x86_64/multiarch/strcspn-c.c>
diff --git a/sysdeps/i386/multiarch/strcspn.c b/sysdeps/i386/multiarch/strcspn.c
new file mode 100644
index 0000000..6d8674b
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcspn.c
@@ -0,0 +1,49 @@
+/* Multiple versions of strcspn.
+   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_strcspn
+/* Redefine strcspn so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strcspn
+# define strcspn __redirect_strcspn
+# include <string.h>
+# undef strcspn
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strcspn) __strcspn_i386 attribute_hidden;
+extern __typeof (__redirect_strcspn) __strcspn_sse42 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strcspn) strcspn;
+extern void *strcspn_ifunc (void) __asm__ ("strcspn");
+
+void *
+strcspn_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE4_2))
+    return __strcspn_sse42;
+
+  return __strcspn_i386;
+}
+__asm__ (".type strcspn, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/multiarch/strpbrk-i386.S b/sysdeps/i386/multiarch/strpbrk-i386.S
new file mode 100644
index 0000000..94e9133
--- /dev/null
+++ b/sysdeps/i386/multiarch/strpbrk-i386.S
@@ -0,0 +1,13 @@
+#ifdef SHARED
+# define strpbrk __strpbrk_i386
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+#endif
+
+#include <sysdeps/i386/strpbrk.S>
+
+#ifdef SHARED
+	.globl __GI_strpbrk
+	.hidden __GI_strpbrk
+	__GI_strpbrk = __strpbrk_i386
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strpbrk-c.c b/sysdeps/i386/multiarch/strpbrk-sse4.c
similarity index 55%
rename from sysdeps/i386/i686/multiarch/strpbrk-c.c
rename to sysdeps/i386/multiarch/strpbrk-sse4.c
index 5db6205..a63afc1 100644
--- a/sysdeps/i386/i686/multiarch/strpbrk-c.c
+++ b/sysdeps/i386/multiarch/strpbrk-sse4.c
@@ -1,2 +1,2 @@
-#define __strpbrk_sse2 __strpbrk_ia32
+#define __strpbrk_sse2 __strpbrk_i386
 #include <sysdeps/x86_64/multiarch/strpbrk-c.c>
diff --git a/sysdeps/i386/multiarch/strpbrk.c b/sysdeps/i386/multiarch/strpbrk.c
new file mode 100644
index 0000000..b857135
--- /dev/null
+++ b/sysdeps/i386/multiarch/strpbrk.c
@@ -0,0 +1,51 @@
+/* Multiple versions of strpbrk.
+   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.  Don't
+   define multiple versions for strpbrk in static library since we
+   need strpbrk before the initialization happened.  */
+#if defined SHARED && IS_IN (libc)
+# define _HAVE_STRING_ARCH_strpbrk
+/* Redefine strpbrk so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strpbrk
+# define strpbrk __redirect_strpbrk
+# include <string.h>
+# undef strpbrk
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strpbrk) __strpbrk_i386 attribute_hidden;
+extern __typeof (__redirect_strpbrk) __strpbrk_sse42 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strpbrk) strpbrk;
+extern void *strpbrk_ifunc (void) __asm__ ("strpbrk");
+
+void *
+strpbrk_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE4_2))
+    return __strpbrk_sse42;
+
+  return __strpbrk_i386;
+}
+__asm__ (".type strpbrk, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/i686/multiarch/varshift.c b/sysdeps/i386/multiarch/varshift.c
similarity index 100%
rename from sysdeps/i386/i686/multiarch/varshift.c
rename to sysdeps/i386/multiarch/varshift.c

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=e28277c7d962889afe1cb065970eba9e0e08454a

commit e28277c7d962889afe1cb065970eba9e0e08454a
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Sun Aug 23 12:47:24 2015 -0700

    Add i386 strchr multiarch functions

diff --git a/sysdeps/i386/i586/multiarch/rtld-strchr.S b/sysdeps/i386/i586/multiarch/rtld-strchr.S
new file mode 100644
index 0000000..a26da1c
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/rtld-strchr.S
@@ -0,0 +1,19 @@
+/* strchr 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/strchr.S>
diff --git a/sysdeps/i386/i586/multiarch/strchr-i386.S b/sysdeps/i386/i586/multiarch/strchr-i386.S
new file mode 100644
index 0000000..74850fa
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strchr-i386.S
@@ -0,0 +1,8 @@
+#define strchr __strchr_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/strchr.S>
diff --git a/sysdeps/i386/i586/multiarch/strchr-i586.S b/sysdeps/i386/i586/multiarch/strchr-i586.S
new file mode 100644
index 0000000..48e71aa
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strchr-i586.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/strchr-i586.S>
+
+#ifdef SHARED
+	.globl __GI_strchr
+	.hidden __GI_strchr
+	__GI_strchr = __strchr_i586
+#endif
diff --git a/sysdeps/i386/i586/multiarch/strchr.c b/sysdeps/i386/i586/multiarch/strchr.c
new file mode 100644
index 0000000..61c2f14
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strchr.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/strchr.c>
diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 830c77d..788dccb 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,7 +1,7 @@
 ifeq ($(subdir),string)
 sysdep_routines += varshift \
 		   strlen-sse2 strlen-sse2-bsf \
-		   strchr-sse2 strrchr-sse2 strchr-sse2-bsf strrchr-sse2-bsf \
+		   strrchr-sse2 strrchr-sse2-bsf \
 		   strnlen-sse2 strnlen-c
 ifeq (yes,$(config-cflags-sse4))
 sysdep_routines += strcspn-c strpbrk-c strspn-c
diff --git a/sysdeps/i386/i686/multiarch/strchr-i586.S b/sysdeps/i386/i686/multiarch/strchr-i586.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/strchr-i586.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/strchr.S b/sysdeps/i386/i686/multiarch/strchr.S
deleted file mode 100644
index 6b46565..0000000
--- a/sysdeps/i386/i686/multiarch/strchr.S
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Multiple versions of strchr
-   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 IS_IN (libc)
-	.text
-ENTRY(strchr)
-	.type	strchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strchr_sse2_bsf)
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strchr_sse2)
-2:	ret
-END(strchr)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __strchr_ia32, @function; \
-	.globl __strchr_ia32; \
-	.p2align 4; \
-	__strchr_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __strchr_ia32, .-__strchr_ia32
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_strchr; __GI_strchr = __strchr_ia32
-#endif
-
-#include "../../i586/strchr.S"
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index ac8ff80..20c8166 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -33,7 +33,8 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   strncase_l-ssse3 \
 		   strncmp-i386 strncmp-ssse3 strncmp-sse4 \
 		   strcat-i486 strcat-sse2 strcat-ssse3 \
-		   strncat-i386 strncat-sse2 strncat-ssse3
+		   strncat-i386 strncat-sse2 strncat-ssse3 \
+		   strchr-i386 strchr-i586 strchr-sse2-bsf strchr-sse2
 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 c689e94..3f81ed6 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -214,15 +214,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strcat_sse2)
 	      IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_i486))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/strchr.S.  */
   IFUNC_IMPL (i, name, strchr,
 	      IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2),
 			      __strchr_sse2_bsf)
 	      IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2),
 			      __strchr_sse2)
-	      IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_ia32))
-#endif
+	      IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_i386))
 
   /* Support sysdeps/i386/i686/multiarch/strcmp.S.  */
   IFUNC_IMPL (i, name, strcmp,
diff --git a/sysdeps/i386/multiarch/rtld-strchr.S b/sysdeps/i386/multiarch/rtld-strchr.S
new file mode 100644
index 0000000..a032fdb
--- /dev/null
+++ b/sysdeps/i386/multiarch/rtld-strchr.S
@@ -0,0 +1,19 @@
+/* strchr 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/strchr.S>
diff --git a/sysdeps/i386/multiarch/strchr-i386.S b/sysdeps/i386/multiarch/strchr-i386.S
new file mode 100644
index 0000000..aff0f7a
--- /dev/null
+++ b/sysdeps/i386/multiarch/strchr-i386.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/i586/multiarch/strchr-i386.S>
+
+#ifdef SHARED
+	.globl __GI_strchr
+	.hidden __GI_strchr
+	__GI_strchr = __strchr_i386
+#endif
diff --git a/sysdeps/i386/multiarch/strchr-i586.S b/sysdeps/i386/multiarch/strchr-i586.S
new file mode 100644
index 0000000..b4327f4
--- /dev/null
+++ b/sysdeps/i386/multiarch/strchr-i586.S
@@ -0,0 +1,8 @@
+#define strchr __strchr_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/strchr.S>
diff --git a/sysdeps/i386/i686/multiarch/strchr-sse2-bsf.S b/sysdeps/i386/multiarch/strchr-sse2-bsf.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strchr-sse2-bsf.S
rename to sysdeps/i386/multiarch/strchr-sse2-bsf.S
diff --git a/sysdeps/i386/i686/multiarch/strchr-sse2.S b/sysdeps/i386/multiarch/strchr-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strchr-sse2.S
rename to sysdeps/i386/multiarch/strchr-sse2.S
diff --git a/sysdeps/i386/multiarch/strchr.c b/sysdeps/i386/multiarch/strchr.c
new file mode 100644
index 0000000..015b51c
--- /dev/null
+++ b/sysdeps/i386/multiarch/strchr.c
@@ -0,0 +1,60 @@
+/* Multiple versions of strchr
+   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_strchr
+/* Redefine strchr so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strchr
+# define strchr __redirect_strchr
+# include <string.h>
+# undef strchr
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strchr) __strchr_i386 attribute_hidden;
+extern __typeof (__redirect_strchr) __strchr_i586 attribute_hidden;
+extern __typeof (__redirect_strchr) __strchr_sse2 attribute_hidden;
+extern __typeof (__redirect_strchr) __strchr_sse2_bsf attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strchr) strchr;
+extern void *strchr_ifunc (void) __asm__ ("strchr");
+
+void *
+strchr_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Slow_BSF))
+	return __strchr_sse2;
+      else
+	return __strchr_sse2_bsf;
+    }
+
+  if (USE_I586)
+    return __strchr_i586;
+  else
+    return __strchr_i386;
+}
+__asm__ (".type strchr, %gnu_indirect_function");
+weak_alias (strchr, index)
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=360413631a2a2bbf086bac17a783b6c4df490d52

commit 360413631a2a2bbf086bac17a783b6c4df490d52
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Aug 20 15:20:58 2015 -0700

    Add i386 strcat multiarch functions

diff --git a/sysdeps/i386/i486/multiarch/strcat-i486.S b/sysdeps/i386/i486/multiarch/strcat-i486.S
new file mode 100644
index 0000000..1b74e55
--- /dev/null
+++ b/sysdeps/i386/i486/multiarch/strcat-i486.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/strcat-i486.S>
+
+#ifdef SHARED
+	.globl __GI_strcat
+	.hidden __GI_strcat
+	__GI_strcat = __strcat_i486
+#endif
diff --git a/sysdeps/i386/i486/multiarch/strcat.c b/sysdeps/i386/i486/multiarch/strcat.c
new file mode 100644
index 0000000..b0ad766
--- /dev/null
+++ b/sysdeps/i386/i486/multiarch/strcat.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/strcat.c>
diff --git a/sysdeps/i386/i586/multiarch/Implies b/sysdeps/i386/i586/multiarch/Implies
new file mode 100644
index 0000000..05dd74e
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/Implies
@@ -0,0 +1,2 @@
+# Code optimized for i486 is better than simple i386 code.
+i386/i486/multiarch
diff --git a/sysdeps/i386/i686/multiarch/Implies b/sysdeps/i386/i686/multiarch/Implies
new file mode 100644
index 0000000..17cc700
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/Implies
@@ -0,0 +1,4 @@
+# Due to the reordering and the other nifty extensions in the i686 it is
+# not really good to use heavily i586 optimized code on a i686.  It's
+# better to use i486/i386 code.
+i386/i486/multiarch
diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index d38a051..830c77d 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,8 +1,6 @@
 ifeq ($(subdir),string)
 sysdep_routines += varshift \
 		   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
 ifeq (yes,$(config-cflags-sse4))
diff --git a/sysdeps/i386/i686/multiarch/strcat.S b/sysdeps/i386/i686/multiarch/strcat.S
deleted file mode 100644
index 45d84cd..0000000
--- a/sysdeps/i386/i686/multiarch/strcat.S
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Multiple versions of strcat
-   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>
-
-#ifndef USE_AS_STRNCAT
-# ifndef STRCAT
-#  define STRCAT strcat
-# endif
-#endif
-
-#ifdef USE_AS_STRNCAT
-# define STRCAT_SSSE3	__strncat_ssse3
-# define STRCAT_SSE2		__strncat_sse2
-# define STRCAT_IA32		__strncat_ia32
-# define __GI_STRCAT		__GI_strncat
-#else
-# define STRCAT_SSSE3	__strcat_ssse3
-# define STRCAT_SSE2		__strcat_sse2
-# define STRCAT_IA32		__strcat_ia32
-# define __GI_STRCAT		__GI_strcat
-#endif
-
-
-/* Define multiple versions only for the definition in libc.  Don't
-   define multiple versions for strncat in static library since we
-   need strncat before the initialization happened.  */
-#if IS_IN (libc)
-
-	.text
-ENTRY(STRCAT)
-	.type	STRCAT, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (STRCAT_IA32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCAT_SSE2)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCAT_SSSE3)
-2:	ret
-END(STRCAT)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type STRCAT_IA32, @function; \
-	.align 16; \
-	.globl STRCAT_IA32; \
-	.hidden STRCAT_IA32; \
-	STRCAT_IA32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size STRCAT_IA32, .-STRCAT_IA32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* It doesn't make sense to send libc-internal strcat 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_STRCAT; __GI_STRCAT = STRCAT_IA32
-#  undef libc_hidden_def
-#  define libc_hidden_def(name) \
-	.globl __GI___STRCAT; __GI___STRCAT = STRCAT_IA32
-
-# endif
-#endif
-
-#ifndef USE_AS_STRNCAT
-# include "../../i486/strcat.S"
-#endif
diff --git a/sysdeps/i386/i686/multiarch/strncat.S b/sysdeps/i386/i686/multiarch/strncat.S
deleted file mode 100644
index 5c1bf41..0000000
--- a/sysdeps/i386/i686/multiarch/strncat.S
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Multiple versions of strncat
-   All versions must be listed in ifunc-impl-list.c.  */
-#define STRCAT strncat
-#define USE_AS_STRNCAT
-#include "strcat.S"
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 78a99a7..ac8ff80 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -31,7 +31,9 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   strcasecmp_l-ssse3 \
 		   strncase-i386 strncase_l-i386 strncase_l-sse4 \
 		   strncase_l-ssse3 \
-		   strncmp-i386 strncmp-ssse3 strncmp-sse4 
+		   strncmp-i386 strncmp-ssse3 strncmp-sse4 \
+		   strcat-i486 strcat-sse2 strcat-ssse3 \
+		   strncat-i386 strncat-sse2 strncat-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 bddc9e7..c689e94 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -206,15 +206,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1,
 			      __strcasecmp_l_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/strcat.S.  */
   IFUNC_IMPL (i, name, strcat,
 	      IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSSE3),
 			      __strcat_ssse3)
 	      IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSE2),
 			      __strcat_sse2)
-	      IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_ia32))
+	      IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_i486))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strchr.S.  */
   IFUNC_IMPL (i, name, strchr,
 	      IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2),
diff --git a/sysdeps/i386/multiarch/strcat-i486.S b/sysdeps/i386/multiarch/strcat-i486.S
new file mode 100644
index 0000000..cfb6610
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcat-i486.S
@@ -0,0 +1,4 @@
+#define strcat __strcat_i486
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/i486/strcat.S>
diff --git a/sysdeps/i386/i686/multiarch/strcat-sse2.S b/sysdeps/i386/multiarch/strcat-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strcat-sse2.S
rename to sysdeps/i386/multiarch/strcat-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/strcat-ssse3.S b/sysdeps/i386/multiarch/strcat-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strcat-ssse3.S
rename to sysdeps/i386/multiarch/strcat-ssse3.S
diff --git a/sysdeps/i386/multiarch/strcat.c b/sysdeps/i386/multiarch/strcat.c
new file mode 100644
index 0000000..17a2af5
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcat.c
@@ -0,0 +1,51 @@
+/* Multiple versions of strcat.
+   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 strcat so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strcat
+# define strcat __redirect_strcat
+# include <string.h>
+# undef strcat
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strcat) __strcat_i486 attribute_hidden;
+extern __typeof (__redirect_strcat) __strcat_sse2 attribute_hidden;
+extern __typeof (__redirect_strcat) __strcat_ssse3 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strcat) strcat;
+extern void *strcat_ifunc (void) __asm__ ("strcat");
+
+void *
+strcat_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    return __strcat_ssse3;
+  else if (HAS_CPU_FEATURE (SSE2))
+    return __strcat_sse2;
+
+  return __strcat_i486;
+}
+__asm__ (".type strcat, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strlen-sse2.S b/sysdeps/i386/multiarch/strlen-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strlen-sse2.S
rename to sysdeps/i386/multiarch/strlen-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/strncat-c.c b/sysdeps/i386/multiarch/strncat-i386.c
similarity index 52%
rename from sysdeps/i386/i686/multiarch/strncat-c.c
rename to sysdeps/i386/multiarch/strncat-i386.c
index 132a000..0f22fbc 100644
--- a/sysdeps/i386/i686/multiarch/strncat-c.c
+++ b/sysdeps/i386/multiarch/strncat-i386.c
@@ -1,8 +1,8 @@
-#define STRNCAT __strncat_ia32
+#define STRNCAT __strncat_i386
 #ifdef SHARED
 #undef libc_hidden_def
 #define libc_hidden_def(name) \
-  __hidden_ver1 (__strncat_ia32, __GI___strncat, __strncat_ia32);
+  __hidden_ver1 (__strncat_i386, __GI___strncat, __strncat_i386);
 #endif
 
 #include "string/strncat.c"
diff --git a/sysdeps/i386/i686/multiarch/strncat-sse2.S b/sysdeps/i386/multiarch/strncat-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strncat-sse2.S
rename to sysdeps/i386/multiarch/strncat-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/strncat-ssse3.S b/sysdeps/i386/multiarch/strncat-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strncat-ssse3.S
rename to sysdeps/i386/multiarch/strncat-ssse3.S
diff --git a/sysdeps/i386/multiarch/strncat.c b/sysdeps/i386/multiarch/strncat.c
new file mode 100644
index 0000000..7ab3e38
--- /dev/null
+++ b/sysdeps/i386/multiarch/strncat.c
@@ -0,0 +1,54 @@
+/* Multiple versions of strncat.
+   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.  Don't
+   define multiple versions for strncat in static library since we
+   need strncat before the initialization happened.  */
+#if defined  SHARED && IS_IN (libc)
+# define _HAVE_STRING_ARCH_strncat
+/* Redefine strncat so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strncat
+# define strncat __redirect_strncat
+# include <string.h>
+# undef strncat
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strncat) __strncat_i386 attribute_hidden;
+extern __typeof (__redirect_strncat) __strncat_sse2 attribute_hidden;
+extern __typeof (__redirect_strncat) __strncat_ssse3 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strncat) strncat;
+extern void *strncat_ifunc (void) __asm__ ("strncat");
+
+void *
+strncat_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    return __strncat_ssse3;
+  else if (HAS_CPU_FEATURE (SSE2))
+    return __strncat_sse2;
+
+  return __strncat_i386;
+}
+__asm__ (".type strncat, %gnu_indirect_function");
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c8734f99b73abd63243c687f1c71a16835a55360

commit c8734f99b73abd63243c687f1c71a16835a55360
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Aug 20 13:57:22 2015 -0700

    Add i386 strcmp family multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 2a14fe8..d38a051 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,15 +1,10 @@
 ifeq ($(subdir),string)
-sysdep_routines += strcmp-ssse3 \
-		   strcmp-sse4 strncmp-c strncmp-ssse3 strncmp-sse4 \
-		   varshift \
+sysdep_routines += varshift \
 		   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 \
-		   strcasecmp_l-c strcasecmp-c strcasecmp_l-ssse3 \
-		   strncase_l-c strncase-c strncase_l-ssse3 \
-		   strcasecmp_l-sse4 strncase_l-sse4
+		   strnlen-sse2 strnlen-c
 ifeq (yes,$(config-cflags-sse4))
 sysdep_routines += strcspn-c strpbrk-c strspn-c
 CFLAGS-varshift.c += -msse4
diff --git a/sysdeps/i386/i686/multiarch/rtld-strcmp.S b/sysdeps/i386/i686/multiarch/rtld-strcmp.S
new file mode 100644
index 0000000..103ab89
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/rtld-strcmp.S
@@ -0,0 +1,19 @@
+/* strcmp 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/i686/strcmp.S>
diff --git a/sysdeps/i386/i686/multiarch/strcasecmp.S b/sysdeps/i386/i686/multiarch/strcasecmp.S
deleted file mode 100644
index e4b3cf5..0000000
--- a/sysdeps/i386/i686/multiarch/strcasecmp.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Entry point for multi-version x86 strcasecmp.
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-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 <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY(__strcasecmp)
-	.type	__strcasecmp, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strcasecmp_ia32)
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strcasecmp_ssse3)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_SSE4_2)
-	jnz	2f
-	LOAD_FUNC_GOT_EAX (__strcasecmp_sse4_2)
-2:	ret
-END(__strcasecmp)
-
-weak_alias (__strcasecmp, strcasecmp)
diff --git a/sysdeps/i386/i686/multiarch/strcasecmp_l.S b/sysdeps/i386/i686/multiarch/strcasecmp_l.S
deleted file mode 100644
index 711c09b..0000000
--- a/sysdeps/i386/i686/multiarch/strcasecmp_l.S
+++ /dev/null
@@ -1,7 +0,0 @@
-/* Multiple versions of strcasecmp_l
-   All versions must be listed in ifunc-impl-list.c.  */
-#define STRCMP __strcasecmp_l
-#define USE_AS_STRCASECMP_L
-#include "strcmp.S"
-
-weak_alias (__strcasecmp_l, strcasecmp_l)
diff --git a/sysdeps/i386/i686/multiarch/strcmp-i386.c b/sysdeps/i386/i686/multiarch/strcmp-i386.c
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/strcmp-i386.c
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/strcmp-i686.S b/sysdeps/i386/i686/multiarch/strcmp-i686.S
new file mode 100644
index 0000000..e4616f8
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/strcmp-i686.S
@@ -0,0 +1,14 @@
+#ifdef SHARED
+# include <init-arch.h>
+# define strcmp __strcmp_i686
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+#endif
+
+#include <sysdeps/i386/i686/strcmp.S>
+
+#ifdef SHARED
+	.globl __GI_strcmp
+	.hidden __GI_strcmp
+	__GI_strcmp = __strcmp_i686
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strcmp.S b/sysdeps/i386/i686/multiarch/strcmp.S
deleted file mode 100644
index cad179d..0000000
--- a/sysdeps/i386/i686/multiarch/strcmp.S
+++ /dev/null
@@ -1,95 +0,0 @@
-/* Multiple versions of strcmp
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-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>
-
-#ifdef USE_AS_STRNCMP
-# define STRCMP			strncmp
-# define __GI_STRCMP		__GI_strncmp
-# define __STRCMP_IA32		__strncmp_ia32
-# define __STRCMP_SSSE3		__strncmp_ssse3
-# define __STRCMP_SSE4_2	__strncmp_sse4_2
-#elif defined USE_AS_STRCASECMP_L
-# define STRCMP			__strcasecmp_l
-# define __GI_STRCMP		__GI_strcasecmp_l
-# define __STRCMP_IA32		__strcasecmp_l_ia32
-# define __STRCMP_SSSE3		__strcasecmp_l_ssse3
-# define __STRCMP_SSE4_2	__strcasecmp_l_sse4_2
-#elif defined USE_AS_STRNCASECMP_L
-# define STRCMP			__strncasecmp_l
-# define __GI_STRCMP		__GI_strncasecmp_l
-# define __STRCMP_IA32		__strncasecmp_l_ia32
-# define __STRCMP_SSSE3		__strncasecmp_l_ssse3
-# define __STRCMP_SSE4_2	__strncasecmp_l_sse4_2
-#else
-# define STRCMP			strcmp
-# define __GI_STRCMP		__GI_strcmp
-# define __STRCMP_IA32		__strcmp_ia32
-# define __STRCMP_SSSE3		__strcmp_ssse3
-# define __STRCMP_SSE4_2	__strcmp_sse4_2
-#endif
-
-/* Define multiple versions only for the definition in libc.  Don't
-   define multiple versions for strncmp in static library since we
-   need strncmp before the initialization happened.  */
-#if (defined SHARED || !defined USE_AS_STRNCMP) && IS_IN (libc)
-	.text
-ENTRY(STRCMP)
-	.type	STRCMP, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__STRCMP_IA32)
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__STRCMP_SSSE3)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_SSE4_2)
-	jnz	2f
-	LOAD_FUNC_GOT_EAX (__STRCMP_SSE4_2)
-2:	ret
-END(STRCMP)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __STRCMP_IA32, @function; \
-	.p2align 4; \
-	.globl __STRCMP_IA32; \
-	.hidden __STRCMP_IA32; \
-	__STRCMP_IA32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __STRCMP_IA32, .-__STRCMP_IA32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_STRCMP; __GI_STRCMP = __STRCMP_IA32
-# endif
-#endif
-
-#if !defined USE_AS_STRNCMP && !defined USE_AS_STRCASECMP_L \
-    && !defined USE_AS_STRNCASECMP_L
-# include "../strcmp.S"
-#endif
diff --git a/sysdeps/i386/i686/multiarch/strcmp.c b/sysdeps/i386/i686/multiarch/strcmp.c
new file mode 100644
index 0000000..e693699
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/strcmp.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/strcmp.c>
diff --git a/sysdeps/i386/i686/multiarch/strncase.S b/sysdeps/i386/i686/multiarch/strncase.S
deleted file mode 100644
index 0cdbeff..0000000
--- a/sysdeps/i386/i686/multiarch/strncase.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Entry point for multi-version x86 strncasecmp.
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-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 <sysdep.h>
-#include <init-arch.h>
-
-	.text
-ENTRY(__strncasecmp)
-	.type	__strncasecmp, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strncasecmp_ia32)
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strncasecmp_ssse3)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	HAS_ARCH_FEATURE (Slow_SSE4_2)
-	jnz	2f
-	LOAD_FUNC_GOT_EAX (__strncasecmp_sse4_2)
-2:	ret
-END(__strncasecmp)
-
-weak_alias (__strncasecmp, strncasecmp)
diff --git a/sysdeps/i386/i686/multiarch/strncase_l.S b/sysdeps/i386/i686/multiarch/strncase_l.S
deleted file mode 100644
index 8a74ee8..0000000
--- a/sysdeps/i386/i686/multiarch/strncase_l.S
+++ /dev/null
@@ -1,7 +0,0 @@
-/* Multiple versions of strncasecmp_l
-   All versions must be listed in ifunc-impl-list.c.  */
-#define STRCMP __strncasecmp_l
-#define USE_AS_STRNCASECMP_L
-#include "strcmp.S"
-
-weak_alias (__strncasecmp_l, strncasecmp_l)
diff --git a/sysdeps/i386/i686/multiarch/strncmp.S b/sysdeps/i386/i686/multiarch/strncmp.S
deleted file mode 100644
index 150d478..0000000
--- a/sysdeps/i386/i686/multiarch/strncmp.S
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Multiple versions of strncmp
-   All versions must be listed in ifunc-impl-list.c.  */
-#define USE_AS_STRNCMP
-#define STRCMP	strncmp
-#include "strcmp.S"
diff --git a/sysdeps/i386/i686/rtld-strcmp.S b/sysdeps/i386/i686/rtld-strcmp.S
new file mode 100644
index 0000000..01f31f4
--- /dev/null
+++ b/sysdeps/i386/i686/rtld-strcmp.S
@@ -0,0 +1 @@
+#include <sysdeps/i386/i686/strcmp.S>
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 1518cae..78a99a7 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -25,7 +25,13 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   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
+		   strncpy-i386 strncpy-sse2 strncpy-ssse3 \
+		   strcmp-i386 strcmp-i686 strcmp-sse4 strcmp-ssse3 \
+		   strcasecmp-i386 strcasecmp_l-i386 strcasecmp_l-sse4 \
+		   strcasecmp_l-ssse3 \
+		   strncase-i386 strncase_l-i386 strncase_l-sse4 \
+		   strncase_l-ssse3 \
+		   strncmp-i386 strncmp-ssse3 strncmp-sse4 
 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 412f227..bddc9e7 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -185,7 +185,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 #endif
 	     )
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/strcasecmp.S.  */
   IFUNC_IMPL (i, name, strcasecmp,
 	      IFUNC_IMPL_ADD (array, i, strcasecmp,
@@ -194,7 +193,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strcasecmp,
 			      HAS_CPU_FEATURE (SSSE3),
 			      __strcasecmp_ssse3)
-	      IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_ia32))
+	      IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_i386))
 
   /* Support sysdeps/i386/i686/multiarch/strcasecmp_l.S.  */
   IFUNC_IMPL (i, name, strcasecmp_l,
@@ -205,8 +204,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      HAS_CPU_FEATURE (SSSE3),
 			      __strcasecmp_l_ssse3)
 	      IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1,
-			      __strcasecmp_l_ia32))
+			      __strcasecmp_l_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strcat.S.  */
   IFUNC_IMPL (i, name, strcat,
 	      IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSSE3),
@@ -222,6 +222,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2),
 			      __strchr_sse2)
 	      IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/strcmp.S.  */
   IFUNC_IMPL (i, name, strcmp,
@@ -229,8 +230,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strcmp_sse4_2)
 	      IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSSE3),
 			      __strcmp_ssse3)
-	      IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_ia32))
+	      IFUNC_IMPL_ADD (array, i, strcmp, HAS_I686, __strcmp_i686)
+#if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_i386)
 #endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/strcpy.S.  */
   IFUNC_IMPL (i, name, strcpy,
@@ -250,6 +254,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strcspn, HAS_CPU_FEATURE (SSE4_2),
 			      __strcspn_sse42)
 	      IFUNC_IMPL_ADD (array, i, strcspn, 1, __strcspn_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/strncase.S.  */
   IFUNC_IMPL (i, name, strncasecmp,
@@ -260,7 +265,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      HAS_CPU_FEATURE (SSSE3),
 			      __strncasecmp_ssse3)
 	      IFUNC_IMPL_ADD (array, i, strncasecmp, 1,
-			      __strncasecmp_ia32))
+			      __strncasecmp_i386))
 
   /* Support sysdeps/i386/i686/multiarch/strncase_l.S.  */
   IFUNC_IMPL (i, name, strncasecmp_l,
@@ -271,8 +276,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      HAS_CPU_FEATURE (SSSE3),
 			      __strncasecmp_l_ssse3)
 	      IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1,
-			      __strncasecmp_l_ia32))
+			      __strncasecmp_l_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strncat.S.  */
   IFUNC_IMPL (i, name, strncat,
 	      IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSSE3),
@@ -437,6 +443,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strlen, HAS_CPU_FEATURE (SSE2),
 			      __strlen_sse2)
 	      IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/strncmp.S.  */
   IFUNC_IMPL (i, name, strncmp,
@@ -444,8 +451,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strncmp_sse4_2)
 	      IFUNC_IMPL_ADD (array, i, strncmp, HAS_CPU_FEATURE (SSSE3),
 			      __strncmp_ssse3)
-	      IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_ia32))
-#endif
+	      IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_i386))
 #endif
 
   return i;
diff --git a/sysdeps/i386/multiarch/rtld-strcmp.c b/sysdeps/i386/multiarch/rtld-strcmp.c
new file mode 100644
index 0000000..78448ae
--- /dev/null
+++ b/sysdeps/i386/multiarch/rtld-strcmp.c
@@ -0,0 +1 @@
+#include "string/strcmp.c"
diff --git a/sysdeps/i386/i686/multiarch/strcasecmp-c.c b/sysdeps/i386/multiarch/strcasecmp-i386.c
similarity index 84%
rename from sysdeps/i386/i686/multiarch/strcasecmp-c.c
rename to sysdeps/i386/multiarch/strcasecmp-i386.c
index 753c6ec..eb5d602 100644
--- a/sysdeps/i386/i686/multiarch/strcasecmp-c.c
+++ b/sysdeps/i386/multiarch/strcasecmp-i386.c
@@ -5,7 +5,7 @@ extern __typeof (strcasecmp) __strcasecmp_nonascii;
 #define __strcasecmp __strcasecmp_nonascii
 #include <string/strcasecmp.c>
 
-strong_alias (__strcasecmp_nonascii, __strcasecmp_ia32)
+strong_alias (__strcasecmp_nonascii, __strcasecmp_i386)
 
 /* The needs of strcasecmp in libc are minimal, no need to go through
    the IFUNC.  */
diff --git a/sysdeps/i386/multiarch/strcasecmp.c b/sysdeps/i386/multiarch/strcasecmp.c
new file mode 100644
index 0000000..261bd7a
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcasecmp.c
@@ -0,0 +1,53 @@
+/* Multiple versions of strcasecmp.
+   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 lib.  */
+#if IS_IN (libc)
+/* Redefine strcasecmp so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strcasecmp
+# define strcasecmp __redirect_strcasecmp
+# include <string.h>
+# undef strcasecmp
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strcasecmp) __strcasecmp_i386 attribute_hidden;
+extern __typeof (__redirect_strcasecmp) __strcasecmp_ssse3 attribute_hidden;
+extern __typeof (__redirect_strcasecmp) __strcasecmp_sse4_2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strcasecmp) __strcasecmp;
+extern void *strcasecmp_ifunc (void) __asm__ ("__strcasecmp");
+
+void *
+strcasecmp_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE4_2))
+    return __strcasecmp_sse4_2;
+  else if (HAS_CPU_FEATURE (SSSE3))
+    return __strcasecmp_ssse3;
+
+  return __strcasecmp_i386;
+}
+__asm__ (".type __strcasecmp, %gnu_indirect_function");
+
+weak_alias (__strcasecmp, strcasecmp)
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strcasecmp_l-c.c b/sysdeps/i386/multiarch/strcasecmp_l-i386.c
similarity index 85%
rename from sysdeps/i386/i686/multiarch/strcasecmp_l-c.c
rename to sysdeps/i386/multiarch/strcasecmp_l-i386.c
index d4fcd2b..b5b38d3 100644
--- a/sysdeps/i386/i686/multiarch/strcasecmp_l-c.c
+++ b/sysdeps/i386/multiarch/strcasecmp_l-i386.c
@@ -6,7 +6,7 @@ extern __typeof (strcasecmp_l) __strcasecmp_l_nonascii;
 #define USE_IN_EXTENDED_LOCALE_MODEL    1
 #include <string/strcasecmp.c>
 
-strong_alias (__strcasecmp_l_nonascii, __strcasecmp_l_ia32)
+strong_alias (__strcasecmp_l_nonascii, __strcasecmp_l_i386)
 
 /* The needs of strcasecmp in libc are minimal, no need to go through
    the IFUNC.  */
diff --git a/sysdeps/i386/i686/multiarch/strcasecmp_l-sse4.S b/sysdeps/i386/multiarch/strcasecmp_l-sse4.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strcasecmp_l-sse4.S
rename to sysdeps/i386/multiarch/strcasecmp_l-sse4.S
diff --git a/sysdeps/i386/i686/multiarch/strcasecmp_l-ssse3.S b/sysdeps/i386/multiarch/strcasecmp_l-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strcasecmp_l-ssse3.S
rename to sysdeps/i386/multiarch/strcasecmp_l-ssse3.S
diff --git a/sysdeps/i386/multiarch/strcasecmp_l.c b/sysdeps/i386/multiarch/strcasecmp_l.c
new file mode 100644
index 0000000..7bdc760
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcasecmp_l.c
@@ -0,0 +1,53 @@
+/* Multiple versions of strcasecmp_l.
+   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 lib.  */
+#if IS_IN (libc)
+/* Redefine strcasecmp_l so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strcasecmp_l
+# define strcasecmp_l __redirect_strcasecmp_l
+# include <string.h>
+# undef strcasecmp_l
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strcasecmp_l) __strcasecmp_l_i386 attribute_hidden;
+extern __typeof (__redirect_strcasecmp_l) __strcasecmp_l_ssse3 attribute_hidden;
+extern __typeof (__redirect_strcasecmp_l) __strcasecmp_l_sse4_2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strcasecmp_l) __strcasecmp_l;
+extern void *strcasecmp_l_ifunc (void) __asm__ ("__strcasecmp_l");
+
+void *
+strcasecmp_l_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE4_2))
+    return __strcasecmp_l_sse4_2;
+  else if (HAS_CPU_FEATURE (SSSE3))
+    return __strcasecmp_l_ssse3;
+
+  return __strcasecmp_l_i386;
+}
+__asm__ (".type __strcasecmp_l, %gnu_indirect_function");
+
+weak_alias (__strcasecmp_l, strcasecmp_l)
+#endif
diff --git a/sysdeps/i386/multiarch/strcmp-i386.c b/sysdeps/i386/multiarch/strcmp-i386.c
new file mode 100644
index 0000000..f3b045a
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcmp-i386.c
@@ -0,0 +1,9 @@
+#ifdef SHARED
+# include <init-arch.h>
+# define STRCMP __strcmp_i386
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)  \
+    __hidden_ver1 (__strcmp_i386, __GI_strcmp, __strcmp_i386);
+#endif
+
+#include "string/strcmp.c"
diff --git a/sysdeps/i386/multiarch/strcmp-i686.S b/sysdeps/i386/multiarch/strcmp-i686.S
new file mode 100644
index 0000000..0265d49
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcmp-i686.S
@@ -0,0 +1,6 @@
+#ifdef SHARED
+# define strcmp __strcmp_i686
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# include <sysdeps/i386/i686/strcmp.S>
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strcmp-sse4.S b/sysdeps/i386/multiarch/strcmp-sse4.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strcmp-sse4.S
rename to sysdeps/i386/multiarch/strcmp-sse4.S
diff --git a/sysdeps/i386/i686/multiarch/strcmp-ssse3.S b/sysdeps/i386/multiarch/strcmp-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strcmp-ssse3.S
rename to sysdeps/i386/multiarch/strcmp-ssse3.S
diff --git a/sysdeps/i386/multiarch/strcmp.c b/sysdeps/i386/multiarch/strcmp.c
new file mode 100644
index 0000000..5073c69
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcmp.c
@@ -0,0 +1,58 @@
+/* Multiple versions of strcmp.
+   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.  Don't
+   define multiple versions for strcmp in static library since we
+   need strcmp before the initialization happened.  */
+#if defined  SHARED && IS_IN (libc)
+# define _HAVE_STRING_ARCH_strcmp
+/* Redefine strcmp so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strcmp
+# define strcmp __redirect_strcmp
+# include <string.h>
+# undef strcmp
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strcmp) __strcmp_i386 attribute_hidden;
+extern __typeof (__redirect_strcmp) __strcmp_i686 attribute_hidden;
+extern __typeof (__redirect_strcmp) __strcmp_ssse3 attribute_hidden;
+extern __typeof (__redirect_strcmp) __strcmp_sse4_2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strcmp) strcmp;
+extern void *strcmp_ifunc (void) __asm__ ("strcmp");
+
+void *
+strcmp_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE4_2))
+    return __strcmp_sse4_2;
+  else if (HAS_CPU_FEATURE (SSSE3))
+    return __strcmp_ssse3;
+
+  if (USE_I686)
+    return __strcmp_i686;
+  else
+    return __strcmp_i386;
+}
+__asm__ (".type strcmp, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strncase-c.c b/sysdeps/i386/multiarch/strncase-i386.c
similarity index 72%
rename from sysdeps/i386/i686/multiarch/strncase-c.c
rename to sysdeps/i386/multiarch/strncase-i386.c
index 76581eb..7053e55 100644
--- a/sysdeps/i386/i686/multiarch/strncase-c.c
+++ b/sysdeps/i386/multiarch/strncase-i386.c
@@ -5,4 +5,4 @@ extern __typeof (strncasecmp) __strncasecmp_nonascii;
 #define __strncasecmp __strncasecmp_nonascii
 #include <string/strncase.c>
 
-strong_alias (__strncasecmp_nonascii, __strncasecmp_ia32)
+strong_alias (__strncasecmp_nonascii, __strncasecmp_i386)
diff --git a/sysdeps/i386/multiarch/strncase.c b/sysdeps/i386/multiarch/strncase.c
new file mode 100644
index 0000000..9e5dcab
--- /dev/null
+++ b/sysdeps/i386/multiarch/strncase.c
@@ -0,0 +1,53 @@
+/* Multiple versions of strncasecmp.
+   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 lib.  */
+#if IS_IN (libc)
+/* Redefine strncasecmp so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strncasecmp
+# define strncasecmp __redirect_strncasecmp
+# include <string.h>
+# undef strncasecmp
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strncasecmp) __strncasecmp_i386 attribute_hidden;
+extern __typeof (__redirect_strncasecmp) __strncasecmp_ssse3 attribute_hidden;
+extern __typeof (__redirect_strncasecmp) __strncasecmp_sse4_2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strncasecmp) __strncasecmp;
+extern void *strncasecmp_ifunc (void) __asm__ ("__strncasecmp");
+
+void *
+strncasecmp_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE4_2))
+    return __strncasecmp_sse4_2;
+  else if (HAS_CPU_FEATURE (SSSE3))
+    return __strncasecmp_ssse3;
+
+  return __strncasecmp_i386;
+}
+__asm__ (".type __strncasecmp, %gnu_indirect_function");
+
+weak_alias (__strncasecmp, strncasecmp)
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strncase_l-c.c b/sysdeps/i386/multiarch/strncase_l-i386.c
similarity index 85%
rename from sysdeps/i386/i686/multiarch/strncase_l-c.c
rename to sysdeps/i386/multiarch/strncase_l-i386.c
index 7e601af..efee0bf 100644
--- a/sysdeps/i386/i686/multiarch/strncase_l-c.c
+++ b/sysdeps/i386/multiarch/strncase_l-i386.c
@@ -6,7 +6,7 @@ extern __typeof (strncasecmp_l) __strncasecmp_l_nonascii;
 #define USE_IN_EXTENDED_LOCALE_MODEL    1
 #include <string/strncase.c>
 
-strong_alias (__strncasecmp_l_nonascii, __strncasecmp_l_ia32)
+strong_alias (__strncasecmp_l_nonascii, __strncasecmp_l_i386)
 
 /* The needs of strcasecmp in libc are minimal, no need to go through
    the IFUNC.  */
diff --git a/sysdeps/i386/i686/multiarch/strncase_l-sse4.S b/sysdeps/i386/multiarch/strncase_l-sse4.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strncase_l-sse4.S
rename to sysdeps/i386/multiarch/strncase_l-sse4.S
diff --git a/sysdeps/i386/i686/multiarch/strncase_l-ssse3.S b/sysdeps/i386/multiarch/strncase_l-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strncase_l-ssse3.S
rename to sysdeps/i386/multiarch/strncase_l-ssse3.S
diff --git a/sysdeps/i386/multiarch/strncase_l.c b/sysdeps/i386/multiarch/strncase_l.c
new file mode 100644
index 0000000..279b3ce
--- /dev/null
+++ b/sysdeps/i386/multiarch/strncase_l.c
@@ -0,0 +1,53 @@
+/* Multiple versions of strncasecmp_l.
+   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 lib.  */
+#if IS_IN (libc)
+/* Redefine strncasecmp_l so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strncasecmp_l
+# define strncasecmp_l __redirect_strncasecmp_l
+# include <string.h>
+# undef strncasecmp_l
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strncasecmp_l) __strncasecmp_l_i386 attribute_hidden;
+extern __typeof (__redirect_strncasecmp_l) __strncasecmp_l_ssse3 attribute_hidden;
+extern __typeof (__redirect_strncasecmp_l) __strncasecmp_l_sse4_2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strncasecmp_l) __strncasecmp_l;
+extern void *strncasecmp_l_ifunc (void) __asm__ ("__strncasecmp_l");
+
+void *
+strncasecmp_l_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE4_2))
+    return __strncasecmp_l_sse4_2;
+  else if (HAS_CPU_FEATURE (SSSE3))
+    return __strncasecmp_l_ssse3;
+
+  return __strncasecmp_l_i386;
+}
+__asm__ (".type __strncasecmp_l, %gnu_indirect_function");
+
+weak_alias (__strncasecmp_l, strncasecmp_l)
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strncmp-c.c b/sysdeps/i386/multiarch/strncmp-i386.c
similarity index 56%
rename from sysdeps/i386/i686/multiarch/strncmp-c.c
rename to sysdeps/i386/multiarch/strncmp-i386.c
index cc059da..8e41388 100644
--- a/sysdeps/i386/i686/multiarch/strncmp-c.c
+++ b/sysdeps/i386/multiarch/strncmp-i386.c
@@ -1,8 +1,8 @@
 #ifdef SHARED
-# define STRNCMP __strncmp_ia32
+# define STRNCMP __strncmp_i386
 # undef libc_hidden_builtin_def
 # define libc_hidden_builtin_def(name)  \
-    __hidden_ver1 (__strncmp_ia32, __GI_strncmp, __strncmp_ia32);
+    __hidden_ver1 (__strncmp_i386, __GI_strncmp, __strncmp_i386);
 #endif
 
 #include "string/strncmp.c"
diff --git a/sysdeps/i386/i686/multiarch/strncmp-sse4.S b/sysdeps/i386/multiarch/strncmp-sse4.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strncmp-sse4.S
rename to sysdeps/i386/multiarch/strncmp-sse4.S
diff --git a/sysdeps/i386/i686/multiarch/strncmp-ssse3.S b/sysdeps/i386/multiarch/strncmp-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strncmp-ssse3.S
rename to sysdeps/i386/multiarch/strncmp-ssse3.S
diff --git a/sysdeps/i386/multiarch/strncmp.c b/sysdeps/i386/multiarch/strncmp.c
new file mode 100644
index 0000000..180f870
--- /dev/null
+++ b/sysdeps/i386/multiarch/strncmp.c
@@ -0,0 +1,54 @@
+/* Multiple versions of strncmp.
+   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.  Don't
+   define multiple versions for strncmp in static library since we
+   need strncmp before the initialization happened.  */
+#if defined  SHARED && IS_IN (libc)
+# define _HAVE_STRING_ARCH_strncmp
+/* Redefine strncmp so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strncmp
+# define strncmp __redirect_strncmp
+# include <string.h>
+# undef strncmp
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strncmp) __strncmp_i386 attribute_hidden;
+extern __typeof (__redirect_strncmp) __strncmp_ssse3 attribute_hidden;
+extern __typeof (__redirect_strncmp) __strncmp_sse4_2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strncmp) strncmp;
+extern void *strncmp_ifunc (void) __asm__ ("strncmp");
+
+void *
+strncmp_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE4_2))
+    return __strncmp_sse4_2;
+  else if (HAS_CPU_FEATURE (SSSE3))
+    return __strncmp_ssse3;
+
+  return __strncmp_i386;
+}
+__asm__ (".type strncmp, %gnu_indirect_function");
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=be4b0898eaa27db0ec04694a3b418b0d569f9dc6

commit be4b0898eaa27db0ec04694a3b418b0d569f9dc6
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Aug 20 12:05:50 2015 -0700

    Add i386 strcpy family multiarch functions

diff --git a/sysdeps/i386/i586/multiarch/rtld-stpcpy.S b/sysdeps/i386/i586/multiarch/rtld-stpcpy.S
new file mode 100644
index 0000000..dc0e337
--- /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 0000000..80d8bea
--- /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 0000000..ad942bf
--- /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 0000000..ab6cc06
--- /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 0000000..b9b15b5
--- /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 0000000..65f5398
--- /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 101bb7d..2a14fe8 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 ee81ab6..0000000
--- 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 2698ca6..0000000
--- 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 e9db766..0000000
--- 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 201e3f9..0000000
--- 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 9c257ef..0000000
--- 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 32d3783..1518cae 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 ce5abeb..412f227 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 0000000..5a49821
--- /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 0000000..ef1ff41
--- /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 0000000..f797959
--- /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
similarity index 100%
rename from sysdeps/i386/i686/multiarch/stpcpy-sse2.S
rename to sysdeps/i386/multiarch/stpcpy-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/stpcpy-ssse3.S b/sysdeps/i386/multiarch/stpcpy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/stpcpy-ssse3.S
rename to 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 0000000..58a54fc
--- /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 0000000..3cd0903
--- /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
similarity index 100%
rename from sysdeps/i386/i686/multiarch/stpncpy-sse2.S
rename to sysdeps/i386/multiarch/stpncpy-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/stpncpy-ssse3.S b/sysdeps/i386/multiarch/stpncpy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/stpncpy-ssse3.S
rename to 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 0000000..609d8d4
--- /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 0000000..e577628
--- /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 0000000..65e0641
--- /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
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strcpy-sse2.S
rename to sysdeps/i386/multiarch/strcpy-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/strcpy-ssse3.S b/sysdeps/i386/multiarch/strcpy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strcpy-ssse3.S
rename to 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 0000000..ede627c
--- /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 0000000..b584d83
--- /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
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strncpy-sse2.S
rename to sysdeps/i386/multiarch/strncpy-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/strncpy-ssse3.S b/sysdeps/i386/multiarch/strncpy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strncpy-ssse3.S
rename to 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 0000000..aa98708
--- /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

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=58178e6da066a6e21602ebfcae556fe1c4e2b0bb

commit 58178e6da066a6e21602ebfcae556fe1c4e2b0bb
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Aug 20 08:56:52 2015 -0700

    Add i386 s_fma family multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 74333ca..101bb7d 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -25,9 +25,3 @@ sysdep_routines += wcscmp-sse2 wcscmp-c wcslen-sse2 wcslen-c \
 		   wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c wcschr-sse2 \
 		   wcschr-c wcsrchr-sse2 wcsrchr-c wcscpy-ssse3 wcscpy-c
 endif
-
-ifeq (mathyes,$(subdir)$(config-cflags-avx))
-libm-sysdep_routines += s_fma-fma s_fmaf-fma
-CFLAGS-s_fma-fma.c += -mavx -mfpmath=sse
-CFLAGS-s_fmaf-fma.c += -mavx -mfpmath=sse
-endif
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 8a9ecf3..32d3783 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -23,3 +23,9 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   memrchr-i386 memrchr-sse2-bsf memrchr-sse2 \
 		   rawmemchr-sse2-bsf rawmemchr-sse2
 endif
+
+ifeq (mathyes,$(subdir)$(config-cflags-avx))
+libm-sysdep_routines += s_fma-fma s_fmaf-fma
+CFLAGS-s_fma-fma.c += -mavx -mfpmath=sse
+CFLAGS-s_fmaf-fma.c += -mavx -mfpmath=sse
+endif
diff --git a/sysdeps/i386/i686/multiarch/s_fma-fma.c b/sysdeps/i386/multiarch/s_fma-fma.c
similarity index 100%
rename from sysdeps/i386/i686/multiarch/s_fma-fma.c
rename to sysdeps/i386/multiarch/s_fma-fma.c
diff --git a/sysdeps/i386/i686/multiarch/s_fma.c b/sysdeps/i386/multiarch/s_fma.c
similarity index 88%
rename from sysdeps/i386/i686/multiarch/s_fma.c
rename to sysdeps/i386/multiarch/s_fma.c
index cf2ede5..ab4d8c3 100644
--- a/sysdeps/i386/i686/multiarch/s_fma.c
+++ b/sysdeps/i386/multiarch/s_fma.c
@@ -23,14 +23,14 @@
 #include <math.h>
 #include <init-arch.h>
 
-extern double __fma_ia32 (double x, double y, double z) attribute_hidden;
+extern double __fma_i386 (double x, double y, double z) attribute_hidden;
 extern double __fma_fma (double x, double y, double z) attribute_hidden;
 
 libm_ifunc (__fma,
-	    HAS_ARCH_FEATURE (FMA_Usable) ? __fma_fma : __fma_ia32);
+	    HAS_ARCH_FEATURE (FMA_Usable) ? __fma_fma : __fma_i386);
 weak_alias (__fma, fma)
 
-# define __fma __fma_ia32
+# define __fma __fma_i386
 #endif
 
 #include <sysdeps/ieee754/ldbl-96/s_fma.c>
diff --git a/sysdeps/i386/i686/multiarch/s_fmaf-fma.c b/sysdeps/i386/multiarch/s_fmaf-fma.c
similarity index 100%
rename from sysdeps/i386/i686/multiarch/s_fmaf-fma.c
rename to sysdeps/i386/multiarch/s_fmaf-fma.c
diff --git a/sysdeps/i386/i686/multiarch/s_fmaf.c b/sysdeps/i386/multiarch/s_fmaf.c
similarity index 87%
rename from sysdeps/i386/i686/multiarch/s_fmaf.c
rename to sysdeps/i386/multiarch/s_fmaf.c
index 526cdf1..3c9af05 100644
--- a/sysdeps/i386/i686/multiarch/s_fmaf.c
+++ b/sysdeps/i386/multiarch/s_fmaf.c
@@ -23,14 +23,14 @@
 #include <math.h>
 #include <init-arch.h>
 
-extern float __fmaf_ia32 (float x, float y, float z) attribute_hidden;
+extern float __fmaf_i386 (float x, float y, float z) attribute_hidden;
 extern float __fmaf_fma (float x, float y, float z) attribute_hidden;
 
 libm_ifunc (__fmaf,
-	    HAS_ARCH_FEATURE (FMA_Usable) ? __fmaf_fma : __fmaf_ia32);
+	    HAS_ARCH_FEATURE (FMA_Usable) ? __fmaf_fma : __fmaf_i386);
 weak_alias (__fmaf, fmaf)
 
-# define __fmaf __fmaf_ia32
+# define __fmaf __fmaf_i386
 #endif
 
 #include <sysdeps/ieee754/dbl-64/s_fmaf.c>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=775f29f729a10bfe59d83a409a1ef90a954dd1bb

commit 775f29f729a10bfe59d83a409a1ef90a954dd1bb
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Aug 20 08:39:14 2015 -0700

    Add i386 sched_cpucount multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/sched_cpucount.c b/sysdeps/i386/multiarch/sched_cpucount.c
similarity index 100%
rename from sysdeps/i386/i686/multiarch/sched_cpucount.c
rename to sysdeps/i386/multiarch/sched_cpucount.c

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=70bbb7d27eda3c50f36e0db583df2915aa103ca6

commit 70bbb7d27eda3c50f36e0db583df2915aa103ca6
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Aug 20 08:33:40 2015 -0700

    Add i386 rawmemchr multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 0b91d00..74333ca 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -7,7 +7,6 @@ sysdep_routines += strcmp-ssse3 \
 		   strncpy-sse2 stpcpy-sse2 stpncpy-sse2 strcat-ssse3 \
 		   strcat-sse2 strncat-ssse3 strncat-sse2 strncat-c \
 		   strchr-sse2 strrchr-sse2 strchr-sse2-bsf strrchr-sse2-bsf \
-		   rawmemchr-sse2 rawmemchr-sse2-bsf \
 		   strnlen-sse2 strnlen-c \
 		   strcasecmp_l-c strcasecmp-c strcasecmp_l-ssse3 \
 		   strncase_l-c strncase-c strncase_l-ssse3 \
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index fc9364f..8a9ecf3 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -20,5 +20,6 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   memset-sse2 memset-sse2-rep \
 		   memchr-sse2-bsf memchr-sse2 \
 		   memcmp-i386 memcmp-i686 memcmp-ssse3 memcmp-sse4 \
-		   memrchr-i386 memrchr-sse2-bsf memrchr-sse2
+		   memrchr-i386 memrchr-sse2-bsf memrchr-sse2 \
+		   rawmemchr-sse2-bsf rawmemchr-sse2
 endif
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 15c2009..ce5abeb 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -157,15 +157,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 #endif
 	      )
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/rawmemchr.S.  */
   IFUNC_IMPL (i, name, rawmemchr,
 	      IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_CPU_FEATURE (SSE2),
 			      __rawmemchr_sse2_bsf)
 	      IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_CPU_FEATURE (SSE2),
 			      __rawmemchr_sse2)
-	      IFUNC_IMPL_ADD (array, i, rawmemchr, 1, __rawmemchr_ia32))
+	      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),
diff --git a/sysdeps/i386/i686/multiarch/rawmemchr-sse2-bsf.S b/sysdeps/i386/multiarch/rawmemchr-sse2-bsf.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/rawmemchr-sse2-bsf.S
rename to sysdeps/i386/multiarch/rawmemchr-sse2-bsf.S
diff --git a/sysdeps/i386/i686/multiarch/rawmemchr-sse2.S b/sysdeps/i386/multiarch/rawmemchr-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/rawmemchr-sse2.S
rename to sysdeps/i386/multiarch/rawmemchr-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/rawmemchr.S b/sysdeps/i386/multiarch/rawmemchr.S
similarity index 84%
rename from sysdeps/i386/i686/multiarch/rawmemchr.S
rename to sysdeps/i386/multiarch/rawmemchr.S
index 2cfbe1b..27cc9f3 100644
--- a/sysdeps/i386/i686/multiarch/rawmemchr.S
+++ b/sysdeps/i386/multiarch/rawmemchr.S
@@ -34,7 +34,7 @@ ENTRY(__rawmemchr)
 	LOAD_FUNC_GOT_EAX (__rawmemchr_sse2)
 	ret
 
-2:	LOAD_FUNC_GOT_EAX (__rawmemchr_ia32)
+2:	LOAD_FUNC_GOT_EAX (__rawmemchr_i386)
 	ret
 
 3:	LOAD_FUNC_GOT_EAX (__rawmemchr_sse2_bsf)
@@ -45,21 +45,21 @@ weak_alias(__rawmemchr, rawmemchr)
 
 # undef ENTRY
 # define ENTRY(name) \
-	.type __rawmemchr_ia32, @function; \
-	.globl __rawmemchr_ia32; \
+	.type __rawmemchr_i386, @function; \
+	.globl __rawmemchr_i386; \
 	.p2align 4; \
-	__rawmemchr_ia32: cfi_startproc; \
+	__rawmemchr_i386: cfi_startproc; \
 	CALL_MCOUNT
 # undef END
 # define END(name) \
-	cfi_endproc; .size __rawmemchr_ia32, .-__rawmemchr_ia32
+	cfi_endproc; .size __rawmemchr_i386, .-__rawmemchr_i386
 
 # undef libc_hidden_def
 /* IFUNC doesn't work with the hidden functions in shared library since
    they will be called without setting up EBX needed for PLT which is
    used by IFUNC.  */
 # define libc_hidden_def(name) \
-	.globl __GI___rawmemchr; __GI___rawmemchr = __rawmemchr_ia32
+	.globl __GI___rawmemchr; __GI___rawmemchr = __rawmemchr_i386
 
 #endif
-#include "../../rawmemchr.S"
+#include <sysdeps/i386/rawmemchr.S>
diff --git a/sysdeps/i386/multiarch/rtld-rawmemchr.S b/sysdeps/i386/multiarch/rtld-rawmemchr.S
new file mode 100644
index 0000000..9d5c196
--- /dev/null
+++ b/sysdeps/i386/multiarch/rtld-rawmemchr.S
@@ -0,0 +1,20 @@
+/* rawmemchr 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 <init-arch.h>
+#include <sysdeps/i386/rawmemchr.S>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=0176f78bd683234f879621b52f95c2599fd61e9c

commit 0176f78bd683234f879621b52f95c2599fd61e9c
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Aug 20 08:28:10 2015 -0700

    Add i386 memrchr multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index ec128d7..0b91d00 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -7,7 +7,6 @@ sysdep_routines += strcmp-ssse3 \
 		   strncpy-sse2 stpcpy-sse2 stpncpy-sse2 strcat-ssse3 \
 		   strcat-sse2 strncat-ssse3 strncat-sse2 strncat-c \
 		   strchr-sse2 strrchr-sse2 strchr-sse2-bsf strrchr-sse2-bsf \
-		   memrchr-sse2 memrchr-sse2-bsf memrchr-c \
 		   rawmemchr-sse2 rawmemchr-sse2-bsf \
 		   strnlen-sse2 strnlen-c \
 		   strcasecmp_l-c strcasecmp-c strcasecmp_l-ssse3 \
diff --git a/sysdeps/i386/i686/multiarch/memrchr-c.c b/sysdeps/i386/i686/multiarch/memrchr-c.c
deleted file mode 100644
index ef7bbbe..0000000
--- a/sysdeps/i386/i686/multiarch/memrchr-c.c
+++ /dev/null
@@ -1,7 +0,0 @@
-#if IS_IN (libc)
-# define MEMRCHR  __memrchr_ia32
-# include <string.h>
-extern void *__memrchr_ia32 (const void *, int, size_t);
-#endif
-
-#include "string/memrchr.c"
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 577bbb6..fc9364f 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -19,5 +19,6 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   memset-i386 memset-i586 memset-i686 \
 		   memset-sse2 memset-sse2-rep \
 		   memchr-sse2-bsf memchr-sse2 \
-		   memcmp-i386 memcmp-i686 memcmp-ssse3 memcmp-sse4
+		   memcmp-i386 memcmp-i686 memcmp-ssse3 memcmp-sse4 \
+		   memrchr-i386 memrchr-sse2-bsf memrchr-sse2
 endif
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index e57134d..15c2009 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -116,15 +116,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 #endif
 	      )
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/memrchr.S.  */
   IFUNC_IMPL (i, name, memrchr,
 	      IFUNC_IMPL_ADD (array, i, memrchr, HAS_CPU_FEATURE (SSE2),
 			      __memrchr_sse2_bsf)
 	      IFUNC_IMPL_ADD (array, i, memrchr, HAS_CPU_FEATURE (SSE2),
 			      __memrchr_sse2)
-	      IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_ia32))
-#endif
+	      IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_i386))
 
   /* Support sysdeps/i386/i686/multiarch/memset_chk.S.  */
   IFUNC_IMPL (i, name, __memset_chk,
diff --git a/sysdeps/i386/multiarch/memrchr-i386.c b/sysdeps/i386/multiarch/memrchr-i386.c
new file mode 100644
index 0000000..f8cef07
--- /dev/null
+++ b/sysdeps/i386/multiarch/memrchr-i386.c
@@ -0,0 +1,7 @@
+#if IS_IN (libc)
+# define MEMRCHR  __memrchr_i386
+# include <string.h>
+extern void *__memrchr_i386 (const void *, int, size_t);
+#endif
+
+#include "string/memrchr.c"
diff --git a/sysdeps/i386/i686/multiarch/memrchr-sse2-bsf.S b/sysdeps/i386/multiarch/memrchr-sse2-bsf.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memrchr-sse2-bsf.S
rename to sysdeps/i386/multiarch/memrchr-sse2-bsf.S
diff --git a/sysdeps/i386/i686/multiarch/memrchr-sse2.S b/sysdeps/i386/multiarch/memrchr-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memrchr-sse2.S
rename to sysdeps/i386/multiarch/memrchr-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/memrchr.S b/sysdeps/i386/multiarch/memrchr.S
similarity index 97%
rename from sysdeps/i386/i686/multiarch/memrchr.S
rename to sysdeps/i386/multiarch/memrchr.S
index 32fb1a6..be8deae 100644
--- a/sysdeps/i386/i686/multiarch/memrchr.S
+++ b/sysdeps/i386/multiarch/memrchr.S
@@ -34,7 +34,7 @@ ENTRY(__memrchr)
 	LOAD_FUNC_GOT_EAX (__memrchr_sse2)
 	ret
 
-2:	LOAD_FUNC_GOT_EAX (__memrchr_ia32)
+2:	LOAD_FUNC_GOT_EAX (__memrchr_i386)
 	ret
 
 3:	LOAD_FUNC_GOT_EAX (__memrchr_sse2_bsf)

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=5e0783331846552f531743d4a6a02889ae0a8098

commit 5e0783331846552f531743d4a6a02889ae0a8098
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Aug 20 08:20:41 2015 -0700

    Add i386 memcmp multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index c088a39..ec128d7 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,7 +1,7 @@
 ifeq ($(subdir),string)
 sysdep_routines += strcmp-ssse3 \
 		   strcmp-sse4 strncmp-c strncmp-ssse3 strncmp-sse4 \
-		   memcmp-ssse3 memcmp-sse4 varshift \
+		   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 \
diff --git a/sysdeps/i386/i686/multiarch/memcmp-i386.S b/sysdeps/i386/i686/multiarch/memcmp-i386.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memcmp-i386.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/memcmp-i686.S b/sysdeps/i386/i686/multiarch/memcmp-i686.S
new file mode 100644
index 0000000..7aaf48b
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memcmp-i686.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/memcmp-i686.S>
+
+#ifdef SHARED
+	.globl __GI_memcmp
+	.hidden __GI_memcmp
+	__GI_memcmp = __memcmp_i686
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memcmp.S b/sysdeps/i386/i686/multiarch/memcmp.S
deleted file mode 100644
index d4d7d2e..0000000
--- a/sysdeps/i386/i686/multiarch/memcmp.S
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Multiple versions of memcmp
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-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>
-
-/* Define multiple versions only for the definition in libc. */
-#if IS_IN (libc)
-	.text
-ENTRY(memcmp)
-	.type	memcmp, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memcmp_ia32)
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcmp_ssse3)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcmp_sse4_2)
-2:	ret
-END(memcmp)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __memcmp_ia32, @function; \
-	.p2align 4; \
-	.globl __memcmp_ia32; \
-	.hidden __memcmp_ia32; \
-	__memcmp_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __memcmp_ia32, .-__memcmp_ia32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_memcmp; __GI_memcmp = __memcmp_ia32
-# endif
-#endif
-
-#include "../memcmp.S"
diff --git a/sysdeps/i386/i686/multiarch/memcmp.c b/sysdeps/i386/i686/multiarch/memcmp.c
new file mode 100644
index 0000000..63103a0
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memcmp.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/memcmp.c>
diff --git a/sysdeps/i386/i686/multiarch/rtld-memcmp.S b/sysdeps/i386/i686/multiarch/rtld-memcmp.S
new file mode 100644
index 0000000..85ec290
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/rtld-memcmp.S
@@ -0,0 +1,19 @@
+/* memcmp 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/i686/memcmp.S>
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 937cea9..577bbb6 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -18,5 +18,6 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   bzero-sse2 bzero-sse2-rep \
 		   memset-i386 memset-i586 memset-i686 \
 		   memset-sse2 memset-sse2-rep \
-		   memchr-sse2-bsf memchr-sse2
+		   memchr-sse2-bsf memchr-sse2 \
+		   memcmp-i386 memcmp-i686 memcmp-ssse3 memcmp-sse4
 endif
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 420efb2..e57134d 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -71,15 +71,17 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __memchr_sse2)
 	      IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/memcmp.S.  */
   IFUNC_IMPL (i, name, memcmp,
 	      IFUNC_IMPL_ADD (array, i, memcmp, HAS_CPU_FEATURE (SSE4_2),
 			      __memcmp_sse4_2)
 	      IFUNC_IMPL_ADD (array, i, memcmp, HAS_CPU_FEATURE (SSSE3),
 			      __memcmp_ssse3)
-	      IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_ia32))
+	      IFUNC_IMPL_ADD (array, i, memcmp, HAS_I686, __memcmp_i686)
+#if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_i386)
 #endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/memmove_chk.S.  */
   IFUNC_IMPL (i, name, __memmove_chk,
diff --git a/sysdeps/i386/multiarch/memcmp-i386.S b/sysdeps/i386/multiarch/memcmp-i386.S
new file mode 100644
index 0000000..18e7424
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcmp-i386.S
@@ -0,0 +1,12 @@
+#define memcmp __memcmp_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/memcmp.S>
+
+#ifdef SHARED
+	.globl __GI_memcmp
+	.hidden __GI_memcmp
+	__GI_memcmp = __memcmp_i386
+#endif
diff --git a/sysdeps/i386/multiarch/memcmp-i686.S b/sysdeps/i386/multiarch/memcmp-i686.S
new file mode 100644
index 0000000..32d1a4d
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcmp-i686.S
@@ -0,0 +1,6 @@
+#define memcmp __memcmp_i686
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/i686/memcmp.S>
diff --git a/sysdeps/i386/i686/multiarch/memcmp-sse4.S b/sysdeps/i386/multiarch/memcmp-sse4.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memcmp-sse4.S
rename to sysdeps/i386/multiarch/memcmp-sse4.S
diff --git a/sysdeps/i386/i686/multiarch/memcmp-ssse3.S b/sysdeps/i386/multiarch/memcmp-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memcmp-ssse3.S
rename to sysdeps/i386/multiarch/memcmp-ssse3.S
diff --git a/sysdeps/i386/multiarch/memcmp.c b/sysdeps/i386/multiarch/memcmp.c
new file mode 100644
index 0000000..36ca7da
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcmp.c
@@ -0,0 +1,57 @@
+/* Multiple versions of memcmp.
+   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 lib.  */
+#if IS_IN (libc)
+/* Redefine memcmp so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef memcmp
+# define memcmp __redirect_memcmp
+# include <string.h>
+# undef memcmp
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_memcmp) __memcmp_i386 attribute_hidden;
+extern __typeof (__redirect_memcmp) __memcmp_i686 attribute_hidden;
+extern __typeof (__redirect_memcmp) __memcmp_ssse3 attribute_hidden;
+extern __typeof (__redirect_memcmp) __memcmp_sse4_2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_memcmp) memcmp;
+extern void *memcmp_ifunc (void) __asm__ ("memcmp");
+
+void *
+memcmp_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE4_2))
+    return __memcmp_sse4_2;
+  else if (HAS_CPU_FEATURE (SSSE3))
+    return __memcmp_ssse3;
+
+  if (USE_I686)
+    return __memcmp_i686;
+  else
+    return __memcmp_i386;
+}
+__asm__ (".type memcmp, %gnu_indirect_function");
+
+weak_alias (memcmp, bcmp)
+#endif
diff --git a/sysdeps/i386/multiarch/rtld-memcmp.S b/sysdeps/i386/multiarch/rtld-memcmp.S
new file mode 100644
index 0000000..d3a07fe
--- /dev/null
+++ b/sysdeps/i386/multiarch/rtld-memcmp.S
@@ -0,0 +1,19 @@
+/* memcmp 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/memcmp.S>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=2d2aac8f79d6537cf4f982391bbffa970cecc8ff

commit 2d2aac8f79d6537cf4f982391bbffa970cecc8ff
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Aug 20 08:05:39 2015 -0700

    Add i386 memchr multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 3b1190e..c088a39 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -7,7 +7,6 @@ sysdep_routines += strcmp-ssse3 \
 		   strncpy-sse2 stpcpy-sse2 stpncpy-sse2 strcat-ssse3 \
 		   strcat-sse2 strncat-ssse3 strncat-sse2 strncat-c \
 		   strchr-sse2 strrchr-sse2 strchr-sse2-bsf strrchr-sse2-bsf \
-		   memchr-sse2 memchr-sse2-bsf \
 		   memrchr-sse2 memrchr-sse2-bsf memrchr-c \
 		   rawmemchr-sse2 rawmemchr-sse2-bsf \
 		   strnlen-sse2 strnlen-c \
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 58dffcd..937cea9 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -17,5 +17,6 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   bzero-i386 bzero-i586 bzero-i686 \
 		   bzero-sse2 bzero-sse2-rep \
 		   memset-i386 memset-i586 memset-i686 \
-		   memset-sse2 memset-sse2-rep
+		   memset-sse2 memset-sse2-rep \
+		   memchr-sse2-bsf memchr-sse2
 endif
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index d5df5de..420efb2 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -63,15 +63,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 #endif
 	      )
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/memchr.S.  */
   IFUNC_IMPL (i, name, memchr,
 	      IFUNC_IMPL_ADD (array, i, memchr, HAS_CPU_FEATURE (SSE2),
 			      __memchr_sse2_bsf)
 	      IFUNC_IMPL_ADD (array, i, memchr, HAS_CPU_FEATURE (SSE2),
 			      __memchr_sse2)
-	      IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_ia32))
+	      IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/memcmp.S.  */
   IFUNC_IMPL (i, name, memcmp,
 	      IFUNC_IMPL_ADD (array, i, memcmp, HAS_CPU_FEATURE (SSE4_2),
diff --git a/sysdeps/i386/i686/multiarch/memchr-sse2-bsf.S b/sysdeps/i386/multiarch/memchr-sse2-bsf.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memchr-sse2-bsf.S
rename to sysdeps/i386/multiarch/memchr-sse2-bsf.S
diff --git a/sysdeps/i386/i686/multiarch/memchr-sse2.S b/sysdeps/i386/multiarch/memchr-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memchr-sse2.S
rename to sysdeps/i386/multiarch/memchr-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/memchr.S b/sysdeps/i386/multiarch/memchr.S
similarity index 83%
rename from sysdeps/i386/i686/multiarch/memchr.S
rename to sysdeps/i386/multiarch/memchr.S
index 65e6b96..4b2b941 100644
--- a/sysdeps/i386/i686/multiarch/memchr.S
+++ b/sysdeps/i386/multiarch/memchr.S
@@ -18,10 +18,10 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
 #if IS_IN (libc)
+# include <sysdep.h>
+# include <init-arch.h>
+
 	.text
 ENTRY(__memchr)
 	.type	__memchr, @gnu_indirect_function
@@ -34,7 +34,7 @@ ENTRY(__memchr)
 	LOAD_FUNC_GOT_EAX ( __memchr_sse2)
 	ret
 
-2:	LOAD_FUNC_GOT_EAX (__memchr_ia32)
+2:	LOAD_FUNC_GOT_EAX (__memchr_i386)
 	ret
 
 3:	LOAD_FUNC_GOT_EAX (__memchr_sse2_bsf)
@@ -45,21 +45,21 @@ weak_alias(__memchr, memchr)
 
 # undef ENTRY
 # define ENTRY(name) \
-	.type __memchr_ia32, @function; \
-	.globl __memchr_ia32; \
+	.type __memchr_i386, @function; \
+	.globl __memchr_i386; \
 	.p2align 4; \
-	__memchr_ia32: cfi_startproc; \
+	__memchr_i386: cfi_startproc; \
 	CALL_MCOUNT
 # undef END
 # define END(name) \
-	cfi_endproc; .size __memchr_ia32, .-__memchr_ia32
+	cfi_endproc; .size __memchr_i386, .-__memchr_i386
 
 # undef libc_hidden_builtin_def
 /* IFUNC doesn't work with the hidden functions in shared library since
    they will be called without setting up EBX needed for PLT which is
    used by IFUNC.  */
 # define libc_hidden_builtin_def(name) \
-	.globl __GI_memchr; __GI_memchr = __memchr_ia32
+	.globl __GI_memchr; __GI_memchr = __memchr_i386
 
 #endif
-#include "../../memchr.S"
+#include <sysdeps/i386/memchr.S>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c725fd57ed2979e093da7f9fac5a2c6e90f5b436

commit c725fd57ed2979e093da7f9fac5a2c6e90f5b436
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Aug 20 06:28:49 2015 -0700

    Add i386 memcpy family multiarch functions

diff --git a/sysdeps/i386/i586/multiarch/memcpy.c b/sysdeps/i386/i586/multiarch/memcpy.c
new file mode 100644
index 0000000..a23ae5c
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/memcpy.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/memcpy.c>
diff --git a/sysdeps/i386/i586/multiarch/mempcpy.c b/sysdeps/i386/i586/multiarch/mempcpy.c
new file mode 100644
index 0000000..1ae8773
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/mempcpy.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/mempcpy.c>
diff --git a/sysdeps/i386/i586/multiarch/rtld-memcpy.S b/sysdeps/i386/i586/multiarch/rtld-memcpy.S
new file mode 100644
index 0000000..2e53b40
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/rtld-memcpy.S
@@ -0,0 +1,19 @@
+/* memcpy 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/memcpy.S>
diff --git a/sysdeps/i386/i586/multiarch/static-memcpy.S b/sysdeps/i386/i586/multiarch/static-memcpy.S
new file mode 100644
index 0000000..37b0917
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/static-memcpy.S
@@ -0,0 +1,21 @@
+/* memcpy for libc.a
+   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/>.  */
+
+#if !defined SHARED && IS_IN (libc)
+# include <sysdeps/i386/i586/memcpy.S>
+#endif
diff --git a/sysdeps/i386/i586/multiarch/static-mempcpy.S b/sysdeps/i386/i586/multiarch/static-mempcpy.S
new file mode 100644
index 0000000..418420f
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/static-mempcpy.S
@@ -0,0 +1,21 @@
+/* memcpy for libc.a
+   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/>.  */
+
+#if !defined SHARED && IS_IN (libc)
+# include <sysdeps/i386/i586/mempcpy.S>
+#endif
diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 59072b9..3b1190e 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,8 +1,5 @@
 ifeq ($(subdir),string)
-sysdep_routines += memcpy-ssse3 mempcpy-ssse3 \
-		   memmove-ssse3 memcpy-ssse3-rep mempcpy-ssse3-rep \
-		   memmove-ssse3-rep bcopy-ssse3 bcopy-ssse3-rep \
-		   strcmp-ssse3 \
+sysdep_routines += strcmp-ssse3 \
 		   strcmp-sse4 strncmp-c strncmp-ssse3 strncmp-sse4 \
 		   memcmp-ssse3 memcmp-sse4 varshift \
 		   strlen-sse2 strlen-sse2-bsf strncpy-c strcpy-ssse3 \
@@ -16,9 +13,7 @@ sysdep_routines += memcpy-ssse3 mempcpy-ssse3 \
 		   strnlen-sse2 strnlen-c \
 		   strcasecmp_l-c strcasecmp-c strcasecmp_l-ssse3 \
 		   strncase_l-c strncase-c strncase_l-ssse3 \
-		   strcasecmp_l-sse4 strncase_l-sse4 \
-		   bcopy-sse2-unaligned memcpy-sse2-unaligned \
-		   mempcpy-sse2-unaligned memmove-sse2-unaligned
+		   strcasecmp_l-sse4 strncase_l-sse4
 ifeq (yes,$(config-cflags-sse4))
 sysdep_routines += strcspn-c strpbrk-c strspn-c
 CFLAGS-varshift.c += -msse4
diff --git a/sysdeps/i386/i686/multiarch/bcopy-i386.S b/sysdeps/i386/i686/multiarch/bcopy-i386.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/bcopy-i386.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/bcopy-i686.S b/sysdeps/i386/i686/multiarch/bcopy-i686.S
new file mode 100644
index 0000000..bb13d28
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/bcopy-i686.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/bcopy-i686.S>
+
+#ifdef SHARED
+	.globl __GI_bcopy
+	.hidden __GI_bcopy
+	__GI_bcopy = __bcopy_i686
+#endif
diff --git a/sysdeps/i386/i686/multiarch/bcopy.S b/sysdeps/i386/i686/multiarch/bcopy.S
deleted file mode 100644
index 3fc95dc..0000000
--- a/sysdeps/i386/i686/multiarch/bcopy.S
+++ /dev/null
@@ -1,59 +0,0 @@
-/* Multiple versions of bcopy
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-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>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(bcopy)
-	.type	bcopy, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__bcopy_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__bcopy_sse2_unaligned)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__bcopy_ssse3)
-	HAS_CPU_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__bcopy_ssse3_rep)
-2:	ret
-END(bcopy)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __bcopy_ia32, @function; \
-	.p2align 4; \
-	.globl __bcopy_ia32; \
-	.hidden __bcopy_ia32; \
-	__bcopy_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __bcopy_ia32, .-__bcopy_ia32
-
-#endif
-
-#include "../bcopy.S"
diff --git a/sysdeps/i386/i686/multiarch/bcopy.c b/sysdeps/i386/i686/multiarch/bcopy.c
new file mode 100644
index 0000000..6fb21e8
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/bcopy.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/bcopy.c>
diff --git a/sysdeps/i386/i686/multiarch/memcpy-i386.S b/sysdeps/i386/i686/multiarch/memcpy-i386.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memcpy-i386.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/memcpy-i586.S b/sysdeps/i386/i686/multiarch/memcpy-i586.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memcpy-i586.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/memcpy-i686.S b/sysdeps/i386/i686/multiarch/memcpy-i686.S
new file mode 100644
index 0000000..e7f84df
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memcpy-i686.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/memcpy-i686.S>
+
+#ifdef SHARED
+	.globl __GI_memcpy
+	.hidden __GI_memcpy
+	__GI_memcpy = __memcpy_i686
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memcpy.S b/sysdeps/i386/i686/multiarch/memcpy.S
deleted file mode 100644
index 9a4d183..0000000
--- a/sysdeps/i386/i686/multiarch/memcpy.S
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Multiple versions of memcpy
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-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>
-
-/* Define multiple versions only for the definition in lib and for
-   DSO.  In static binaries we need memcpy before the initialization
-   happened.  */
-#if defined SHARED && IS_IN (libc)
-	.text
-ENTRY(memcpy)
-	.type	memcpy, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memcpy_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcpy_sse2_unaligned)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcpy_ssse3)
-	HAS_CPU_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcpy_ssse3_rep)
-2:	ret
-END(memcpy)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __memcpy_ia32, @function; \
-	.p2align 4; \
-	.globl __memcpy_ia32; \
-	.hidden __memcpy_ia32; \
-	__memcpy_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __memcpy_ia32, .-__memcpy_ia32
-
-# undef ENTRY_CHK
-# define ENTRY_CHK(name) \
-	.type __memcpy_chk_ia32, @function; \
-	.globl __memcpy_chk_ia32; \
-	.p2align 4; \
-	__memcpy_chk_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END_CHK
-# define END_CHK(name) \
-	cfi_endproc; .size __memcpy_chk_ia32, .-__memcpy_chk_ia32
-
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_memcpy; __GI_memcpy = __memcpy_ia32
-#endif
-
-#include "../memcpy.S"
diff --git a/sysdeps/i386/i686/multiarch/memcpy.c b/sysdeps/i386/i686/multiarch/memcpy.c
new file mode 100644
index 0000000..a23ae5c
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memcpy.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/memcpy.c>
diff --git a/sysdeps/i386/i686/multiarch/memcpy_chk.S b/sysdeps/i386/i686/multiarch/memcpy_chk.S
deleted file mode 100644
index 3bbd921..0000000
--- a/sysdeps/i386/i686/multiarch/memcpy_chk.S
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Multiple versions of __memcpy_chk
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-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>
-
-/* Define multiple versions only for the definition in lib and for
-   DSO.  There are no multiarch memcpy functions for static binaries.
- */
-#if IS_IN (libc)
-# ifdef SHARED
-	.text
-ENTRY(__memcpy_chk)
-	.type	__memcpy_chk, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memcpy_chk_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcpy_chk_sse2_unaligned)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcpy_chk_ssse3)
-	HAS_CPU_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcpy_chk_ssse3_rep)
-2:	ret
-END(__memcpy_chk)
-# else
-#  include "../memcpy_chk.S"
-# endif
-#endif
diff --git a/sysdeps/i386/i686/multiarch/memmove-i386.S b/sysdeps/i386/i686/multiarch/memmove-i386.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memmove-i386.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/memmove-i686.S b/sysdeps/i386/i686/multiarch/memmove-i686.S
new file mode 100644
index 0000000..35ad327
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memmove-i686.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/memmove-i686.S>
+
+#ifdef SHARED
+	.globl __GI_memmove
+	.hidden __GI_memmove
+	__GI_memmove = __memmove_i686
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memmove.S b/sysdeps/i386/i686/multiarch/memmove.S
deleted file mode 100644
index 2bf427f..0000000
--- a/sysdeps/i386/i686/multiarch/memmove.S
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Multiple versions of memmove
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-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>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(memmove)
-	.type	memmove, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memmove_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memmove_sse2_unaligned)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memmove_ssse3)
-	HAS_ARCH_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memmove_ssse3_rep)
-2:	ret
-END(memmove)
-
-# ifdef SHARED
-#  undef ENTRY
-#  define ENTRY(name) \
-	.type __memmove_ia32, @function; \
-	.p2align 4; \
-	.globl __memmove_ia32; \
-	.hidden __memmove_ia32; \
-	__memmove_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# else
-#  undef ENTRY
-#  define ENTRY(name) \
-	.type __memmove_ia32, @function; \
-	.globl __memmove_ia32; \
-	.p2align 4; \
-	__memmove_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# endif
-
-# undef END
-# define END(name) \
-	cfi_endproc; .size __memmove_ia32, .-__memmove_ia32
-
-# undef ENTRY_CHK
-# define ENTRY_CHK(name) \
-	.type __memmove_chk_ia32, @function; \
-	.globl __memmove_chk_ia32; \
-	.p2align 4; \
-	__memmove_chk_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END_CHK
-# define END_CHK(name) \
-	cfi_endproc; .size __memmove_chk_ia32, .-__memmove_chk_ia32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_memmove; __GI_memmove = __memmove_ia32
-# endif
-#endif
-
-#include "../memmove.S"
diff --git a/sysdeps/i386/i686/multiarch/memmove.c b/sysdeps/i386/i686/multiarch/memmove.c
new file mode 100644
index 0000000..5953add
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memmove.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/memmove.c>
diff --git a/sysdeps/i386/i686/multiarch/memmove_chk.S b/sysdeps/i386/i686/multiarch/memmove_chk.S
deleted file mode 100644
index b17f6ed..0000000
--- a/sysdeps/i386/i686/multiarch/memmove_chk.S
+++ /dev/null
@@ -1,94 +0,0 @@
-/* Multiple versions of __memmove_chk
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-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>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(__memmove_chk)
-	.type	__memmove_chk, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memmove_chk_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memmove_chk_sse2_unaligned)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memmove_chk_ssse3)
-	HAS_CPU_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memmove_chk_ssse3_rep)
-2:	ret
-END(__memmove_chk)
-
-# ifndef SHARED
-	.type __memmove_chk_sse2_unaligned, @function
-	.p2align 4;
-__memmove_chk_sse2_unaligned:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memmove_sse2_unaligned
-	cfi_endproc
-	.size __memmove_chk_sse2_unaligned, .-__memmove_chk_sse2_unaligned
-
-	.type __memmove_chk_ssse3, @function
-	.p2align 4;
-__memmove_chk_ssse3:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memmove_ssse3
-	cfi_endproc
-	.size __memmove_chk_ssse3, .-__memmove_chk_ssse3
-
-	.type __memmove_chk_ssse3_rep, @function
-	.p2align 4;
-__memmove_chk_ssse3_rep:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memmove_ssse3_rep
-	cfi_endproc
-	.size __memmove_chk_ssse3_rep, .-__memmove_chk_ssse3_rep
-
-	.type __memmove_chk_ia32, @function
-	.p2align 4;
-__memmove_chk_ia32:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memmove_ia32
-	cfi_endproc
-	.size __memmove_chk_ia32, .-__memmove_chk_ia32
-# endif
-#endif
diff --git a/sysdeps/i386/i686/multiarch/mempcpy-i386.S b/sysdeps/i386/i686/multiarch/mempcpy-i386.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/mempcpy-i386.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/mempcpy-i586.S b/sysdeps/i386/i686/multiarch/mempcpy-i586.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/mempcpy-i586.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/mempcpy-i686.S b/sysdeps/i386/i686/multiarch/mempcpy-i686.S
new file mode 100644
index 0000000..f87cac3
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/mempcpy-i686.S
@@ -0,0 +1,10 @@
+#include <sysdeps/i386/multiarch/mempcpy-i686.S>
+
+#ifdef SHARED
+	.globl __GI_mempcpy
+	.hidden __GI_mempcpy
+	__GI_mempcpy = __mempcpy_i686
+	.globl __GI___mempcpy
+	.hidden __GI___mempcpy
+	__GI___mempcpy = __mempcpy_i686
+#endif
diff --git a/sysdeps/i386/i686/multiarch/mempcpy.S b/sysdeps/i386/i686/multiarch/mempcpy.S
deleted file mode 100644
index 021558a..0000000
--- a/sysdeps/i386/i686/multiarch/mempcpy.S
+++ /dev/null
@@ -1,81 +0,0 @@
-/* Multiple versions of mempcpy
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-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>
-
-/* Define multiple versions only for the definition in lib and for
-   DSO.  In static binaries we need mempcpy before the initialization
-   happened.  */
-#if defined SHARED && IS_IN (libc)
-	.text
-ENTRY(__mempcpy)
-	.type	__mempcpy, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__mempcpy_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__mempcpy_sse2_unaligned)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__mempcpy_ssse3)
-	HAS_CPU_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__mempcpy_ssse3_rep)
-2:	ret
-END(__mempcpy)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __mempcpy_ia32, @function; \
-	.p2align 4; \
-	.globl __mempcpy_ia32; \
-	.hidden __mempcpy_ia32; \
-	__mempcpy_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __mempcpy_ia32, .-__mempcpy_ia32
-
-# undef ENTRY_CHK
-# define ENTRY_CHK(name) \
-	.type __mempcpy_chk_ia32, @function; \
-	.globl __mempcpy_chk_ia32; \
-	.p2align 4; \
-	__mempcpy_chk_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END_CHK
-# define END_CHK(name) \
-	cfi_endproc; .size __mempcpy_chk_ia32, .-__mempcpy_chk_ia32
-
-# undef libc_hidden_def
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_def(name) \
-	.globl __GI_mempcpy; __GI_mempcpy = __mempcpy_ia32
-# define libc_hidden_builtin_def(name) \
-	.globl __GI___mempcpy; __GI___mempcpy = __mempcpy_ia32
-#endif
-
-#include "../mempcpy.S"
diff --git a/sysdeps/i386/i686/multiarch/mempcpy.c b/sysdeps/i386/i686/multiarch/mempcpy.c
new file mode 100644
index 0000000..1ae8773
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/mempcpy.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/mempcpy.c>
diff --git a/sysdeps/i386/i686/multiarch/mempcpy_chk.S b/sysdeps/i386/i686/multiarch/mempcpy_chk.S
deleted file mode 100644
index 1bea6ea..0000000
--- a/sysdeps/i386/i686/multiarch/mempcpy_chk.S
+++ /dev/null
@@ -1,50 +0,0 @@
-/* Multiple versions of __mempcpy_chk
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-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>
-
-/* Define multiple versions only for the definition in lib and for
-   DSO.  There are no multiarch mempcpy functions for static binaries.
- */
-#if IS_IN (libc)
-# ifdef SHARED
-	.text
-ENTRY(__mempcpy_chk)
-	.type	__mempcpy_chk, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__mempcpy_chk_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__mempcpy_chk_sse2_unaligned)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__mempcpy_chk_ssse3)
-	HAS_CPU_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__mempcpy_chk_ssse3_rep)
-2:	ret
-END(__mempcpy_chk)
-# else
-#  include "../mempcpy_chk.S"
-# endif
-#endif
diff --git a/sysdeps/i386/i686/multiarch/rtld-memcpy.S b/sysdeps/i386/i686/multiarch/rtld-memcpy.S
new file mode 100644
index 0000000..0ab09fb
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/rtld-memcpy.S
@@ -0,0 +1,19 @@
+/* memcpy 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/i686/memcpy.S>
diff --git a/sysdeps/i386/i686/multiarch/rtld-memmove.S b/sysdeps/i386/i686/multiarch/rtld-memmove.S
new file mode 100644
index 0000000..38f589a
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/rtld-memmove.S
@@ -0,0 +1,19 @@
+/* memmove 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/i686/memmove.S>
diff --git a/sysdeps/i386/i686/multiarch/static-memcpy.S b/sysdeps/i386/i686/multiarch/static-memcpy.S
new file mode 100644
index 0000000..ef9f0b9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/static-memcpy.S
@@ -0,0 +1,21 @@
+/* memcpy for libc.a
+   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/>.  */
+
+#if !defined SHARED && IS_IN (libc)
+# include <sysdeps/i386/i686/memcpy.S>
+#endif
diff --git a/sysdeps/i386/i686/multiarch/static-memmove.S b/sysdeps/i386/i686/multiarch/static-memmove.S
new file mode 100644
index 0000000..6fc3a39
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/static-memmove.S
@@ -0,0 +1,21 @@
+/* memmove for libc.a
+   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/>.  */
+
+#if !defined SHARED && IS_IN (libc)
+# include <sysdeps/i386/i686/memmove.S>
+#endif
diff --git a/sysdeps/i386/i686/multiarch/static-mempcpy.S b/sysdeps/i386/i686/multiarch/static-mempcpy.S
new file mode 100644
index 0000000..60db75c
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/static-mempcpy.S
@@ -0,0 +1,21 @@
+/* memcpy for libc.a
+   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/>.  */
+
+#if !defined SHARED && IS_IN (libc)
+# include <sysdeps/i386/i686/mempcpy.S>
+#endif
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 44fabed..58dffcd 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -5,7 +5,16 @@ endif
 
 ifeq ($(subdir),string)
 gen-as-const-headers += locale-defines.sym
-sysdep_routines += bzero-i386 bzero-i586 bzero-i686 \
+sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
+		   bcopy-ssse3 bcopy-ssse3-rep \
+		   memcpy-i386 memcpy-i586 memcpy-i686 \
+		   memcpy-sse2-unaligned memcpy-ssse3 memcpy-ssse3-rep \
+		   memmove-i386 memmove-i686 memmove-sse2-unaligned \
+		   memmove-ssse3 memmove-ssse3-rep \
+		   mempcpy-i386 mempcpy-i586 mempcpy-i686 \
+		   mempcpy-sse2-unaligned mempcpy-ssse3 mempcpy-ssse3-rep \
+		   static-memcpy static-memmove static-mempcpy \
+		   bzero-i386 bzero-i586 bzero-i686 \
 		   bzero-sse2 bzero-sse2-rep \
 		   memset-i386 memset-i586 memset-i686 \
 		   memset-sse2 memset-sse2-rep
diff --git a/sysdeps/i386/multiarch/bcopy-i386.S b/sysdeps/i386/multiarch/bcopy-i386.S
new file mode 100644
index 0000000..dbc9bd1
--- /dev/null
+++ b/sysdeps/i386/multiarch/bcopy-i386.S
@@ -0,0 +1,12 @@
+#define bcopy __bcopy_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/bcopy.S>
+
+#ifdef SHARED
+	.globl __GI_bcopy
+	.hidden __GI_bcopy
+	__GI_bcopy = __bcopy_i386
+#endif
diff --git a/sysdeps/i386/multiarch/bcopy-i686.S b/sysdeps/i386/multiarch/bcopy-i686.S
new file mode 100644
index 0000000..335ac85
--- /dev/null
+++ b/sysdeps/i386/multiarch/bcopy-i686.S
@@ -0,0 +1,6 @@
+#define bcopy __bcopy_i686
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/i686/bcopy.S>
diff --git a/sysdeps/i386/i686/multiarch/bcopy-sse2-unaligned.S b/sysdeps/i386/multiarch/bcopy-sse2-unaligned.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/bcopy-sse2-unaligned.S
rename to sysdeps/i386/multiarch/bcopy-sse2-unaligned.S
diff --git a/sysdeps/i386/i686/multiarch/bcopy-ssse3-rep.S b/sysdeps/i386/multiarch/bcopy-ssse3-rep.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/bcopy-ssse3-rep.S
rename to sysdeps/i386/multiarch/bcopy-ssse3-rep.S
diff --git a/sysdeps/i386/i686/multiarch/bcopy-ssse3.S b/sysdeps/i386/multiarch/bcopy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/bcopy-ssse3.S
rename to sysdeps/i386/multiarch/bcopy-ssse3.S
diff --git a/sysdeps/i386/multiarch/bcopy.c b/sysdeps/i386/multiarch/bcopy.c
new file mode 100644
index 0000000..eefbd4e
--- /dev/null
+++ b/sysdeps/i386/multiarch/bcopy.c
@@ -0,0 +1,64 @@
+/* Multiple versions of bcopy.
+   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 lib.  */
+#if IS_IN (libc)
+/* Redefine bcopy so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef bcopy
+# define bcopy __redirect_bcopy
+# include <string.h>
+# undef bcopy
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_bcopy) __bcopy_i386 attribute_hidden;
+extern __typeof (__redirect_bcopy) __bcopy_i686 attribute_hidden;
+extern __typeof (__redirect_bcopy) __bcopy_sse2_unaligned attribute_hidden;
+extern __typeof (__redirect_bcopy) __bcopy_ssse3 attribute_hidden;
+extern __typeof (__redirect_bcopy) __bcopy_ssse3_rep attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_bcopy) bcopy;
+extern void *bcopy_ifunc (void) __asm__ ("bcopy");
+
+void *
+bcopy_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Fast_Unaligned_Load))
+	return __bcopy_sse2_unaligned;
+      else if (HAS_CPU_FEATURE (SSSE3))
+	{
+	  if (HAS_ARCH_FEATURE (Fast_Rep_String))
+	    return __bcopy_ssse3_rep;
+	  else
+	    return __bcopy_ssse3;
+	}
+    }
+
+  if (USE_I686)
+    return __bcopy_i686;
+  else
+    return __bcopy_i386;
+}
+__asm__ (".type bcopy, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 7bde24e..d5df5de 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -36,7 +36,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   size_t i = 0;
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/bcopy.S.  */
   IFUNC_IMPL (i, name, bcopy,
 	      IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSSE3),
@@ -45,8 +44,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __bcopy_ssse3)
 	      IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSE2),
 			      __bcopy_sse2_unaligned)
-	      IFUNC_IMPL_ADD (array, i, bcopy, 1, __bcopy_ia32))
+	      IFUNC_IMPL_ADD (array, i, bcopy, HAS_I686, __bcopy_i686)
+#if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, bcopy, 1, __bcopy_i386)
 #endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/bzero.S.  */
   IFUNC_IMPL (i, name, bzero,
@@ -77,6 +79,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, memcmp, HAS_CPU_FEATURE (SSSE3),
 			      __memcmp_ssse3)
 	      IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/memmove_chk.S.  */
   IFUNC_IMPL (i, name, __memmove_chk,
@@ -89,8 +92,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, __memmove_chk,
 			      HAS_CPU_FEATURE (SSE2),
 			      __memmove_chk_sse2_unaligned)
+	      IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_I686,
+			      __memmove_chk_i686)
+#if MINIMUM_ISA < 686
 	      IFUNC_IMPL_ADD (array, i, __memmove_chk, 1,
-			      __memmove_chk_ia32))
+			      __memmove_chk_i386)
+#endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/memmove.S.  */
   IFUNC_IMPL (i, name, memmove,
@@ -100,8 +108,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __memmove_ssse3)
 	      IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSE2),
 			      __memmove_sse2_unaligned)
-	      IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ia32))
+	      IFUNC_IMPL_ADD (array, i, memmove, HAS_I686, __memmove_i686)
+#if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_i386)
+#endif
+	      )
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/memrchr.S.  */
   IFUNC_IMPL (i, name, memrchr,
 	      IFUNC_IMPL_ADD (array, i, memrchr, HAS_CPU_FEATURE (SSE2),
@@ -329,6 +342,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSSE3),
 			      __wmemcmp_ssse3)
 	      IFUNC_IMPL_ADD (array, i, wmemcmp, 1, __wmemcmp_ia32))
+#endif
 
 #ifdef SHARED
   /* Support sysdeps/i386/i686/multiarch/memcpy_chk.S.  */
@@ -342,8 +356,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, __memcpy_chk,
 			      HAS_CPU_FEATURE (SSE2),
 			      __memcpy_chk_sse2_unaligned)
+	      IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_I686,
+			      __memcpy_chk_i686)
+# if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_I586,
+			      __memcpy_chk_i586)
 	      IFUNC_IMPL_ADD (array, i, __memcpy_chk, 1,
-			      __memcpy_chk_ia32))
+			      __memcpy_chk_i386)
+# endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/memcpy.S.  */
   IFUNC_IMPL (i, name, memcpy,
@@ -353,7 +374,12 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __memcpy_ssse3)
 	      IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSE2),
 			      __memcpy_sse2_unaligned)
-	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ia32))
+	      IFUNC_IMPL_ADD (array, i, memcpy, HAS_I686, __memcpy_i686)
+#if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, memcpy, HAS_I586, __memcpy_i586)
+	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_i386)
+# endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/mempcpy_chk.S.  */
   IFUNC_IMPL (i, name, __mempcpy_chk,
@@ -366,8 +392,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, __mempcpy_chk,
 			      HAS_CPU_FEATURE (SSE2),
 			      __mempcpy_chk_sse2_unaligned)
+	      IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_I686,
+			      __mempcpy_chk_i686)
+# if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_I586,
+			      __mempcpy_chk_i586)
 	      IFUNC_IMPL_ADD (array, i, __mempcpy_chk, 1,
-			      __mempcpy_chk_ia32))
+			      __mempcpy_chk_i386)
+# endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/mempcpy.S.  */
   IFUNC_IMPL (i, name, mempcpy,
@@ -377,8 +410,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __mempcpy_ssse3)
 	      IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSE2),
 			      __mempcpy_sse2_unaligned)
-	      IFUNC_IMPL_ADD (array, i, mempcpy, 1, __mempcpy_ia32))
+	      IFUNC_IMPL_ADD (array, i, mempcpy, HAS_I686, __mempcpy_i686)
+# if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, mempcpy, HAS_I586, __mempcpy_i586)
+	      IFUNC_IMPL_ADD (array, i, mempcpy, 1, __mempcpy_i386)
+# endif
+	      )
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strlen.S.  */
   IFUNC_IMPL (i, name, strlen,
 	      IFUNC_IMPL_ADD (array, i, strlen, HAS_CPU_FEATURE (SSE2),
diff --git a/sysdeps/i386/multiarch/memcpy-i386.S b/sysdeps/i386/multiarch/memcpy-i386.S
new file mode 100644
index 0000000..d26b195
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcpy-i386.S
@@ -0,0 +1,11 @@
+#ifdef SHARED
+# define memcpy __memcpy_i386
+# define __memcpy_chk __memcpy_chk_i386
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# include <sysdeps/i386/memcpy.S>
+
+	.globl __GI_memcpy
+	.hidden __GI_memcpy
+	__GI_memcpy = __memcpy_i386
+#endif
diff --git a/sysdeps/i386/multiarch/memcpy-i586.S b/sysdeps/i386/multiarch/memcpy-i586.S
new file mode 100644
index 0000000..a9d89d9
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcpy-i586.S
@@ -0,0 +1,7 @@
+#ifdef SHARED
+# define memcpy __memcpy_i586
+# define __memcpy_chk __memcpy_chk_i586
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# include <sysdeps/i386/i586/memcpy.S>
+#endif
diff --git a/sysdeps/i386/multiarch/memcpy-i686.S b/sysdeps/i386/multiarch/memcpy-i686.S
new file mode 100644
index 0000000..c5f516e
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcpy-i686.S
@@ -0,0 +1,7 @@
+#ifdef SHARED
+# define memcpy __memcpy_i686
+# define __memcpy_chk __memcpy_chk_i686
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# include <sysdeps/i386/i686/memcpy.S>
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S b/sysdeps/i386/multiarch/memcpy-sse2-unaligned.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S
rename to sysdeps/i386/multiarch/memcpy-sse2-unaligned.S
diff --git a/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S b/sysdeps/i386/multiarch/memcpy-ssse3-rep.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S
rename to sysdeps/i386/multiarch/memcpy-ssse3-rep.S
diff --git a/sysdeps/i386/i686/multiarch/memcpy-ssse3.S b/sysdeps/i386/multiarch/memcpy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memcpy-ssse3.S
rename to sysdeps/i386/multiarch/memcpy-ssse3.S
diff --git a/sysdeps/i386/multiarch/memcpy.c b/sysdeps/i386/multiarch/memcpy.c
new file mode 100644
index 0000000..68401c7
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcpy.c
@@ -0,0 +1,69 @@
+/* Multiple versions of memcpy.
+   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 lib and for
+   DSO.  In static binaries we need memcpy before the initialization
+   happened.  */
+#if defined SHARED && IS_IN (libc)
+/* Redefine memcpy so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef memcpy
+# define memcpy __redirect_memcpy
+# include <string.h>
+# undef memcpy
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_memcpy) __memcpy_i386 attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_i586 attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_i686 attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_sse2_unaligned attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_ssse3 attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_ssse3_rep attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_memcpy) memcpy;
+extern void *memcpy_ifunc (void) __asm__ ("memcpy");
+
+void *
+memcpy_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Fast_Unaligned_Load))
+	return __memcpy_sse2_unaligned;
+      else if (HAS_CPU_FEATURE (SSSE3))
+	{
+	  if (HAS_ARCH_FEATURE (Fast_Rep_String))
+	    return __memcpy_ssse3_rep;
+	  else
+	    return __memcpy_ssse3;
+	}
+    }
+
+  if (USE_I686)
+    return __memcpy_i686;
+  else if (USE_I586)
+    return __memcpy_i586;
+  else
+    return __memcpy_i386;
+}
+__asm__ (".type memcpy, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/multiarch/memcpy_chk.c b/sysdeps/i386/multiarch/memcpy_chk.c
new file mode 100644
index 0000000..aad6f87
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcpy_chk.c
@@ -0,0 +1,70 @@
+/* Multiple versions of __memcpy_chk
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 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/>.  */
+
+/* Define multiple versions only for the definition in lib and for
+   DSO.  There are no multiarch memcpy functions for static binaries.
+ */
+#if IS_IN (libc)
+# ifdef SHARED
+#  include <stddef.h>
+
+extern void * __memcpy_chk (void *, const void *, size_t, size_t);
+
+extern __typeof (__memcpy_chk) __memcpy_chk_i386 attribute_hidden;
+extern __typeof (__memcpy_chk) __memcpy_chk_i586 attribute_hidden;
+extern __typeof (__memcpy_chk) __memcpy_chk_i686 attribute_hidden;
+extern __typeof (__memcpy_chk) __memcpy_chk_sse2_unaligned attribute_hidden;
+extern __typeof (__memcpy_chk) __memcpy_chk_ssse3 attribute_hidden;
+extern __typeof (__memcpy_chk) __memcpy_chk_ssse3_rep attribute_hidden;
+
+#  include <init-arch.h>
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern void *memcpy_chk_ifunc (void) __asm__ ("__memcpy_chk");
+
+void *
+memcpy_chk_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Fast_Unaligned_Load))
+	return __memcpy_chk_sse2_unaligned;
+      else if (HAS_CPU_FEATURE (SSSE3))
+	{
+	  if (HAS_ARCH_FEATURE (Fast_Rep_String))
+	    return __memcpy_chk_ssse3_rep;
+	  else
+	    return __memcpy_chk_ssse3;
+	}
+    }
+
+  if (USE_I686)
+    return __memcpy_chk_i686;
+  else if (USE_I586)
+    return __memcpy_chk_i586;
+  else
+    return __memcpy_chk_i386;
+}
+__asm__ (".type __memcpy_chk, %gnu_indirect_function");
+# else
+#  include <debug/memcpy_chk.c>
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/memmove-i386.S b/sysdeps/i386/multiarch/memmove-i386.S
new file mode 100644
index 0000000..af21d2d
--- /dev/null
+++ b/sysdeps/i386/multiarch/memmove-i386.S
@@ -0,0 +1,11 @@
+#ifdef SHARED
+# define memmove __memmove_i386
+# define __memmove_chk __memmove_chk_i386
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# include <sysdeps/i386/memmove.S>
+
+	.globl __GI_memmove
+	.hidden __GI_memmove
+	__GI_memmove = __memmove_i386
+#endif
diff --git a/sysdeps/i386/multiarch/memmove-i686.S b/sysdeps/i386/multiarch/memmove-i686.S
new file mode 100644
index 0000000..bde4051
--- /dev/null
+++ b/sysdeps/i386/multiarch/memmove-i686.S
@@ -0,0 +1,7 @@
+#ifdef SHARED
+# define memmove __memmove_i686
+# define __memmove_chk __memmove_chk_i686
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# include <sysdeps/i386/i686/memmove.S>
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memmove-sse2-unaligned.S b/sysdeps/i386/multiarch/memmove-sse2-unaligned.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memmove-sse2-unaligned.S
rename to sysdeps/i386/multiarch/memmove-sse2-unaligned.S
diff --git a/sysdeps/i386/i686/multiarch/memmove-ssse3-rep.S b/sysdeps/i386/multiarch/memmove-ssse3-rep.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memmove-ssse3-rep.S
rename to sysdeps/i386/multiarch/memmove-ssse3-rep.S
diff --git a/sysdeps/i386/i686/multiarch/memmove-ssse3.S b/sysdeps/i386/multiarch/memmove-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memmove-ssse3.S
rename to sysdeps/i386/multiarch/memmove-ssse3.S
diff --git a/sysdeps/i386/multiarch/memmove.c b/sysdeps/i386/multiarch/memmove.c
new file mode 100644
index 0000000..e47d15e
--- /dev/null
+++ b/sysdeps/i386/multiarch/memmove.c
@@ -0,0 +1,66 @@
+/* Multiple versions of memmove.
+   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 lib and for
+   DSO.  In static binaries we need memmove before the initialization
+   happened.  */
+#if defined SHARED && IS_IN (libc)
+/* Redefine memmove so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef memmove
+# define memmove __redirect_memmove
+# include <string.h>
+# undef memmove
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_memmove) __memmove_i386 attribute_hidden;
+extern __typeof (__redirect_memmove) __memmove_i686 attribute_hidden;
+extern __typeof (__redirect_memmove) __memmove_sse2_unaligned attribute_hidden;
+extern __typeof (__redirect_memmove) __memmove_ssse3 attribute_hidden;
+extern __typeof (__redirect_memmove) __memmove_ssse3_rep attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_memmove) memmove;
+extern void *memmove_ifunc (void) __asm__ ("memmove");
+
+void *
+memmove_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Fast_Unaligned_Load))
+	return __memmove_sse2_unaligned;
+      else if (HAS_CPU_FEATURE (SSSE3))
+	{
+	  if (HAS_ARCH_FEATURE (Fast_Rep_String))
+	    return __memmove_ssse3_rep;
+	  else
+	    return __memmove_ssse3;
+	}
+    }
+
+  if (USE_I686)
+    return __memmove_i686;
+  else
+    return __memmove_i386;
+}
+__asm__ (".type memmove, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/multiarch/memmove_chk.c b/sysdeps/i386/multiarch/memmove_chk.c
new file mode 100644
index 0000000..d34c19a
--- /dev/null
+++ b/sysdeps/i386/multiarch/memmove_chk.c
@@ -0,0 +1,105 @@
+/* Multiple versions of __memmove_chk
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 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/>.  */
+
+/* Define multiple versions only for the definition in lib.  */
+#if IS_IN (libc)
+#  include <stddef.h>
+
+extern void * __memmove_chk (void *, const void *, size_t, size_t);
+
+# ifdef SHARED
+extern __typeof (__memmove_chk) __memmove_chk_i386 attribute_hidden;
+extern __typeof (__memmove_chk) __memmove_chk_i686 attribute_hidden;
+extern __typeof (__memmove_chk) __memmove_chk_sse2_unaligned attribute_hidden;
+extern __typeof (__memmove_chk) __memmove_chk_ssse3 attribute_hidden;
+extern __typeof (__memmove_chk) __memmove_chk_ssse3_rep attribute_hidden;
+
+#  include <init-arch.h>
+# else
+/* Redefine memmove so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+#  undef memmove
+#  define memmove __redirect_memmove
+#  include <string.h>
+#  undef memmove
+
+extern __typeof (__redirect_memmove) __memmove_i386 attribute_hidden;
+extern __typeof (__redirect_memmove) __memmove_i686 attribute_hidden;
+extern __typeof (__redirect_memmove) __memmove_sse2_unaligned attribute_hidden;
+extern __typeof (__redirect_memmove) __memmove_ssse3 attribute_hidden;
+extern __typeof (__redirect_memmove) __memmove_ssse3_rep attribute_hidden;
+
+/* Due to
+   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10837
+   noreturn attribute disable tail call optimization.  Removes noreturn
+   attribute to enable tail call optimization.  */
+extern void *chk_fail (void) __asm__ ("__chk_fail") attribute_hidden;
+
+#  include <init-arch.h>
+
+#define ifunc_chk(func, arch) \
+static void *							\
+func##_chk_##arch (void *dstpp, const void *srcpp, size_t len,	\
+		   size_t dstlen)				\
+{								\
+  if (__glibc_unlikely (dstlen < len))				\
+    return chk_fail ();						\
+  return func##_##arch (dstpp, srcpp, len);			\
+}
+
+#  if MINIMUM_ISA < 686
+ifunc_chk (__memmove, i386)
+#  else
+extern __typeof (__memmove_chk) __memmove_chk_i386 attribute_hidden;
+#  endif
+
+ifunc_chk (__memmove, i686)
+ifunc_chk (__memmove, sse2_unaligned)
+ifunc_chk (__memmove, ssse3)
+ifunc_chk (__memmove, ssse3_rep)
+# endif
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern void *memmove_chk_ifunc (void) __asm__ ("__memmove_chk");
+
+void *
+memmove_chk_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Fast_Unaligned_Load))
+	return __memmove_chk_sse2_unaligned;
+      else if (HAS_CPU_FEATURE (SSSE3))
+	{
+	  if (HAS_ARCH_FEATURE (Fast_Rep_String))
+	    return __memmove_chk_ssse3_rep;
+	  else
+	    return __memmove_chk_ssse3;
+	}
+    }
+
+  if (USE_I686)
+    return __memmove_chk_i686;
+  else
+    return __memmove_chk_i386;
+}
+__asm__ (".type __memmove_chk, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/multiarch/mempcpy-i386.S b/sysdeps/i386/multiarch/mempcpy-i386.S
new file mode 100644
index 0000000..39f72b6
--- /dev/null
+++ b/sysdeps/i386/multiarch/mempcpy-i386.S
@@ -0,0 +1,18 @@
+#ifdef SHARED
+# define __mempcpy __mempcpy_i386
+# define __mempcpy_chk __mempcpy_chk_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/mempcpy.S>
+
+	.globl __GI_mempcpy
+	.hidden __GI_mempcpy
+	__GI_mempcpy = __mempcpy_i386
+	.globl __GI___mempcpy
+	.hidden __GI___mempcpy
+	__GI___mempcpy = __mempcpy_i386
+#endif
diff --git a/sysdeps/i386/multiarch/mempcpy-i586.S b/sysdeps/i386/multiarch/mempcpy-i586.S
new file mode 100644
index 0000000..cb0d241
--- /dev/null
+++ b/sysdeps/i386/multiarch/mempcpy-i586.S
@@ -0,0 +1,11 @@
+#ifdef SHARED
+# define __mempcpy __mempcpy_i586
+# define __mempcpy_chk __mempcpy_chk_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/mempcpy.S>
+#endif
diff --git a/sysdeps/i386/multiarch/mempcpy-i686.S b/sysdeps/i386/multiarch/mempcpy-i686.S
new file mode 100644
index 0000000..1b5fba6
--- /dev/null
+++ b/sysdeps/i386/multiarch/mempcpy-i686.S
@@ -0,0 +1,11 @@
+#ifdef SHARED
+# define __mempcpy __mempcpy_i686
+# define __mempcpy_chk __mempcpy_chk_i686
+# 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/i686/mempcpy.S>
+#endif
diff --git a/sysdeps/i386/i686/multiarch/mempcpy-sse2-unaligned.S b/sysdeps/i386/multiarch/mempcpy-sse2-unaligned.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/mempcpy-sse2-unaligned.S
rename to sysdeps/i386/multiarch/mempcpy-sse2-unaligned.S
diff --git a/sysdeps/i386/i686/multiarch/mempcpy-ssse3-rep.S b/sysdeps/i386/multiarch/mempcpy-ssse3-rep.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/mempcpy-ssse3-rep.S
rename to sysdeps/i386/multiarch/mempcpy-ssse3-rep.S
diff --git a/sysdeps/i386/i686/multiarch/mempcpy-ssse3.S b/sysdeps/i386/multiarch/mempcpy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/mempcpy-ssse3.S
rename to sysdeps/i386/multiarch/mempcpy-ssse3.S
diff --git a/sysdeps/i386/multiarch/mempcpy.c b/sysdeps/i386/multiarch/mempcpy.c
new file mode 100644
index 0000000..a267477
--- /dev/null
+++ b/sysdeps/i386/multiarch/mempcpy.c
@@ -0,0 +1,71 @@
+/* Multiple versions of mempcpy.
+   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 lib and for
+   DSO.  In static binaries we need mempcpy before the initialization
+   happened.  */
+#if defined SHARED && IS_IN (libc)
+# define _HAVE_STRING_ARCH_mempcpy
+/* Redefine mempcpy so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef mempcpy
+# define mempcpy __redirect_mempcpy
+# include <string.h>
+# undef mempcpy
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_mempcpy) __mempcpy_i386 attribute_hidden;
+extern __typeof (__redirect_mempcpy) __mempcpy_i586 attribute_hidden;
+extern __typeof (__redirect_mempcpy) __mempcpy_i686 attribute_hidden;
+extern __typeof (__redirect_mempcpy) __mempcpy_sse2_unaligned attribute_hidden;
+extern __typeof (__redirect_mempcpy) __mempcpy_ssse3 attribute_hidden;
+extern __typeof (__redirect_mempcpy) __mempcpy_ssse3_rep attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_mempcpy) __mempcpy;
+extern void *mempcpy_ifunc (void) __asm__ ("__mempcpy");
+
+void *
+mempcpy_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Fast_Unaligned_Load))
+	return __mempcpy_sse2_unaligned;
+      else if (HAS_CPU_FEATURE (SSSE3))
+	{
+	  if (HAS_ARCH_FEATURE (Fast_Rep_String))
+	    return __mempcpy_ssse3_rep;
+	  else
+	    return __mempcpy_ssse3;
+	}
+    }
+
+  if (USE_I686)
+    return __mempcpy_i686;
+  else if (USE_I586)
+    return __mempcpy_i586;
+  else
+    return __mempcpy_i386;
+}
+__asm__ (".type __mempcpy, %gnu_indirect_function");
+weak_alias (__mempcpy, mempcpy)
+#endif
diff --git a/sysdeps/i386/multiarch/mempcpy_chk.c b/sysdeps/i386/multiarch/mempcpy_chk.c
new file mode 100644
index 0000000..b1e1fd6
--- /dev/null
+++ b/sysdeps/i386/multiarch/mempcpy_chk.c
@@ -0,0 +1,70 @@
+/* Multiple versions of __mempcpy_chk
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 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/>.  */
+
+/* Define multiple versions only for the definition in lib and for
+   DSO.  There are no multiarch mempcpy functions for static binaries.
+ */
+#if IS_IN (libc)
+# ifdef SHARED
+#  include <stddef.h>
+
+extern void * __mempcpy_chk (void *, const void *, size_t, size_t);
+
+extern __typeof (__mempcpy_chk) __mempcpy_chk_i386 attribute_hidden;
+extern __typeof (__mempcpy_chk) __mempcpy_chk_i586 attribute_hidden;
+extern __typeof (__mempcpy_chk) __mempcpy_chk_i686 attribute_hidden;
+extern __typeof (__mempcpy_chk) __mempcpy_chk_sse2_unaligned attribute_hidden;
+extern __typeof (__mempcpy_chk) __mempcpy_chk_ssse3 attribute_hidden;
+extern __typeof (__mempcpy_chk) __mempcpy_chk_ssse3_rep attribute_hidden;
+
+#  include <init-arch.h>
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern void *mempcpy_chk_ifunc (void) __asm__ ("__mempcpy_chk");
+
+void *
+mempcpy_chk_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Fast_Unaligned_Load))
+	return __mempcpy_chk_sse2_unaligned;
+      else if (HAS_CPU_FEATURE (SSSE3))
+	{
+	  if (HAS_ARCH_FEATURE (Fast_Rep_String))
+	    return __mempcpy_chk_ssse3_rep;
+	  else
+	    return __mempcpy_chk_ssse3;
+	}
+    }
+
+  if (USE_I686)
+    return __mempcpy_chk_i686;
+  else if (USE_I586)
+    return __mempcpy_chk_i586;
+  else
+    return __mempcpy_chk_i386;
+}
+__asm__ (".type __mempcpy_chk, %gnu_indirect_function");
+# else
+#  include <debug/mempcpy_chk.c>
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/rtld-memmove.S b/sysdeps/i386/multiarch/rtld-memmove.S
new file mode 100644
index 0000000..d1312ec
--- /dev/null
+++ b/sysdeps/i386/multiarch/rtld-memmove.S
@@ -0,0 +1,19 @@
+/* memmove 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/memmove.S>
diff --git a/sysdeps/i386/multiarch/static-memcpy.S b/sysdeps/i386/multiarch/static-memcpy.S
new file mode 100644
index 0000000..b7d6b2a
--- /dev/null
+++ b/sysdeps/i386/multiarch/static-memcpy.S
@@ -0,0 +1,21 @@
+/* memcpy for libc.a
+   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/>.  */
+
+#if !defined SHARED && IS_IN (libc)
+# include <sysdeps/i386/memcpy.S>
+#endif
diff --git a/sysdeps/i386/multiarch/static-memmove.S b/sysdeps/i386/multiarch/static-memmove.S
new file mode 100644
index 0000000..086f394
--- /dev/null
+++ b/sysdeps/i386/multiarch/static-memmove.S
@@ -0,0 +1,21 @@
+/* memmove for libc.a
+   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/>.  */
+
+#if !defined SHARED && IS_IN (libc)
+# include <sysdeps/i386/memmove.S>
+#endif
diff --git a/sysdeps/i386/multiarch/static-mempcpy.S b/sysdeps/i386/multiarch/static-mempcpy.S
new file mode 100644
index 0000000..27c035c
--- /dev/null
+++ b/sysdeps/i386/multiarch/static-mempcpy.S
@@ -0,0 +1,21 @@
+/* memcpy for libc.a
+   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/>.  */
+
+#if !defined SHARED && IS_IN (libc)
+# include <sysdeps/i386/mempcpy.S>
+#endif

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=38fcdcffac0466fe89affd4052e711c17bd6eea9

commit 38fcdcffac0466fe89affd4052e711c17bd6eea9
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Aug 19 14:10:40 2015 -0700

    Add i386 memset family multiarch functions

diff --git a/sysdeps/i386/i586/multiarch/bzero-i386.S b/sysdeps/i386/i586/multiarch/bzero-i386.S
new file mode 100644
index 0000000..02c0874
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/bzero-i386.S
@@ -0,0 +1,6 @@
+#define __bzero __bzero_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/bzero.S>
diff --git a/sysdeps/i386/i586/multiarch/bzero-i586.S b/sysdeps/i386/i586/multiarch/bzero-i586.S
new file mode 100644
index 0000000..b33a36c
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/bzero-i586.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/bzero-i586.S>
+
+#ifdef SHARED
+	.globl __GI_bzero
+	.hidden __GI_bzero
+	__GI_bzero = __bzero_i586
+#endif
diff --git a/sysdeps/i386/i586/multiarch/bzero.c b/sysdeps/i386/i586/multiarch/bzero.c
new file mode 100644
index 0000000..c14c064
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/bzero.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/bzero.c>
diff --git a/sysdeps/i386/i586/multiarch/memset-i386.S b/sysdeps/i386/i586/multiarch/memset-i386.S
new file mode 100644
index 0000000..3d2a287
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/memset-i386.S
@@ -0,0 +1,5 @@
+#define memset __memset_i386
+#define __memset_chk __memset_chk_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/memset.S>
diff --git a/sysdeps/i386/i586/multiarch/memset-i586.S b/sysdeps/i386/i586/multiarch/memset-i586.S
new file mode 100644
index 0000000..47b29ce
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/memset-i586.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/memset-i586.S>
+
+#ifdef SHARED
+	.globl __GI_memset
+	.hidden __GI_memset
+	__GI_memset = __memset_i586
+#endif
diff --git a/sysdeps/i386/i586/multiarch/memset.c b/sysdeps/i386/i586/multiarch/memset.c
new file mode 100644
index 0000000..57037dd
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/memset.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/memset.c>
diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 31bfd39..59072b9 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,14 +1,8 @@
-ifeq ($(subdir),csu)
-tests += test-multiarch
-gen-as-const-headers += ifunc-defines.sym
-endif
-
 ifeq ($(subdir),string)
-gen-as-const-headers += locale-defines.sym
-sysdep_routines += bzero-sse2 memset-sse2 memcpy-ssse3 mempcpy-ssse3 \
+sysdep_routines += memcpy-ssse3 mempcpy-ssse3 \
 		   memmove-ssse3 memcpy-ssse3-rep mempcpy-ssse3-rep \
 		   memmove-ssse3-rep bcopy-ssse3 bcopy-ssse3-rep \
-		   memset-sse2-rep bzero-sse2-rep strcmp-ssse3 \
+		   strcmp-ssse3 \
 		   strcmp-sse4 strncmp-c strncmp-ssse3 strncmp-sse4 \
 		   memcmp-ssse3 memcmp-sse4 varshift \
 		   strlen-sse2 strlen-sse2-bsf strncpy-c strcpy-ssse3 \
diff --git a/sysdeps/i386/i686/multiarch/bzero-i386.S b/sysdeps/i386/i686/multiarch/bzero-i386.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/bzero-i386.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/bzero-i586.S b/sysdeps/i386/i686/multiarch/bzero-i586.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/bzero-i586.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/bzero-i686.S b/sysdeps/i386/i686/multiarch/bzero-i686.S
new file mode 100644
index 0000000..1af300c
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/bzero-i686.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/bzero-i686.S>
+
+#ifdef SHARED
+	.globl __GI_bzero
+	.hidden __GI_bzero
+	__GI_bzero = __bzero_i686
+#endif
diff --git a/sysdeps/i386/i686/multiarch/bzero.S b/sysdeps/i386/i686/multiarch/bzero.S
deleted file mode 100644
index 95c96a8..0000000
--- a/sysdeps/i386/i686/multiarch/bzero.S
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Multiple versions of bzero
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-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>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(__bzero)
-	.type	__bzero, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__bzero_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX ( __bzero_sse2)
-	HAS_CPU_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__bzero_sse2_rep)
-2:	ret
-END(__bzero)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __bzero_ia32, @function; \
-	.p2align 4; \
-	.globl __bzero_ia32; \
-	.hidden __bzero_ia32; \
-	__bzero_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __bzero_ia32, .-__bzero_ia32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI___bzero; __GI___bzero = __bzero_ia32
-# endif
-#endif
-
-#include "../bzero.S"
diff --git a/sysdeps/i386/i686/multiarch/bzero.c b/sysdeps/i386/i686/multiarch/bzero.c
new file mode 100644
index 0000000..c14c064
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/bzero.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/bzero.c>
diff --git a/sysdeps/i386/i686/multiarch/memset-i386.S b/sysdeps/i386/i686/multiarch/memset-i386.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memset-i386.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/memset-i586.S b/sysdeps/i386/i686/multiarch/memset-i586.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memset-i586.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/memset-i686.S b/sysdeps/i386/i686/multiarch/memset-i686.S
new file mode 100644
index 0000000..e9a22b8
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memset-i686.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/memset-i686.S>
+
+#ifdef SHARED
+	.globl __GI_memset
+	.hidden __GI_memset
+	__GI_memset = __memset_i686
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memset.S b/sysdeps/i386/i686/multiarch/memset.S
deleted file mode 100644
index 8015d57..0000000
--- a/sysdeps/i386/i686/multiarch/memset.S
+++ /dev/null
@@ -1,75 +0,0 @@
-/* Multiple versions of memset
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-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>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(memset)
-	.type	memset, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memset_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memset_sse2)
-	HAS_CPU_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memset_sse2_rep)
-2:	ret
-END(memset)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __memset_ia32, @function; \
-	.globl __memset_ia32; \
-	.p2align 4; \
-	__memset_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __memset_ia32, .-__memset_ia32
-
-# undef ENTRY_CHK
-# define ENTRY_CHK(name) \
-	.type __memset_chk_ia32, @function; \
-	.globl __memset_chk_ia32; \
-	.p2align 4; \
-	__memset_chk_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END_CHK
-# define END_CHK(name) \
-	cfi_endproc; .size __memset_chk_ia32, .-__memset_chk_ia32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_memset; __GI_memset = __memset_ia32
-# endif
-
-# undef strong_alias
-# define strong_alias(original, alias)
-#endif
-
-#include "../memset.S"
diff --git a/sysdeps/i386/i686/multiarch/memset.c b/sysdeps/i386/i686/multiarch/memset.c
new file mode 100644
index 0000000..57037dd
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memset.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/memset.c>
diff --git a/sysdeps/i386/i686/multiarch/memset_chk.S b/sysdeps/i386/i686/multiarch/memset_chk.S
deleted file mode 100644
index 7be45e7..0000000
--- a/sysdeps/i386/i686/multiarch/memset_chk.S
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Multiple versions of __memset_chk
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-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>
-
-/* Define multiple versions only for the definition in lib.  */
-#if IS_IN (libc)
-	.text
-ENTRY(__memset_chk)
-	.type	__memset_chk, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memset_chk_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memset_chk_sse2)
-	HAS_CPU_FEATURE (Fast_Rep_String)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memset_chk_sse2_rep)
-2:	ret
-END(__memset_chk)
-
-# ifdef SHARED
-strong_alias (__memset_chk, __memset_zero_constant_len_parameter)
-	.section .gnu.warning.__memset_zero_constant_len_parameter
-	.string "memset used with constant zero length parameter; this could be due to transposed parameters"
-# else
-	.text
-	.type __memset_chk_sse2, @function
-	.p2align 4;
-__memset_chk_sse2:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memset_sse2
-	cfi_endproc
-	.size __memset_chk_sse2, .-__memset_chk_sse2
-
-	.type __memset_chk_sse2_rep, @function
-	.p2align 4;
-__memset_chk_sse2_rep:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memset_sse2_rep
-	cfi_endproc
-	.size __memset_chk_sse2_rep, .-__memset_chk_sse2_rep
-
-	.type __memset_chk_ia32, @function
-	.p2align 4;
-__memset_chk_ia32:
-	cfi_startproc
-	CALL_MCOUNT
-	movl	12(%esp), %eax
-	cmpl	%eax, 16(%esp)
-	jb	__chk_fail
-	jmp	__memset_ia32
-	cfi_endproc
-	.size __memset_chk_ia32, .-__memset_chk_ia32
-# endif
-#endif
diff --git a/sysdeps/i386/i686/multiarch/rtld-memset.S b/sysdeps/i386/i686/multiarch/rtld-memset.S
new file mode 100644
index 0000000..fefbc63
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/rtld-memset.S
@@ -0,0 +1 @@
+#include <sysdeps/i386/i686/memset.S>
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
new file mode 100644
index 0000000..44fabed
--- /dev/null
+++ b/sysdeps/i386/multiarch/Makefile
@@ -0,0 +1,12 @@
+ifeq ($(subdir),csu)
+tests += test-multiarch
+gen-as-const-headers += ifunc-defines.sym
+endif
+
+ifeq ($(subdir),string)
+gen-as-const-headers += locale-defines.sym
+sysdep_routines += bzero-i386 bzero-i586 bzero-i686 \
+		   bzero-sse2 bzero-sse2-rep \
+		   memset-i386 memset-i586 memset-i686 \
+		   memset-sse2 memset-sse2-rep
+endif
diff --git a/sysdeps/i386/multiarch/bzero-i386.S b/sysdeps/i386/multiarch/bzero-i386.S
new file mode 100644
index 0000000..4a253d6
--- /dev/null
+++ b/sysdeps/i386/multiarch/bzero-i386.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/i586/multiarch/bzero-i386.S>
+
+#ifdef SHARED
+	.globl __GI_bzero
+	.hidden __GI_bzero
+	__GI_bzero = __bzero_i386
+#endif
diff --git a/sysdeps/i386/multiarch/bzero-i586.S b/sysdeps/i386/multiarch/bzero-i586.S
new file mode 100644
index 0000000..2d5b61a
--- /dev/null
+++ b/sysdeps/i386/multiarch/bzero-i586.S
@@ -0,0 +1,6 @@
+#define __bzero __bzero_i586
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/i586/bzero.S>
diff --git a/sysdeps/i386/multiarch/bzero-i686.S b/sysdeps/i386/multiarch/bzero-i686.S
new file mode 100644
index 0000000..aaa36ce
--- /dev/null
+++ b/sysdeps/i386/multiarch/bzero-i686.S
@@ -0,0 +1,6 @@
+#define __bzero __bzero_i686
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/i686/bzero.S>
diff --git a/sysdeps/i386/i686/multiarch/bzero-sse2-rep.S b/sysdeps/i386/multiarch/bzero-sse2-rep.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/bzero-sse2-rep.S
rename to sysdeps/i386/multiarch/bzero-sse2-rep.S
diff --git a/sysdeps/i386/i686/multiarch/bzero-sse2.S b/sysdeps/i386/multiarch/bzero-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/bzero-sse2.S
rename to sysdeps/i386/multiarch/bzero-sse2.S
diff --git a/sysdeps/i386/multiarch/bzero.c b/sysdeps/i386/multiarch/bzero.c
new file mode 100644
index 0000000..75fe9b8
--- /dev/null
+++ b/sysdeps/i386/multiarch/bzero.c
@@ -0,0 +1,63 @@
+/* Multiple versions of bzero.
+   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 lib.  */
+#if IS_IN (libc)
+/* Redefine bzero so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef bzero
+# define bzero __redirect_bzero
+# include <string.h>
+# undef bzero
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_bzero) __bzero_i386 attribute_hidden;
+extern __typeof (__redirect_bzero) __bzero_i586 attribute_hidden;
+extern __typeof (__redirect_bzero) __bzero_i686 attribute_hidden;
+extern __typeof (__redirect_bzero) __bzero_sse2 attribute_hidden;
+extern __typeof (__redirect_bzero) __bzero_sse2_rep attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_bzero) __bzero;
+extern void *bzero_ifunc (void) __asm__ ("__bzero");
+
+void *
+bzero_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Fast_Rep_String))
+	return __bzero_sse2_rep;
+      else
+	return __bzero_sse2;
+    }
+
+  if (USE_I686)
+    return __bzero_i686;
+  else if (USE_I586)
+    return __bzero_i586;
+  else
+    return __bzero_i386;
+}
+__asm__ (".type __bzero, %gnu_indirect_function");
+
+weak_alias (__bzero, bzero)
+#endif
diff --git a/sysdeps/i386/i686/multiarch/ifunc-defines.sym b/sysdeps/i386/multiarch/ifunc-defines.sym
similarity index 100%
rename from sysdeps/i386/i686/multiarch/ifunc-defines.sym
rename to sysdeps/i386/multiarch/ifunc-defines.sym
diff --git a/sysdeps/i386/i686/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
similarity index 94%
rename from sysdeps/i386/i686/multiarch/ifunc-impl-list.c
rename to sysdeps/i386/multiarch/ifunc-impl-list.c
index a6735a8..7bde24e 100644
--- a/sysdeps/i386/i686/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -1,5 +1,5 @@
-/* Enumerate available IFUNC implementations of a function.  i686 version.
-   Copyright (C) 2012-2015 Free Software Foundation, Inc.
+/* Enumerate available IFUNC implementations of a function.  i386 version.
+   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
@@ -36,6 +36,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 
   size_t i = 0;
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/bcopy.S.  */
   IFUNC_IMPL (i, name, bcopy,
 	      IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSSE3),
@@ -45,6 +46,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSE2),
 			      __bcopy_sse2_unaligned)
 	      IFUNC_IMPL_ADD (array, i, bcopy, 1, __bcopy_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/bzero.S.  */
   IFUNC_IMPL (i, name, bzero,
@@ -52,8 +54,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __bzero_sse2_rep)
 	      IFUNC_IMPL_ADD (array, i, bzero, HAS_CPU_FEATURE (SSE2),
 			      __bzero_sse2)
-	      IFUNC_IMPL_ADD (array, i, bzero, 1, __bzero_ia32))
+	      IFUNC_IMPL_ADD (array, i, bzero, HAS_I686, __bzero_i686)
+#if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, bzero, HAS_I586, __bzero_i586)
+	      IFUNC_IMPL_ADD (array, i, bzero, 1, __bzero_i386)
+#endif
+	      )
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/memchr.S.  */
   IFUNC_IMPL (i, name, memchr,
 	      IFUNC_IMPL_ADD (array, i, memchr, HAS_CPU_FEATURE (SSE2),
@@ -101,6 +109,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, memrchr, HAS_CPU_FEATURE (SSE2),
 			      __memrchr_sse2)
 	      IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/memset_chk.S.  */
   IFUNC_IMPL (i, name, __memset_chk,
@@ -110,8 +119,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, __memset_chk,
 			      HAS_CPU_FEATURE (SSE2),
 			      __memset_chk_sse2)
+	      IFUNC_IMPL_ADD (array, i, __memset_chk,
+			      HAS_I686, __memset_chk_i686)
+#if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, __memset_chk,
+			      HAS_I586, __memset_chk_i586)
 	      IFUNC_IMPL_ADD (array, i, __memset_chk, 1,
-			      __memset_chk_ia32))
+			      __memset_chk_i386)
+#endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/memset.S.  */
   IFUNC_IMPL (i, name, memset,
@@ -119,8 +135,16 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __memset_sse2_rep)
 	      IFUNC_IMPL_ADD (array, i, memset, HAS_CPU_FEATURE (SSE2),
 			      __memset_sse2)
-	      IFUNC_IMPL_ADD (array, i, memset, 1, __memset_ia32))
+	      IFUNC_IMPL_ADD (array, i, memset, HAS_I686,
+			      __memset_i686)
+#if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, memset, HAS_I586,
+			      __memset_i586)
+	      IFUNC_IMPL_ADD (array, i, memset, 1, __memset_i386)
+#endif
+	      )
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/rawmemchr.S.  */
   IFUNC_IMPL (i, name, rawmemchr,
 	      IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_CPU_FEATURE (SSE2),
@@ -371,6 +395,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strncmp_ssse3)
 	      IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_ia32))
 #endif
+#endif
 
   return i;
 }
diff --git a/sysdeps/i386/i686/multiarch/locale-defines.sym b/sysdeps/i386/multiarch/locale-defines.sym
similarity index 100%
rename from sysdeps/i386/i686/multiarch/locale-defines.sym
rename to sysdeps/i386/multiarch/locale-defines.sym
diff --git a/sysdeps/i386/multiarch/memset-i386.S b/sysdeps/i386/multiarch/memset-i386.S
new file mode 100644
index 0000000..860c756
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset-i386.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/i586/multiarch/memset-i386.S>
+
+#ifdef SHARED
+	.globl __GI_memset
+	.hidden __GI_memset
+	__GI_memset = __memset_i386
+#endif
diff --git a/sysdeps/i386/multiarch/memset-i586.S b/sysdeps/i386/multiarch/memset-i586.S
new file mode 100644
index 0000000..4c94fe4
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset-i586.S
@@ -0,0 +1,5 @@
+#define memset __memset_i586
+#define __memset_chk __memset_chk_i586
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/i586/memset.S>
diff --git a/sysdeps/i386/multiarch/memset-i686.S b/sysdeps/i386/multiarch/memset-i686.S
new file mode 100644
index 0000000..8d3462f
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset-i686.S
@@ -0,0 +1,5 @@
+#define memset __memset_i686
+#define __memset_chk __memset_chk_i686
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/i686/memset.S>
diff --git a/sysdeps/i386/i686/multiarch/memset-sse2-rep.S b/sysdeps/i386/multiarch/memset-sse2-rep.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memset-sse2-rep.S
rename to sysdeps/i386/multiarch/memset-sse2-rep.S
diff --git a/sysdeps/i386/i686/multiarch/memset-sse2.S b/sysdeps/i386/multiarch/memset-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memset-sse2.S
rename to sysdeps/i386/multiarch/memset-sse2.S
diff --git a/sysdeps/i386/multiarch/memset.c b/sysdeps/i386/multiarch/memset.c
new file mode 100644
index 0000000..49d7839
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset.c
@@ -0,0 +1,63 @@
+/* Multiple versions of memset.
+   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 lib.  */
+#if IS_IN (libc)
+/* Redefine memset so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef memset
+# define memset __redirect_memset
+# include <string.h>
+# undef memset
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_memset) __memset_i386 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_i586 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_i686 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_sse2 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_sse2_rep attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_memset) __memset;
+extern void *memset_ifunc (void) __asm__ ("__memset");
+
+void *
+memset_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Fast_Rep_String))
+	return __memset_sse2_rep;
+      else
+	return __memset_sse2;
+    }
+
+  if (USE_I686)
+    return __memset_i686;
+  else if (USE_I586)
+    return __memset_i586;
+  else
+    return __memset_i386;
+}
+__asm__ (".type __memset, %gnu_indirect_function");
+
+strong_alias (__memset, memset)
+#endif
diff --git a/sysdeps/i386/multiarch/memset_chk.c b/sysdeps/i386/multiarch/memset_chk.c
new file mode 100644
index 0000000..5e5c9b6
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset_chk.c
@@ -0,0 +1,101 @@
+/* Multiple versions of __memset_chk
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 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/>.  */
+
+/* Define multiple versions only for the definition in lib.  */
+#if IS_IN (libc)
+# include <stddef.h>
+extern void * __memset_chk (void *, int, size_t, size_t);
+
+# ifdef SHARED
+extern __typeof (__memset_chk) __memset_chk_i386 attribute_hidden;
+extern __typeof (__memset_chk) __memset_chk_i586 attribute_hidden;
+extern __typeof (__memset_chk) __memset_chk_i686 attribute_hidden;
+extern __typeof (__memset_chk) __memset_chk_sse2 attribute_hidden;
+extern __typeof (__memset_chk) __memset_chk_sse2_rep attribute_hidden;
+
+#  include <init-arch.h>
+# else
+/* Redefine memset so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+#  undef memset
+#  define memset __redirect_memset
+#  include <string.h>
+#  undef memset
+
+extern __typeof (__redirect_memset) __memset_i386 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_i586 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_i686 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_sse2 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_sse2_rep attribute_hidden;
+
+#  include <init-arch.h>
+
+/* Due to
+   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10837
+   noreturn attribute disable tail call optimization.  Removes noreturn
+   attribute to enable tail call optimization.  */
+extern void *chk_fail (void) __asm__ ("__chk_fail") attribute_hidden;
+
+#define ifunc_chk(func, arch) \
+static void *							\
+func##_chk_##arch (void *dstpp, int c, size_t len,		\
+		   size_t dstlen)				\
+{								\
+  if (__glibc_unlikely (dstlen < len))				\
+    return chk_fail ();						\
+  return func##_##arch (dstpp, c, len);				\
+}
+
+#  if MINIMUM_ISA < 686
+ifunc_chk (__memset, i386)
+ifunc_chk (__memset, i586)
+#  else
+extern __typeof (__redirect_memset) __memset_chk_i386 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_chk_i586 attribute_hidden;
+#  endif
+ifunc_chk (__memset, i686)
+ifunc_chk (__memset, sse2)
+ifunc_chk (__memset, sse2_rep)
+# endif
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern void *memset_chk_ifunc (void) __asm__ ("__memset_chk");
+
+void *
+memset_chk_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Fast_Unaligned_Load))
+	return __memset_chk_sse2_rep;
+      else
+	return __memset_chk_sse2;
+    }
+
+  if (USE_I686)
+    return __memset_chk_i686;
+  else if (USE_I586)
+    return __memset_chk_i586;
+  else
+    return __memset_chk_i386;
+}
+__asm__ (".type __memset_chk, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/i686/multiarch/test-multiarch.c b/sysdeps/i386/multiarch/test-multiarch.c
similarity index 100%
rename from sysdeps/i386/i686/multiarch/test-multiarch.c
rename to sysdeps/i386/multiarch/test-multiarch.c

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=12414bd20215ca896ec356bcb11579ba33e4d031

commit 12414bd20215ca896ec356bcb11579ba33e4d031
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Aug 18 13:45:25 2015 -0700

    Add i386 memset and memcpy assembly functions
    
    Add i386 memset and memcpy assembly functions with REP MOVSB/STOSB
    instructions.
    
    	* sysdeps/i386/bcopy.S: New file.
    	* sysdeps/i386/bzero.S: Likewise.
    	* sysdeps/i386/memcpy.S: Likewise.
    	* sysdeps/i386/memmove.S: Likewise.
    	* sysdeps/i386/mempcpy.S: Likewise.
    	* sysdeps/i386/memset.S: Likewise.
    	* sysdeps/i386/bzero.c: Removed.
    	* sysdeps/i386/memset.c: Likewise.
    	* sysdeps/i386/i586/memcpy_chk.S: Likewise.
    	* sysdeps/i386/i586/mempcpy_chk.S: Likewise.
    	* sysdeps/i386/i586/memset_chk.S: Likewise.
    	* sysdeps/i386/i686/memcpy_chk.S: Moved to ...
    	* sysdeps/i386/memcpy_chk.S: Here.
    	* sysdeps/i386/i686/memmove_chk.S: Moved to ...
    	* sysdeps/i386/memmove_chk.S: Here.
    	* sysdeps/i386/i686/mempcpy_chk.S: Moved to ...
    	* sysdeps/i386/mempcpy_chk.S: Likewise.
    	* sysdeps/i386/i686/memset_chk.S: Moved to ...
    	* sysdeps/i386/memset_chk.S: Likewise.

diff --git a/sysdeps/i386/bcopy.S b/sysdeps/i386/bcopy.S
new file mode 100644
index 0000000..12b8ddb
--- /dev/null
+++ b/sysdeps/i386/bcopy.S
@@ -0,0 +1,4 @@
+#define USE_AS_MEMMOVE
+#define USE_AS_BCOPY
+#define MEMCPY		bcopy
+#include "memcpy.S"
diff --git a/sysdeps/i386/bzero.S b/sysdeps/i386/bzero.S
new file mode 100644
index 0000000..c8dd47b
--- /dev/null
+++ b/sysdeps/i386/bzero.S
@@ -0,0 +1,5 @@
+#define USE_AS_BZERO
+#define memset __bzero
+#include "memset.S"
+
+weak_alias (__bzero, bzero)
diff --git a/sysdeps/i386/bzero.c b/sysdeps/i386/bzero.c
deleted file mode 100644
index 1a89444..0000000
--- a/sysdeps/i386/bzero.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* bzero -- set a block of memory to zero.  For Intel 80x86, x>=3.
-   This file is part of the GNU C Library.
-   Copyright (C) 1991-2015 Free Software Foundation, Inc.
-   Contributed by Torbjorn Granlund (tege@sics.se).
-
-   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 <string.h>
-#include <memcopy.h>
-
-#undef	bzero
-#undef	__bzero
-
-#ifdef	__GNUC__
-
-void
-__bzero (dstpp, len)
-     void *dstpp;
-     size_t len;
-{
-  /* N.B.: This code is almost verbatim from memset.c.  */
-  int d0;
-  unsigned long int dstp = (unsigned long int) dstpp;
-
-  /* This explicit register allocation
-     improves code very much indeed.  */
-  register op_t x asm ("ax");
-
-  x = 0;
-
-  /* Clear the direction flag, so filling will move forward.  */
-  asm volatile ("cld");
-
-  /* This threshold value is optimal.  */
-  if (len >= 12)
-    {
-      /* Adjust LEN for the bytes handled in the first loop.  */
-      len -= (-dstp) % OPSIZ;
-
-      /* There are at least some bytes to set.
-	 No need to test for LEN == 0 in this alignment loop.  */
-
-      /* Fill bytes until DSTP is aligned on a longword boundary.  */
-      asm volatile ("rep\n"
-		    "stosb" /* %0, %2, %3 */ :
-		    "=D" (dstp), "=c" (d0) :
-		    "0" (dstp), "1" ((-dstp) % OPSIZ), "a" (x) :
-		    "memory");
-
-      /* Fill longwords.  */
-      asm volatile ("rep\n"
-		    "stosl" /* %0, %2, %3 */ :
-		    "=D" (dstp), "=c" (d0) :
-		    "0" (dstp), "1" (len / OPSIZ), "a" (x) :
-		    "memory");
-      len %= OPSIZ;
-    }
-
-  /* Write the last few bytes.  */
-  asm volatile ("rep\n"
-		"stosb" /* %0, %2, %3 */ :
-		"=D" (dstp), "=c" (d0) :
-		"0" (dstp), "c" (len), "a" (x) :
-		"memory");
-}
-weak_alias (__bzero, bzero)
-
-#else
-#include <string/bzero.c>
-#endif
diff --git a/sysdeps/i386/i586/memcpy_chk.S b/sysdeps/i386/i586/memcpy_chk.S
deleted file mode 100644
index ab8a95c..0000000
--- a/sysdeps/i386/i586/memcpy_chk.S
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/i386/i686/memcpy_chk.S>
diff --git a/sysdeps/i386/i586/mempcpy_chk.S b/sysdeps/i386/i586/mempcpy_chk.S
deleted file mode 100644
index 9a1de1d..0000000
--- a/sysdeps/i386/i586/mempcpy_chk.S
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/i386/i686/mempcpy_chk.S>
diff --git a/sysdeps/i386/i586/memset_chk.S b/sysdeps/i386/i586/memset_chk.S
deleted file mode 100644
index 09f9d42..0000000
--- a/sysdeps/i386/i586/memset_chk.S
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/i386/i686/memset_chk.S>
diff --git a/sysdeps/i386/memcpy.S b/sysdeps/i386/memcpy.S
new file mode 100644
index 0000000..5f0196e
--- /dev/null
+++ b/sysdeps/i386/memcpy.S
@@ -0,0 +1,95 @@
+/* memcpy with REP MOVSB/STOSB
+   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 <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef MEMCPY
+# define MEMCPY		memcpy
+# define MEMCPY_CHK	__memcpy_chk
+#endif
+
+#ifdef USE_AS_BCOPY
+# define STR2		12
+# define STR1		STR2+4
+# define N     		STR1+4
+#else
+# define STR1		12
+# define STR2		STR1+4
+# define N     		STR2+4
+#endif
+
+#define CFI_PUSH(REG)						\
+  cfi_adjust_cfa_offset (4);					\
+  cfi_rel_offset (REG, 0)
+
+#define CFI_POP(REG)						\
+  cfi_adjust_cfa_offset (-4);					\
+  cfi_restore (REG)
+
+#define PUSH(REG)	pushl REG; CFI_PUSH (REG)
+#define POP(REG)	popl REG; CFI_POP (REG)
+
+	.text
+#if defined SHARED && IS_IN (libc) && !defined USE_AS_BCOPY
+ENTRY (MEMCPY_CHK)
+	movl	12(%esp), %eax
+	cmpl	%eax, 16(%esp)
+	jb	HIDDEN_JUMPTARGET (__chk_fail)
+END (MEMCPY_CHK)
+#endif
+ENTRY (MEMCPY)
+	PUSH	(%esi)
+	PUSH	(%edi)
+	movl	N(%esp), %ecx
+	movl	STR1(%esp), %edi
+	movl	STR2(%esp), %esi
+	mov	%edi, %eax
+#ifdef USE_AS_MEMPCPY
+	add	%ecx, %eax
+#endif
+
+#ifdef USE_AS_MEMMOVE
+	cmp	%esi, %edi
+	ja	L(copy_backward)
+	je	L(bwd_write_0bytes)
+#endif
+
+	rep	movsb
+	POP	(%edi)
+	POP	(%esi)
+	ret
+
+#ifdef USE_AS_MEMMOVE
+L(copy_backward):
+	lea	-1(%edi,%ecx), %edi
+	lea	-1(%esi,%ecx), %esi
+	std
+	rep	movsb
+	cld
+L(bwd_write_0bytes):
+	POP	(%edi)
+	POP	(%esi)
+	ret
+#endif
+
+END (MEMCPY)
+
+#ifndef USE_AS_BCOPY
+libc_hidden_builtin_def (MEMCPY)
+#endif
diff --git a/sysdeps/i386/i686/memcpy_chk.S b/sysdeps/i386/memcpy_chk.S
similarity index 92%
rename from sysdeps/i386/i686/memcpy_chk.S
rename to sysdeps/i386/memcpy_chk.S
index cdf807f..b3b25de 100644
--- a/sysdeps/i386/i686/memcpy_chk.S
+++ b/sysdeps/i386/memcpy_chk.S
@@ -1,4 +1,4 @@
-/* Checking memcpy for i686.
+/* Checking memcpy for i386.
    Copyright (C) 2004-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,10 +16,10 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include "asm-syntax.h"
+#ifndef SHARED
+# include <sysdep.h>
+# include "asm-syntax.h"
 
-#ifndef PIC
 	/* For libc.so this is defined in memcpy.S.
 	   For libc.a, this is a separate source to avoid
 	   memcpy bringing in __chk_fail and all routines
diff --git a/sysdeps/i386/memmove.S b/sysdeps/i386/memmove.S
new file mode 100644
index 0000000..60a45d2
--- /dev/null
+++ b/sysdeps/i386/memmove.S
@@ -0,0 +1,4 @@
+#define USE_AS_MEMMOVE
+#define MEMCPY		memmove
+#define MEMCPY_CHK	__memmove_chk
+#include "memcpy.S"
diff --git a/sysdeps/i386/i686/memmove_chk.S b/sysdeps/i386/memmove_chk.S
similarity index 78%
rename from sysdeps/i386/i686/memmove_chk.S
rename to sysdeps/i386/memmove_chk.S
index 64bf9e0..26d2abd 100644
--- a/sysdeps/i386/i686/memmove_chk.S
+++ b/sysdeps/i386/memmove_chk.S
@@ -1,4 +1,4 @@
-/* Checking memmove for x86-64.
+/* Checking memmove for i386
    Copyright (C) 2004-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,14 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include "asm-syntax.h"
+#ifndef SHARED
+# include <sysdep.h>
+# include "asm-syntax.h"
 
-#ifndef PIC
-	/* For libc.so this is defined in memmove.S.
-	   For libc.a, this is a separate source to avoid
-	   memmove bringing in __chk_fail and all routines
-	   it calls.  */
+/* For libc.so this is defined in memmove.S.  For libc.a, this is a
+   separate source to avoid memmove bringing in __chk_fail and all
+   routines it calls.  */
         .text
 ENTRY (__memmove_chk)
 	movl	12(%esp), %eax
diff --git a/sysdeps/i386/mempcpy.S b/sysdeps/i386/mempcpy.S
new file mode 100644
index 0000000..61addb7
--- /dev/null
+++ b/sysdeps/i386/mempcpy.S
@@ -0,0 +1,7 @@
+#define USE_AS_MEMPCPY
+#define MEMCPY		__mempcpy
+#define MEMCPY_CHK	__mempcpy_chk
+#include "memcpy.S"
+
+weak_alias (__mempcpy, mempcpy)
+libc_hidden_builtin_def (mempcpy)
diff --git a/sysdeps/i386/i686/mempcpy_chk.S b/sysdeps/i386/mempcpy_chk.S
similarity index 78%
rename from sysdeps/i386/i686/mempcpy_chk.S
rename to sysdeps/i386/mempcpy_chk.S
index a61757b..05f86c3 100644
--- a/sysdeps/i386/i686/mempcpy_chk.S
+++ b/sysdeps/i386/mempcpy_chk.S
@@ -1,4 +1,4 @@
-/* Checking mempcpy for x86-64.
+/* Checking mempcpy for i386
    Copyright (C) 2004-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,14 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include "asm-syntax.h"
+#ifndef SHARED
+# include <sysdep.h>
+# include "asm-syntax.h"
 
-#ifndef PIC
-	/* For libc.so this is defined in mempcpy.S.
-	   For libc.a, this is a separate source to avoid
-	   mempcpy bringing in __chk_fail and all routines
-	   it calls.  */
+/* For libc.so this is defined in mempcpy.S.  For libc.a, this is a
+   separate source to avoid mempcpy bringing in __chk_fail and all
+   routines it calls.  */
         .text
 ENTRY (__mempcpy_chk)
 	movl	12(%esp), %eax
diff --git a/sysdeps/i386/memset.S b/sysdeps/i386/memset.S
new file mode 100644
index 0000000..21b3430
--- /dev/null
+++ b/sysdeps/i386/memset.S
@@ -0,0 +1,68 @@
+/* memset with REP MOVSB/STOSB
+   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 <sysdep.h>
+
+#define CFI_PUSH(REG)						\
+  cfi_adjust_cfa_offset (4);					\
+  cfi_rel_offset (REG, 0)
+
+#define CFI_POP(REG)						\
+  cfi_adjust_cfa_offset (-4);					\
+  cfi_restore (REG)
+
+#define PUSH(REG)	pushl REG; CFI_PUSH (REG)
+#define POP(REG)	popl REG; CFI_POP (REG)
+
+#define STR1  8
+#ifdef USE_AS_BZERO
+#define N     STR1+4
+#else
+#define STR2  STR1+4
+#define N     STR2+4
+#endif
+
+	.text
+#if defined SHARED && IS_IN (libc) && !defined USE_AS_BZERO
+ENTRY (__memset_chk)
+	movl	12(%esp), %eax
+	cmpl	%eax, 16(%esp)
+	jb	HIDDEN_JUMPTARGET (__chk_fail)
+END (__memset_chk)
+#endif
+ENTRY (memset)
+	PUSH    (%edi)
+	movl	N(%esp), %ecx
+	movl	STR1(%esp), %edi
+#ifdef USE_AS_BZERO
+	xor	%eax, %eax
+#else
+	movzbl	STR2(%esp), %eax
+	mov	%edi, %edx
+#endif
+	rep	stosb
+#ifndef USE_AS_BZERO
+	mov	%edx, %eax
+#endif
+	POP     (%edi)
+	ret
+END (memset)
+
+#ifndef USE_AS_BZERO
+libc_hidden_builtin_def (memset)
+#endif
diff --git a/sysdeps/i386/memset.c b/sysdeps/i386/memset.c
deleted file mode 100644
index bf11590..0000000
--- a/sysdeps/i386/memset.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Set a block of memory to some byte value.
-   For Intel 80x86, x>=3.
-   Copyright (C) 1991-2015 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Torbjorn Granlund (tege@sics.se).
-
-   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 <string.h>
-#include <memcopy.h>
-
-#ifdef	__GNUC__
-
-#undef memset
-
-void *
-memset (void *dstpp, int c, size_t len)
-{
-  int d0;
-  unsigned long int dstp = (unsigned long int) dstpp;
-
-  /* This explicit register allocation
-     improves code very much indeed.  */
-  register op_t x asm("ax");
-
-  x = (unsigned char) c;
-
-  /* Clear the direction flag, so filling will move forward.  */
-  asm volatile("cld");
-
-  /* This threshold value is optimal.  */
-  if (len >= 12)
-    {
-      /* Fill X with four copies of the char we want to fill with.  */
-      x |= (x << 8);
-      x |= (x << 16);
-
-      /* Adjust LEN for the bytes handled in the first loop.  */
-      len -= (-dstp) % OPSIZ;
-
-      /* There are at least some bytes to set.
-	 No need to test for LEN == 0 in this alignment loop.  */
-
-      /* Fill bytes until DSTP is aligned on a longword boundary.  */
-      asm volatile("rep\n"
-		   "stosb" /* %0, %2, %3 */ :
-		   "=D" (dstp), "=c" (d0) :
-		   "0" (dstp), "1" ((-dstp) % OPSIZ), "a" (x) :
-		   "memory");
-
-      /* Fill longwords.  */
-      asm volatile("rep\n"
-		   "stosl" /* %0, %2, %3 */ :
-		   "=D" (dstp), "=c" (d0) :
-		   "0" (dstp), "1" (len / OPSIZ), "a" (x) :
-		   "memory");
-      len %= OPSIZ;
-    }
-
-  /* Write the last few bytes.  */
-  asm volatile("rep\n"
-	       "stosb" /* %0, %2, %3 */ :
-	       "=D" (dstp), "=c" (d0) :
-	       "0" (dstp), "1" (len), "a" (x) :
-	       "memory");
-
-  return dstpp;
-}
-libc_hidden_builtin_def (memset)
-
-#else
-#include <string/memset.c>
-#endif
diff --git a/sysdeps/i386/i686/memset_chk.S b/sysdeps/i386/memset_chk.S
similarity index 79%
rename from sysdeps/i386/i686/memset_chk.S
rename to sysdeps/i386/memset_chk.S
index da982fd..2312d32 100644
--- a/sysdeps/i386/i686/memset_chk.S
+++ b/sysdeps/i386/memset_chk.S
@@ -1,4 +1,4 @@
-/* Checking memset for i686.
+/* Checking memset for i386.
    Copyright (C) 2004-2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -16,14 +16,13 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include "asm-syntax.h"
-
 #ifndef SHARED
-	/* For libc.so this is defined in memset.S.
-	   For libc.a, this is a separate source to avoid
-	   memset bringing in __chk_fail and all routines
-	   it calls.  */
+# include <sysdep.h>
+# include "asm-syntax.h"
+
+/* For libc.so this is defined in memset.S.  For libc.a, this is a
+   separate source to avoid memset bringing in __chk_fail and all
+   routines it calls.  */
         .text
 ENTRY (__memset_chk)
 	movl	12(%esp), %eax

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=126d74c3a7a591eabfb0aa662bde85fa8d6764cc

commit 126d74c3a7a591eabfb0aa662bde85fa8d6764cc
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Aug 20 13:53:44 2015 -0700

    Add multiarch support to string/strcmp.c
    
    Change function name to STRCMP so that it can be renamed for multiarch.
    
    	* string/strcmp.c (STRCMP): New.  Defined as strcmp if not
    	defined.
    	(strcmp): Rennamed to ...
    	(STRCMP): This.

diff --git a/string/strcmp.c b/string/strcmp.c
index 4d4c044..501cda4 100644
--- a/string/strcmp.c
+++ b/string/strcmp.c
@@ -19,11 +19,15 @@
 
 #undef strcmp
 
+#ifndef STRCMP
+#define STRCMP strcmp
+#endif
+
 /* Compare S1 and S2, returning less than, equal to or
    greater than zero if S1 is lexicographically less than,
    equal to or greater than S2.  */
 int
-strcmp (const char *p1, const char *p2)
+STRCMP (const char *p1, const char *p2)
 {
   const unsigned char *s1 = (const unsigned char *) p1;
   const unsigned char *s2 = (const unsigned char *) p2;

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=194a86f2c14e6794d1fac70877b737888fc8ddd6

commit 194a86f2c14e6794d1fac70877b737888fc8ddd6
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Thu Aug 20 09:50:33 2015 -0700

    Replace MEMPCPY_P/PIC with USE_AS_MEMPCPY/SHARED
    
    Replace MEMPCPY_P with USE_AS_MEMPCPY in i586 memcpy.S to support i386
    multi-arch memcpy.  Also we should check SHARED not PIC for libc.so
    since libc.a may be compiled with PIC.
    
    	* sysdeps/i386/i586/memcpy.S (MEMPCPY_P): Removed.
    	Check USE_AS_MEMPCPY/SHARED instead of MEMPCPY_P/PIC.
    	* sysdeps/i386/i586/mempcpy.S (USE_AS_MEMPCPY): New.

diff --git a/sysdeps/i386/i586/memcpy.S b/sysdeps/i386/i586/memcpy.S
index 9797365..e0ac692 100644
--- a/sysdeps/i386/i586/memcpy.S
+++ b/sysdeps/i386/i586/memcpy.S
@@ -20,11 +20,6 @@
 #include <sysdep.h>
 #include "asm-syntax.h"
 
-/* BEWARE: `#ifdef memcpy' means that memcpy is redefined as `mempcpy',
-   and the return value is the byte after the last one copied in
-   the destination. */
-#define MEMPCPY_P (defined memcpy)
-
 #define PARMS	4+8	/* space for 2 saved regs */
 #define RTN	PARMS
 #define DEST	RTN
@@ -105,13 +100,13 @@ L(3):	movl	28(%edi), %edx
 
 	/* Correct extra loop counter modification.  */
 L(2):	addl	$32, %ecx
-#if !MEMPCPY_P
+#ifndef USE_AS_MEMPCPY
 	movl	DEST(%esp), %eax
 #endif
 
 L(1):	rep; movsb
 
-#if MEMPCPY_P
+#ifdef USE_AS_MEMPCPY
 	movl	%edi, %eax
 #endif
 
@@ -124,6 +119,6 @@ L(1):	rep; movsb
 
 	ret
 END (memcpy)
-#if !MEMPCPY_P
+#ifndef USE_AS_MEMPCPY
 libc_hidden_builtin_def (memcpy)
 #endif
diff --git a/sysdeps/i386/i586/mempcpy.S b/sysdeps/i386/i586/mempcpy.S
index afc112d..720a4c0 100644
--- a/sysdeps/i386/i586/mempcpy.S
+++ b/sysdeps/i386/i586/mempcpy.S
@@ -1,3 +1,4 @@
+#define USE_AS_MEMPCPY
 #define memcpy __mempcpy
 #define __memcpy_chk __mempcpy_chk
 #include <sysdeps/i386/i586/memcpy.S>

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=267ef01a18979dfdc035ad1ae09e3811ebbe26a1

commit 267ef01a18979dfdc035ad1ae09e3811ebbe26a1
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Aug 19 13:43:30 2015 -0700

    Replace BZERO_P/PIC with USE_AS_BZERO/SHARED
    
    Replace BZERO_P with USE_AS_BZERO in i586/i686 memset.S to support i386
    multi-arch memset.  Also we should check SHARED not PIC for libc.so
    since libc.a may be compiled with PIC.
    
    	* sysdeps/i386/i586/bzero.S (USE_AS_BZERO): New.
    	* sysdeps/i386/i686/bzero.S (USE_AS_BZERO): Likewise.
    	* sysdeps/i386/i586/memset.S (BZERO_P): Removed.
    	Check USE_AS_BZERO/SHARED instead of BZERO_P/PIC.
    	(__memset_zero_constant_len_parameter): New.
    	* sysdeps/i386/i686/memset.S (BZERO_P): Removed.
    	Check USE_AS_BZERO/SHARED instead of BZERO_P/PIC.
    	(__memset_zero_constant_len_parameter): Don't define if
    	__memset_chk or USE_AS_BZERO are defined.

diff --git a/sysdeps/i386/i586/bzero.S b/sysdeps/i386/i586/bzero.S
index 84d2f70..2a10671 100644
--- a/sysdeps/i386/i586/bzero.S
+++ b/sysdeps/i386/i586/bzero.S
@@ -1,3 +1,4 @@
+#define USE_AS_BZERO
 #define memset __bzero
 #include <sysdeps/i386/i586/memset.S>
 weak_alias (__bzero, bzero)
diff --git a/sysdeps/i386/i586/memset.S b/sysdeps/i386/i586/memset.S
index bc26501..82f7878 100644
--- a/sysdeps/i386/i586/memset.S
+++ b/sysdeps/i386/i586/memset.S
@@ -21,13 +21,10 @@
 #include <sysdep.h>
 #include "asm-syntax.h"
 
-/* BEWARE: `#ifdef memset' means that memset is redefined as `bzero' */
-#define BZERO_P (defined memset)
-
 #define PARMS	4+4	/* space for 1 saved reg */
 #define RTN	PARMS
 #define DEST	RTN
-#if BZERO_P
+#ifdef USE_AS_BZERO
 # define LEN	DEST+4
 #else
 # define CHR	DEST+4
@@ -35,7 +32,7 @@
 #endif
 
         .text
-#if defined PIC && IS_IN (libc) && !BZERO_P
+#if defined SHARED && IS_IN (libc) && !defined USE_AS_BZERO
 ENTRY (__memset_chk)
 	movl	12(%esp), %eax
 	cmpl	%eax, 16(%esp)
@@ -50,7 +47,7 @@ ENTRY (memset)
 	movl	DEST(%esp), %edi
 	cfi_rel_offset (edi, 0)
 	movl	LEN(%esp), %edx
-#if BZERO_P
+#ifdef USE_AS_BZERO
 	xorl	%eax, %eax	/* we fill with 0 */
 #else
 	movb	CHR(%esp), %al
@@ -104,7 +101,7 @@ L(2):	shrl	$2, %ecx	/* convert byte count to longword count */
 	rep
 	stosb
 
-#if !BZERO_P
+#ifndef USE_AS_BZERO
 	/* Load result (only if used as memset).  */
 	movl DEST(%esp), %eax	/* start address of destination is result */
 #endif
@@ -112,10 +109,13 @@ L(2):	shrl	$2, %ecx	/* convert byte count to longword count */
 	cfi_adjust_cfa_offset (-4)
 	cfi_restore (edi)
 
-#if BZERO_P
-	ret
-#else
 	ret
-#endif
 END (memset)
 libc_hidden_builtin_def (memset)
+
+#if defined SHARED && IS_IN (libc) && !defined __memset_chk \
+    && !defined USE_AS_BZERO
+strong_alias (__memset_chk, __memset_zero_constant_len_parameter)
+	.section .gnu.warning.__memset_zero_constant_len_parameter
+	.string "memset used with constant zero length parameter; this could be due to transposed parameters"
+#endif
diff --git a/sysdeps/i386/i686/bzero.S b/sysdeps/i386/i686/bzero.S
index 34b0faa..c7898f1 100644
--- a/sysdeps/i386/i686/bzero.S
+++ b/sysdeps/i386/i686/bzero.S
@@ -1,3 +1,4 @@
+#define USE_AS_BZERO
 #define memset __bzero
 #include <sysdeps/i386/i686/memset.S>
 weak_alias (__bzero, bzero)
diff --git a/sysdeps/i386/i686/memset.S b/sysdeps/i386/i686/memset.S
index b6dbf2a..86c3010 100644
--- a/sysdeps/i386/i686/memset.S
+++ b/sysdeps/i386/i686/memset.S
@@ -21,11 +21,8 @@
 #include <sysdep.h>
 #include "asm-syntax.h"
 
-/* BEWARE: `#ifdef memset' means that memset is redefined as `bzero' */
-#define BZERO_P (defined memset)
-
 #define PARMS	4+4	/* space for 1 saved reg */
-#if BZERO_P
+#ifdef USE_AS_BZERO
 # define DEST	PARMS
 # define LEN	DEST+4
 #else
@@ -36,7 +33,7 @@
 #endif
 
         .text
-#if defined PIC && IS_IN (libc) && !BZERO_P
+#if defined SHARED && IS_IN (libc) && !defined USE_AS_BZERO
 ENTRY_CHK (__memset_chk)
 	movl	12(%esp), %eax
 	cmpl	%eax, 16(%esp)
@@ -50,7 +47,7 @@ ENTRY (memset)
 	cfi_adjust_cfa_offset (4)
 	movl	DEST(%esp), %edx
 	movl	LEN(%esp), %ecx
-#if BZERO_P
+#ifdef USE_AS_BZERO
 	xorl	%eax, %eax	/* fill with 0 */
 #else
 	movzbl	CHR(%esp), %eax
@@ -74,7 +71,7 @@ ENTRY (memset)
 2:	movl	%ecx, %edx
 	shrl	$2, %ecx
 	andl	$3, %edx
-#if !BZERO_P
+#ifndef USE_AS_BZERO
 	imul	$0x01010101, %eax
 #endif
 	rep
@@ -84,22 +81,19 @@ ENTRY (memset)
 	stosb
 
 1:
-#if !BZERO_P
+#ifndef USE_AS_BZERO
 	movl DEST(%esp), %eax	/* start address of destination is result */
 #endif
 	popl	%edi
 	cfi_adjust_cfa_offset (-4)
 	cfi_restore (edi)
 
-#if BZERO_P
-	ret
-#else
 	ret
-#endif
 END (memset)
 libc_hidden_builtin_def (memset)
 
-#if defined PIC && IS_IN (libc) && !BZERO_P
+#if defined SHARED && IS_IN (libc) && !defined __memset_chk \
+    && !defined USE_AS_BZERO
 strong_alias (__memset_chk, __memset_zero_constant_len_parameter)
 	.section .gnu.warning.__memset_zero_constant_len_parameter
 	.string "memset used with constant zero length parameter; this could be due to transposed parameters"

http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=2ffe21439aa87a0fd83349997579884f137bd000

commit 2ffe21439aa87a0fd83349997579884f137bd000
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Mon Aug 17 10:19:05 2015 -0700

    Detect i586 and i686 features at run-time
    
    We detect i586 and i686 features at run-time by checking CX8 and CMOV
    CPUID features bits.  We can use these information to select the best
    implementation in ix86 multiarch.  Due to the reordering and the other
    nifty extensions in i686, it is not really good to use heavily i586
    optimized code on an i686.  It's better to use i486/i386 code if it
    isn't an i586.
    
    	* sysdeps/i386/init-arch.h: New file.
    	* sysdeps/i386/i486/init-arch.h: Likewise.
    	* sysdeps/i386/i586/init-arch.h: Likewise.
    	* sysdeps/i386/i686/init-arch.h: Likewise.
    	* sysdeps/x86/cpu-features.c (init_cpu_features): Set bit_I586
    	bit if CX8 is available.  Set bit_I686 bit if CMOV is available.
    	* sysdeps/x86/cpu-features.h (bit_I586): New.
    	(bit_I686): Likewise.
    	(bit_CX8): Likewise.
    	(bit_CMOV): Likewise.
    	(index_CX8): Likewise.
    	(index_CMOV): Likewise.
    	(index_I586): Likewise.
    	(index_I686): Likewise.
    	(reg_CX8): Likewise.
    	(reg_CMOV): Likewise.
    	(HAS_I586): Defined as HAS_ARCH_FEATURE (I586) if i586 isn't
    	available at compile-time.
    	(HAS_I686): Defined as HAS_ARCH_FEATURE (I686) if i686 isn't
    	available at compile-time.
    	* sysdeps/x86/init-arch.h (USE_I586): New macro.
    	(USE_I686): Likewise.

diff --git a/sysdeps/x86/init-arch.h b/sysdeps/i386/i486/init-arch.h
similarity index 78%
copy from sysdeps/x86/init-arch.h
copy to sysdeps/i386/i486/init-arch.h
index 2b9988e..0c74ddc 100644
--- a/sysdeps/x86/init-arch.h
+++ b/sysdeps/i386/i486/init-arch.h
@@ -1,5 +1,5 @@
-/* This file is part of the GNU C Library.
-   Copyright (C) 2008-2015 Free Software Foundation, Inc.
+/* 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
@@ -15,8 +15,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifdef  __ASSEMBLER__
-# include <cpu-features.h>
-#else
-# include <ldsodefs.h>
-#endif
+#define MINIMUM_ISA 486
+#include <sysdeps/x86/init-arch.h>
diff --git a/sysdeps/x86/init-arch.h b/sysdeps/i386/i586/init-arch.h
similarity index 78%
copy from sysdeps/x86/init-arch.h
copy to sysdeps/i386/i586/init-arch.h
index 2b9988e..50c43a2 100644
--- a/sysdeps/x86/init-arch.h
+++ b/sysdeps/i386/i586/init-arch.h
@@ -1,5 +1,5 @@
-/* This file is part of the GNU C Library.
-   Copyright (C) 2008-2015 Free Software Foundation, Inc.
+/* 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
@@ -15,8 +15,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifdef  __ASSEMBLER__
-# include <cpu-features.h>
-#else
-# include <ldsodefs.h>
-#endif
+#define MINIMUM_ISA 586
+#include <sysdeps/x86/init-arch.h>
diff --git a/sysdeps/x86/init-arch.h b/sysdeps/i386/i686/init-arch.h
similarity index 78%
copy from sysdeps/x86/init-arch.h
copy to sysdeps/i386/i686/init-arch.h
index 2b9988e..b4a2735 100644
--- a/sysdeps/x86/init-arch.h
+++ b/sysdeps/i386/i686/init-arch.h
@@ -1,5 +1,5 @@
-/* This file is part of the GNU C Library.
-   Copyright (C) 2008-2015 Free Software Foundation, Inc.
+/* 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
@@ -15,8 +15,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifdef  __ASSEMBLER__
-# include <cpu-features.h>
-#else
-# include <ldsodefs.h>
-#endif
+#define MINIMUM_ISA 686
+#include <sysdeps/x86/init-arch.h>
diff --git a/sysdeps/x86/init-arch.h b/sysdeps/i386/init-arch.h
similarity index 78%
copy from sysdeps/x86/init-arch.h
copy to sysdeps/i386/init-arch.h
index 2b9988e..9adb451 100644
--- a/sysdeps/x86/init-arch.h
+++ b/sysdeps/i386/init-arch.h
@@ -1,5 +1,5 @@
-/* This file is part of the GNU C Library.
-   Copyright (C) 2008-2015 Free Software Foundation, Inc.
+/* 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
@@ -15,8 +15,5 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#ifdef  __ASSEMBLER__
-# include <cpu-features.h>
-#else
-# include <ldsodefs.h>
-#endif
+#define MINIMUM_ISA 386
+#include <sysdeps/x86/init-arch.h>
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index 40575de..b03451d 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -150,6 +150,14 @@ init_cpu_features (struct cpu_features *cpu_features)
   else
     kind = arch_kind_other;
 
+  /* Support i586 if CX8 is available.  */
+  if (HAS_CPU_FEATURE (CX8))
+    cpu_features->feature[index_I586] |= bit_I586;
+
+  /* Support i686 if CMOV is available.  */
+  if (HAS_CPU_FEATURE (CMOV))
+    cpu_features->feature[index_I686] |= bit_I686;
+
   if (cpu_features->max_cpuid >= 7)
     __cpuid_count (7, 0,
 		   cpu_features->cpuid[COMMON_CPUID_INDEX_7].eax,
diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/cpu-features.h
index 6e70624..80edbee 100644
--- a/sysdeps/x86/cpu-features.h
+++ b/sysdeps/x86/cpu-features.h
@@ -31,10 +31,14 @@
 #define bit_AVX_Fast_Unaligned_Load	(1 << 11)
 #define bit_AVX512F_Usable		(1 << 12)
 #define bit_AVX512DQ_Usable		(1 << 13)
+#define bit_I586			(1 << 14)
+#define bit_I686			(1 << 15)
 
 /* CPUID Feature flags.  */
 
 /* COMMON_CPUID_INDEX_1.  */
+#define bit_CX8		(1 << 8)
+#define bit_CMOV	(1 << 15)
 #define bit_SSE2	(1 << 26)
 #define bit_SSSE3	(1 << 9)
 #define bit_SSE4_1	(1 << 19)
@@ -69,6 +73,8 @@
 # include <ifunc-defines.h>
 # include <rtld-global-offsets.h>
 
+# define index_CX8	COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_EDX_OFFSET
+# define index_CMOV	COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_EDX_OFFSET
 # define index_SSE2	COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_EDX_OFFSET
 # define index_SSSE3	COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET
 # define index_SSE4_1	COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET
@@ -89,6 +95,8 @@
 # define index_AVX_Fast_Unaligned_Load	FEATURE_INDEX_1*FEATURE_SIZE
 # define index_AVX512F_Usable		FEATURE_INDEX_1*FEATURE_SIZE
 # define index_AVX512DQ_Usable		FEATURE_INDEX_1*FEATURE_SIZE
+# define index_I586			FEATURE_INDEX_1*FEATURE_SIZE
+# define index_I686			FEATURE_INDEX_1*FEATURE_SIZE
 
 # if defined (_LIBC) && !IS_IN (nonlib)
 #  ifdef __x86_64__
@@ -193,6 +201,8 @@ extern const struct cpu_features *__get_cpu_features (void)
 # define HAS_ARCH_FEATURE(name) \
   ((__get_cpu_features ()->feature[index_##name] & (bit_##name)) != 0)
 
+# define index_CX8		COMMON_CPUID_INDEX_1
+# define index_CMOV		COMMON_CPUID_INDEX_1
 # define index_SSE2		COMMON_CPUID_INDEX_1
 # define index_SSSE3		COMMON_CPUID_INDEX_1
 # define index_SSE4_1		COMMON_CPUID_INDEX_1
@@ -207,6 +217,8 @@ extern const struct cpu_features *__get_cpu_features (void)
 # define index_POPCOUNT		COMMON_CPUID_INDEX_1
 # define index_OSXSAVE		COMMON_CPUID_INDEX_1
 
+# define reg_CX8		edx
+# define reg_CMOV		edx
 # define reg_SSE2		edx
 # define reg_SSSE3		ecx
 # define reg_SSE4_1		ecx
@@ -234,6 +246,8 @@ extern const struct cpu_features *__get_cpu_features (void)
 # define index_AVX_Fast_Unaligned_Load	FEATURE_INDEX_1
 # define index_AVX512F_Usable		FEATURE_INDEX_1
 # define index_AVX512DQ_Usable		FEATURE_INDEX_1
+# define index_I586			FEATURE_INDEX_1
+# define index_I686			FEATURE_INDEX_1
 
 #endif	/* !__ASSEMBLER__ */
 
@@ -242,7 +256,7 @@ extern const struct cpu_features *__get_cpu_features (void)
 #elif defined __i586__ || defined __pentium__
 # define HAS_CPUID 1
 # define HAS_I586 1
-# define HAS_I686 0
+# define HAS_I686 HAS_ARCH_FEATURE (I686)
 #elif (defined __i686__ || defined __pentiumpro__		\
        || defined __pentium4__ || defined __nocona__		\
        || defined __atom__ || defined __core2__			\
@@ -261,8 +275,8 @@ extern const struct cpu_features *__get_cpu_features (void)
 # define HAS_I686 1
 #else
 # define HAS_CPUID 0
-# define HAS_I586 0
-# define HAS_I686 0
+# define HAS_I586 HAS_ARCH_FEATURE (I586)
+# define HAS_I686 HAS_ARCH_FEATURE (I686)
 #endif
 
 #endif  /* cpu_features_h */
diff --git a/sysdeps/x86/init-arch.h b/sysdeps/x86/init-arch.h
index 2b9988e..1257fd1 100644
--- a/sysdeps/x86/init-arch.h
+++ b/sysdeps/x86/init-arch.h
@@ -20,3 +20,16 @@
 #else
 # include <ldsodefs.h>
 #endif
+
+#ifndef __x86_64__
+/* Due to the reordering and the other nifty extensions in i686, it is
+   not really good to use heavily i586 optimized code on an i686.  It's
+   better to use i486/i386 code if it isn't an i586.  */
+# if MINIMUM_ISA == 686
+#  define USE_I586 0
+#  define USE_I686 1
+# else
+#  define USE_I586 (HAS_ARCH_FEATURE (I586) && !HAS_ARCH_FEATURE (I686))
+#  define USE_I686 HAS_ARCH_FEATURE (I686)
+# endif
+#endif

-----------------------------------------------------------------------


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]