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-127-g04f8695


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  04f86950e1439b8e71e1ca251741265658a84816 (commit)

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

commit 04f86950e1439b8e71e1ca251741265658a84816
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/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 147258c..ba6a489 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 73cd46d..015ad3c 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -191,7 +191,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,
@@ -200,7 +199,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,
@@ -211,8 +210,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),
@@ -228,6 +228,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,
@@ -235,8 +236,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 !SUPPORT_I686
+	      IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_i386)
 #endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/strcpy.S.  */
   IFUNC_IMPL (i, name, strcpy,
@@ -256,6 +260,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,
@@ -266,7 +271,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,
@@ -277,8 +282,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),
@@ -451,6 +457,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,
@@ -458,8 +465,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..f5931bf
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcmp-i386.c
@@ -0,0 +1,10 @@
+#include <init-arch.h>
+#if !SUPPORT_I686
+# ifdef SHARED
+#  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"
+#endif
diff --git a/sysdeps/i386/multiarch/strcmp-i686.S b/sysdeps/i386/multiarch/strcmp-i686.S
new file mode 100644
index 0000000..c031500
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcmp-i686.S
@@ -0,0 +1,16 @@
+#include <init-arch.h>
+#ifdef SHARED
+# define strcmp __strcmp_i686
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+#endif
+
+#if SUPPORT_I686 || defined SHARED
+#include <sysdeps/i386/i686/strcmp.S>
+#endif
+
+#if SUPPORT_I686 && defined SHARED
+	.globl __GI_strcmp
+	.hidden __GI_strcmp
+	__GI_strcmp = __strcmp_i686
+#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..58049e8
--- /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 (HAS_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=7fe145945d39cf47c93dce41dd104b7f18a8e986

commit 7fe145945d39cf47c93dce41dd104b7f18a8e986
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=20e63db1befbee2fd570d765e4ac1803f00373db

commit 20e63db1befbee2fd570d765e4ac1803f00373db
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/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/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index ad8c864..147258c 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 b026cb8..73cd46d 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -171,14 +171,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,
@@ -186,8 +185,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 !SUPPORT_I586
+	      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,
@@ -232,6 +236,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,
@@ -239,8 +244,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 !SUPPORT_I586
+	      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),
@@ -276,6 +286,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,
@@ -283,8 +294,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..d64e2bf
--- /dev/null
+++ b/sysdeps/i386/multiarch/rtld-stpcpy.S
@@ -0,0 +1,24 @@
+/* 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 <init-arch.h>
+#if SUPPORT_I586
+# include <sysdeps/i386/i586/stpcpy.S>
+#else
+# include <sysdeps/i386/stpcpy.S>
+#endif
diff --git a/sysdeps/i386/multiarch/stpcpy-i386.S b/sysdeps/i386/multiarch/stpcpy-i386.S
new file mode 100644
index 0000000..2b73cf8
--- /dev/null
+++ b/sysdeps/i386/multiarch/stpcpy-i386.S
@@ -0,0 +1,15 @@
+#include <init-arch.h>
+#if !SUPPORT_I586
+# 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>
+
+	.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..2f8fed8
--- /dev/null
+++ b/sysdeps/i386/multiarch/stpcpy-i586.S
@@ -0,0 +1,15 @@
+#include <init-arch.h>
+#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>
+
+#if SUPPORT_I586
+	.globl __GI_stpcpy
+	.hidden __GI_stpcpy
+	__GI_stpcpy = __stpcpy_i586
+#endif
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..e4f75c4
--- /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 (HAS_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..abeb071
--- /dev/null
+++ b/sysdeps/i386/multiarch/stpncpy-i386.S
@@ -0,0 +1,11 @@
+#include <init-arch.h>
+#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>
+
+	.globl __GI___stpncpy
+	.hidden __GI___stpncpy
+	__GI___stpncpy = __stpncpy_i386
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..a98f4d2
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcpy-i386.c
@@ -0,0 +1,13 @@
+#include <init-arch.h>
+#if !SUPPORT_I586
+# undef libc_hidden_builtin_def
+# ifdef SHARED
+#  define libc_hidden_builtin_def(name)  \
+    __hidden_ver1 (__strcpy_i386, __GI_strcpy, __strcpy_i386);
+# else
+#  define libc_hidden_builtin_def(name)
+# endif
+#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..0aa67bf
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcpy-i586.S
@@ -0,0 +1,11 @@
+#include <init-arch.h>
+#define strcpy __strcpy_i586
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/i586/strcpy.S>
+
+#if SUPPORT_I586
+	.globl __GI_strcpy
+	.hidden __GI_strcpy
+	__GI_strcpy = __strcpy_i586
+#endif
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..72daf1e
--- /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 (HAS_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=878b4ec6b69bf55b93f5f487c78c135e24e78557

commit 878b4ec6b69bf55b93f5f487c78c135e24e78557
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/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 9026e09..ad8c864 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=b47c1cd361f6be83ef34f8e298861f190ae992a1

commit b47c1cd361f6be83ef34f8e298861f190ae992a1
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=aa4525274b266c45d005b6d8a1b6f034b26cf549

commit aa4525274b266c45d005b6d8a1b6f034b26cf549
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/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 601039a..9026e09 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 16f50b8..b026cb8 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -163,15 +163,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=b9410a6e7560dba9682fbe51ef69b646a111a0b2

commit b9410a6e7560dba9682fbe51ef69b646a111a0b2
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/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 375f66c..601039a 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 1c9ae6a..16f50b8 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -118,15 +118,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=f7b58b910dba24e8fd00b47f70f334ff0d068d87

commit f7b58b910dba24e8fd00b47f70f334ff0d068d87
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/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index c9508a2..375f66c 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 680e467..1c9ae6a 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -73,15 +73,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 !SUPPORT_I686
+	      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..bdc1b1d
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcmp-i386.S
@@ -0,0 +1,15 @@
+#include <init-arch.h>
+#if !SUPPORT_I686
+# 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
+#endif
diff --git a/sysdeps/i386/multiarch/memcmp-i686.S b/sysdeps/i386/multiarch/memcmp-i686.S
new file mode 100644
index 0000000..e2cc40a
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcmp-i686.S
@@ -0,0 +1,15 @@
+#include <init-arch.h>
+#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>
+
+#ifdef SHARED
+# if SUPPORT_I686
+	.globl __GI_memcmp
+	.hidden __GI_memcmp
+	__GI_memcmp = __memcmp_i686
+# endif
+#endif
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..a0cd039
--- /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 (HAS_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..89466a5
--- /dev/null
+++ b/sysdeps/i386/multiarch/rtld-memcmp.S
@@ -0,0 +1,24 @@
+/* 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 <init-arch.h>
+#if SUPPORT_I686
+# include <sysdeps/i386/i686/memcmp.S>
+#else
+# include <sysdeps/i386/memcmp.S>
+#endif

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

commit 29eab15d8cb8a4324c523aac71ade9e7ed33f2d7
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/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 63a61d8..c9508a2 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -18,4 +18,5 @@ 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
 endif
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 18f17e4..680e467 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -65,15 +65,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=8b9887641de415d236e571d18141f130d169d513

commit 8b9887641de415d236e571d18141f130d169d513
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/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/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index cb96d46..63a61d8 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 \
+		   static-memmove \
+		   mempcpy-i386 mempcpy-i586 mempcpy-i686 \
+		   mempcpy-sse2-unaligned mempcpy-ssse3 mempcpy-ssse3-rep \
+		   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..ad85776
--- /dev/null
+++ b/sysdeps/i386/multiarch/bcopy-i386.S
@@ -0,0 +1,15 @@
+#include <init-arch.h>
+#if !SUPPORT_I686
+# 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
+#endif
diff --git a/sysdeps/i386/multiarch/bcopy-i686.S b/sysdeps/i386/multiarch/bcopy-i686.S
new file mode 100644
index 0000000..9fc09a3
--- /dev/null
+++ b/sysdeps/i386/multiarch/bcopy-i686.S
@@ -0,0 +1,15 @@
+#include <init-arch.h>
+#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>
+
+#ifdef SHARED
+# if SUPPORT_I686
+	.globl __GI_bcopy
+	.hidden __GI_bcopy
+	__GI_bcopy = __bcopy_i686
+# endif
+#endif
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..21ecf62
--- /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 (HAS_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 87d2080..18f17e4 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 !SUPPORT_I686
+	      IFUNC_IMPL_ADD (array, i, bcopy, 1, __bcopy_i386)
 #endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/bzero.S.  */
   IFUNC_IMPL (i, name, bzero,
@@ -79,6 +81,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,
@@ -91,8 +94,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 !SUPPORT_I686
 	      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,
@@ -102,8 +110,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 !SUPPORT_I686
+	      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),
@@ -335,6 +348,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.  */
@@ -348,8 +362,17 @@ __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 !SUPPORT_I686
+	      IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_I586,
+			      __memcpy_chk_i586)
+#  if !SUPPORT_I586
 	      IFUNC_IMPL_ADD (array, i, __memcpy_chk, 1,
-			      __memcpy_chk_ia32))
+			      __memcpy_chk_i386)
+#  endif
+# endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/memcpy.S.  */
   IFUNC_IMPL (i, name, memcpy,
@@ -359,7 +382,14 @@ __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 !SUPPORT_I686
+	      IFUNC_IMPL_ADD (array, i, memcpy, HAS_I586, __memcpy_i586)
+#  if !SUPPORT_I586
+	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_i386)
+#  endif
+# endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/mempcpy_chk.S.  */
   IFUNC_IMPL (i, name, __mempcpy_chk,
@@ -372,8 +402,17 @@ __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 !SUPPORT_I686
+	      IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_I586,
+			      __mempcpy_chk_i586)
+#  if !SUPPORT_I586
 	      IFUNC_IMPL_ADD (array, i, __mempcpy_chk, 1,
-			      __mempcpy_chk_ia32))
+			      __mempcpy_chk_i386)
+#  endif
+# endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/mempcpy.S.  */
   IFUNC_IMPL (i, name, mempcpy,
@@ -383,8 +422,16 @@ __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 !SUPPORT_I686
+	      IFUNC_IMPL_ADD (array, i, mempcpy, HAS_I586, __mempcpy_i586)
+#  if !SUPPORT_I586
+	      IFUNC_IMPL_ADD (array, i, mempcpy, 1, __mempcpy_i386)
+#  endif
+# 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..b3f022d
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcpy-i386.S
@@ -0,0 +1,14 @@
+#ifdef SHARED
+# include <init-arch.h>
+# if !SUPPORT_I586 && !SUPPORT_I686
+#  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
+#endif
diff --git a/sysdeps/i386/multiarch/memcpy-i586.S b/sysdeps/i386/multiarch/memcpy-i586.S
new file mode 100644
index 0000000..35162d2
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcpy-i586.S
@@ -0,0 +1,16 @@
+#ifdef SHARED
+# include <init-arch.h>
+# if !SUPPORT_I686
+#  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>
+
+#  if SUPPORT_I586
+	.globl __GI_memcpy
+	.hidden __GI_memcpy
+	__GI_memcpy = __memcpy_i586
+#  endif
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/memcpy-i686.S b/sysdeps/i386/multiarch/memcpy-i686.S
new file mode 100644
index 0000000..c0bf4a4
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcpy-i686.S
@@ -0,0 +1,14 @@
+#ifdef SHARED
+# include <init-arch.h>
+# 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>
+
+# if SUPPORT_I686
+	.globl __GI_memcpy
+	.hidden __GI_memcpy
+	__GI_memcpy = __memcpy_i686
+# endif
+#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..bb3f84a
--- /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 (HAS_I686)
+    return __memcpy_i686;
+  else if (HAS_I586)
+    return __memcpy_i586;
+  else
+    return __memcpy_i386;
+}
+__asm__ (".type memcpy, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memcpy_chk.S b/sysdeps/i386/multiarch/memcpy_chk.S
similarity index 84%
rename from sysdeps/i386/i686/multiarch/memcpy_chk.S
rename to sysdeps/i386/multiarch/memcpy_chk.S
index 3bbd921..c5e95b4 100644
--- a/sysdeps/i386/i686/multiarch/memcpy_chk.S
+++ b/sysdeps/i386/multiarch/memcpy_chk.S
@@ -18,19 +18,29 @@
    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)
+# include <sysdep.h>
+# include <init-arch.h>
+
 # 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)
+# if !SUPPORT_I686
+#  if !SUPPORT_I586
+	LOAD_FUNC_GOT_EAX (__memcpy_chk_i386)
+	HAS_ARCH_FEATURE (I586)
+	jz	2f
+#  endif
+	LOAD_FUNC_GOT_EAX (__memcpy_chk_i586)
+	HAS_ARCH_FEATURE (I686)
+	jz	2f
+# endif
+	LOAD_FUNC_GOT_EAX (__memcpy_chk_i686)
 	HAS_CPU_FEATURE (SSE2)
 	jz	2f
 	LOAD_FUNC_GOT_EAX (__memcpy_chk_sse2_unaligned)
diff --git a/sysdeps/i386/multiarch/memmove-i386.S b/sysdeps/i386/multiarch/memmove-i386.S
new file mode 100644
index 0000000..d19cb1f
--- /dev/null
+++ b/sysdeps/i386/multiarch/memmove-i386.S
@@ -0,0 +1,14 @@
+#ifdef SHARED
+# include <init-arch.h>
+# if !SUPPORT_I686
+#  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
+#endif
diff --git a/sysdeps/i386/multiarch/memmove-i686.S b/sysdeps/i386/multiarch/memmove-i686.S
new file mode 100644
index 0000000..1ed5c6b
--- /dev/null
+++ b/sysdeps/i386/multiarch/memmove-i686.S
@@ -0,0 +1,14 @@
+#ifdef SHARED
+# include <init-arch.h>
+# 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>
+
+# if SUPPORT_I686
+	.globl __GI_memmove
+	.hidden __GI_memmvoe
+	__GI_memmove = __memmove i686
+# endif
+#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..6082844
--- /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 (HAS_I686)
+    return __memmove_i686;
+  else
+    return __memmove_i386;
+}
+__asm__ (".type memmove, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memmove_chk.S b/sysdeps/i386/multiarch/memmove_chk.S
similarity index 80%
rename from sysdeps/i386/i686/multiarch/memmove_chk.S
rename to sysdeps/i386/multiarch/memmove_chk.S
index b17f6ed..15e47d5 100644
--- a/sysdeps/i386/i686/multiarch/memmove_chk.S
+++ b/sysdeps/i386/multiarch/memmove_chk.S
@@ -18,16 +18,21 @@
    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)
+# include <sysdep.h>
+# include <init-arch.h>
+
 	.text
 ENTRY(__memmove_chk)
 	.type	__memmove_chk, @gnu_indirect_function
 	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memmove_chk_ia32)
+# if !SUPPORT_I686
+	LOAD_FUNC_GOT_EAX (__memmove_chk_i386)
+	HAS_ARCH_FEATURE (I686)
+	jz	2f
+# endif
+	LOAD_FUNC_GOT_EAX (__memmove_chk_i686)
 	HAS_CPU_FEATURE (SSE2)
 	jz	2f
 	LOAD_FUNC_GOT_EAX (__memmove_chk_sse2_unaligned)
@@ -79,16 +84,30 @@ __memmove_chk_ssse3_rep:
 	cfi_endproc
 	.size __memmove_chk_ssse3_rep, .-__memmove_chk_ssse3_rep
 
-	.type __memmove_chk_ia32, @function
+	.type __memmove_chk_i686, @function
+	.p2align 4;
+__memmove_chk_i686:
+	cfi_startproc
+	CALL_MCOUNT
+	movl	12(%esp), %eax
+	cmpl	%eax, 16(%esp)
+	jb	__chk_fail
+	jmp	__memmove_i686
+	cfi_endproc
+	.size __memmove_chk_i686, .-__memmove_chk_i686
+
+#  if !SUPPORT_I686
+	.type __memmove_chk_i386, @function
 	.p2align 4;
-__memmove_chk_ia32:
+__memmove_chk_i386:
 	cfi_startproc
 	CALL_MCOUNT
 	movl	12(%esp), %eax
 	cmpl	%eax, 16(%esp)
 	jb	__chk_fail
-	jmp	__memmove_ia32
+	jmp	__memmove_i386
 	cfi_endproc
-	.size __memmove_chk_ia32, .-__memmove_chk_ia32
+	.size __memmove_chk_i386, .-__memmove_chk_i386
+#  endif
 # endif
 #endif
diff --git a/sysdeps/i386/multiarch/mempcpy-i386.S b/sysdeps/i386/multiarch/mempcpy-i386.S
new file mode 100644
index 0000000..8070f8d
--- /dev/null
+++ b/sysdeps/i386/multiarch/mempcpy-i386.S
@@ -0,0 +1,21 @@
+#ifdef SHARED
+# include <init-arch.h>
+# if !SUPPORT_I586 && !SUPPORT_I686
+#  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
+#endif
diff --git a/sysdeps/i386/multiarch/mempcpy-i586.S b/sysdeps/i386/multiarch/mempcpy-i586.S
new file mode 100644
index 0000000..408ae5e
--- /dev/null
+++ b/sysdeps/i386/multiarch/mempcpy-i586.S
@@ -0,0 +1,23 @@
+#ifdef SHARED
+# include <init-arch.h>
+# if !SUPPORT_I686
+#  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>
+
+#  if SUPPORT_I586
+	.globl __GI_mempcpy
+	.hidden __GI_mempcpy
+	__GI_mempcpy = __mempcpy_i586
+	.globl __GI___mempcpy
+	.hidden __GI___mempcpy 
+	__GI___mempcpy = __mempcpy_i586
+#  endif
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/mempcpy-i686.S b/sysdeps/i386/multiarch/mempcpy-i686.S
new file mode 100644
index 0000000..f27c7a9
--- /dev/null
+++ b/sysdeps/i386/multiarch/mempcpy-i686.S
@@ -0,0 +1,21 @@
+#ifdef SHARED
+# include <init-arch.h>
+# 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>
+
+# if SUPPORT_I686
+	.globl __GI_mempcpy
+	.hidden __GI_mempcpy
+	__GI_mempcpy = __mempcpy_i686
+	.globl __GI___mempcpy
+	.hidden __GI___mempcpy 
+	__GI___mempcpy = __mempcpy_i686
+# endif
+#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..150f407
--- /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 (HAS_I686)
+    return __mempcpy_i686;
+  else if (HAS_I586)
+    return __mempcpy_i586;
+  else
+    return __mempcpy_i386;
+}
+__asm__ (".type __mempcpy, %gnu_indirect_function");
+weak_alias (__mempcpy, mempcpy)
+#endif
diff --git a/sysdeps/i386/i686/multiarch/mempcpy_chk.S b/sysdeps/i386/multiarch/mempcpy_chk.S
similarity index 84%
rename from sysdeps/i386/i686/multiarch/mempcpy_chk.S
rename to sysdeps/i386/multiarch/mempcpy_chk.S
index 1bea6ea..a0f0b67 100644
--- a/sysdeps/i386/i686/multiarch/mempcpy_chk.S
+++ b/sysdeps/i386/multiarch/mempcpy_chk.S
@@ -18,19 +18,29 @@
    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)
+# include <sysdep.h>
+# include <init-arch.h>
+
 # 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)
+# if !SUPPORT_I686
+#  if !SUPPORT_I586
+	LOAD_FUNC_GOT_EAX (__mempcpy_chk_i386)
+	HAS_ARCH_FEATURE (I586)
+	jz	2f
+#  endif
+	LOAD_FUNC_GOT_EAX (__mempcpy_chk_i586)
+	HAS_ARCH_FEATURE (I686)
+	jz	2f
+# endif
+	LOAD_FUNC_GOT_EAX (__mempcpy_chk_i686)
 	HAS_CPU_FEATURE (SSE2)
 	jz	2f
 	LOAD_FUNC_GOT_EAX (__mempcpy_chk_sse2_unaligned)
diff --git a/sysdeps/i386/multiarch/rtld-memmove.S b/sysdeps/i386/multiarch/rtld-memmove.S
new file mode 100644
index 0000000..efbbd21
--- /dev/null
+++ b/sysdeps/i386/multiarch/rtld-memmove.S
@@ -0,0 +1,24 @@
+/* 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 <init-arch.h>
+#if SUPPORT_I686
+# include <sysdeps/i386/i686/memmove.S>
+#else
+# include <sysdeps/i386/memmove.S>
+#endif
diff --git a/sysdeps/i386/multiarch/static-memmove.S b/sysdeps/i386/multiarch/static-memmove.S
new file mode 100644
index 0000000..4debbbe
--- /dev/null
+++ b/sysdeps/i386/multiarch/static-memmove.S
@@ -0,0 +1,26 @@
+/* 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 <init-arch.h>
+# if SUPPORT_I686
+#  include <sysdeps/i386/i686/memmove.S>
+# else
+#  include <sysdeps/i386/memmove.S>
+# endif
+#endif

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

commit 7d7da0efaca7c080d2ad5623324e2bedba1583e9
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/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
new file mode 100644
index 0000000..cb96d46
--- /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..a59b2f1
--- /dev/null
+++ b/sysdeps/i386/multiarch/bzero-i386.S
@@ -0,0 +1,15 @@
+#include <init-arch.h>
+#if !SUPPORT_I586 && !SUPPORT_I686
+# 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>
+
+# ifdef SHARED
+	.globl __GI_bzero
+	.hidden __GI_bzero
+	__GI_bzero = __bzero_i386
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/bzero-i586.S b/sysdeps/i386/multiarch/bzero-i586.S
new file mode 100644
index 0000000..24a0ab7
--- /dev/null
+++ b/sysdeps/i386/multiarch/bzero-i586.S
@@ -0,0 +1,17 @@
+#include <init-arch.h>
+#if !SUPPORT_I686
+# 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>
+
+# ifdef SHARED
+# if SUPPORT_I586
+	.globl __GI_bzero
+	.hidden __GI_bzero
+	__GI_bzero = __bzero_i586
+#  endif
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/bzero-i686.S b/sysdeps/i386/multiarch/bzero-i686.S
new file mode 100644
index 0000000..0711988
--- /dev/null
+++ b/sysdeps/i386/multiarch/bzero-i686.S
@@ -0,0 +1,15 @@
+#include <init-arch.h>
+#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>
+
+#ifdef SHARED
+# if SUPPORT_I686
+	.globl __GI_bzero
+	.hidden __GI_bzero
+	__GI_bzero = __bzero_i686
+# endif
+#endif
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..8de71be
--- /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 (HAS_I686)
+    return __bzero_i686;
+  else if (HAS_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/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
new file mode 100644
index 0000000..87d2080
--- /dev/null
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -0,0 +1,407 @@
+/* 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
+   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 <assert.h>
+#include <string.h>
+#include <wchar.h>
+#include <ifunc-impl-list.h>
+#include "init-arch.h"
+
+/* Maximum number of IFUNC implementations.  */
+#define MAX_IFUNC	4
+
+/* Fill ARRAY of MAX elements with IFUNC implementations for function
+   NAME and return the number of valid entries.  */
+
+size_t
+__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+			size_t max)
+{
+  assert (max >= MAX_IFUNC);
+
+  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),
+			      __bcopy_ssse3_rep)
+	      IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSSE3),
+			      __bcopy_ssse3)
+	      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,
+	      IFUNC_IMPL_ADD (array, i, bzero, HAS_CPU_FEATURE (SSE2),
+			      __bzero_sse2_rep)
+	      IFUNC_IMPL_ADD (array, i, bzero, HAS_CPU_FEATURE (SSE2),
+			      __bzero_sse2)
+	      IFUNC_IMPL_ADD (array, i, bzero, HAS_I686, __bzero_i686)
+#if !SUPPORT_I686
+	      IFUNC_IMPL_ADD (array, i, bzero, HAS_I586, __bzero_i586)
+# if !SUPPORT_I586
+	      IFUNC_IMPL_ADD (array, i, bzero, 1, __bzero_i386)
+# endif
+#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))
+
+  /* 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))
+
+  /* Support sysdeps/i386/i686/multiarch/memmove_chk.S.  */
+  IFUNC_IMPL (i, name, __memmove_chk,
+	      IFUNC_IMPL_ADD (array, i, __memmove_chk,
+			      HAS_CPU_FEATURE (SSSE3),
+			      __memmove_chk_ssse3_rep)
+	      IFUNC_IMPL_ADD (array, i, __memmove_chk,
+			      HAS_CPU_FEATURE (SSSE3),
+			      __memmove_chk_ssse3)
+	      IFUNC_IMPL_ADD (array, i, __memmove_chk,
+			      HAS_CPU_FEATURE (SSE2),
+			      __memmove_chk_sse2_unaligned)
+	      IFUNC_IMPL_ADD (array, i, __memmove_chk, 1,
+			      __memmove_chk_ia32))
+
+  /* Support sysdeps/i386/i686/multiarch/memmove.S.  */
+  IFUNC_IMPL (i, name, memmove,
+	      IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSSE3),
+			      __memmove_ssse3_rep)
+	      IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSSE3),
+			      __memmove_ssse3)
+	      IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSE2),
+			      __memmove_sse2_unaligned)
+	      IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ia32))
+
+  /* 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
+
+  /* Support sysdeps/i386/i686/multiarch/memset_chk.S.  */
+  IFUNC_IMPL (i, name, __memset_chk,
+	      IFUNC_IMPL_ADD (array, i, __memset_chk,
+			      HAS_CPU_FEATURE (SSE2),
+			      __memset_chk_sse2_rep)
+	      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 !SUPPORT_I686
+	      IFUNC_IMPL_ADD (array, i, __memset_chk,
+			      HAS_I586, __memset_chk_i586)
+# if !SUPPORT_I586
+	      IFUNC_IMPL_ADD (array, i, __memset_chk, 1,
+			      __memset_chk_i386)
+# endif
+#endif
+	      )
+
+  /* Support sysdeps/i386/i686/multiarch/memset.S.  */
+  IFUNC_IMPL (i, name, memset,
+	      IFUNC_IMPL_ADD (array, i, memset, HAS_CPU_FEATURE (SSE2),
+			      __memset_sse2_rep)
+	      IFUNC_IMPL_ADD (array, i, memset, HAS_CPU_FEATURE (SSE2),
+			      __memset_sse2)
+	      IFUNC_IMPL_ADD (array, i, memset, HAS_I686,
+			      __memset_i686)
+#if !SUPPORT_I686
+	      IFUNC_IMPL_ADD (array, i, memset, HAS_I586,
+			      __memset_i586)
+# if !SUPPORT_I586
+	      IFUNC_IMPL_ADD (array, i, memset, 1, __memset_i386)
+# endif
+#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))
+
+  /* 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))
+
+  /* Support sysdeps/i386/i686/multiarch/stpcpy.S.  */
+  IFUNC_IMPL (i, name, stpcpy,
+	      IFUNC_IMPL_ADD (array, i, stpcpy, HAS_CPU_FEATURE (SSSE3),
+			      __stpcpy_ssse3)
+	      IFUNC_IMPL_ADD (array, i, stpcpy, HAS_CPU_FEATURE (SSE2),
+			      __stpcpy_sse2)
+	      IFUNC_IMPL_ADD (array, i, stpcpy, 1, __stpcpy_ia32))
+
+  /* Support sysdeps/i386/i686/multiarch/strcasecmp.S.  */
+  IFUNC_IMPL (i, name, strcasecmp,
+	      IFUNC_IMPL_ADD (array, i, strcasecmp,
+			      HAS_CPU_FEATURE (SSE4_2),
+			      __strcasecmp_sse4_2)
+	      IFUNC_IMPL_ADD (array, i, strcasecmp,
+			      HAS_CPU_FEATURE (SSSE3),
+			      __strcasecmp_ssse3)
+	      IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_ia32))
+
+  /* Support sysdeps/i386/i686/multiarch/strcasecmp_l.S.  */
+  IFUNC_IMPL (i, name, strcasecmp_l,
+	      IFUNC_IMPL_ADD (array, i, strcasecmp_l,
+			      HAS_CPU_FEATURE (SSE4_2),
+			      __strcasecmp_l_sse4_2)
+	      IFUNC_IMPL_ADD (array, i, strcasecmp_l,
+			      HAS_CPU_FEATURE (SSSE3),
+			      __strcasecmp_l_ssse3)
+	      IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1,
+			      __strcasecmp_l_ia32))
+
+  /* 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))
+
+  /* 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))
+
+  /* Support sysdeps/i386/i686/multiarch/strcmp.S.  */
+  IFUNC_IMPL (i, name, strcmp,
+	      IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSE4_2),
+			      __strcmp_sse4_2)
+	      IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSSE3),
+			      __strcmp_ssse3)
+	      IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_ia32))
+
+  /* Support sysdeps/i386/i686/multiarch/strcpy.S.  */
+  IFUNC_IMPL (i, name, strcpy,
+	      IFUNC_IMPL_ADD (array, i, strcpy, HAS_CPU_FEATURE (SSSE3),
+			      __strcpy_ssse3)
+	      IFUNC_IMPL_ADD (array, i, strcpy, HAS_CPU_FEATURE (SSE2),
+			      __strcpy_sse2)
+	      IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_ia32))
+
+  /* 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))
+
+  /* Support sysdeps/i386/i686/multiarch/strncase.S.  */
+  IFUNC_IMPL (i, name, strncasecmp,
+	      IFUNC_IMPL_ADD (array, i, strncasecmp,
+			      HAS_CPU_FEATURE (SSE4_2),
+			      __strncasecmp_sse4_2)
+	      IFUNC_IMPL_ADD (array, i, strncasecmp,
+			      HAS_CPU_FEATURE (SSSE3),
+			      __strncasecmp_ssse3)
+	      IFUNC_IMPL_ADD (array, i, strncasecmp, 1,
+			      __strncasecmp_ia32))
+
+  /* Support sysdeps/i386/i686/multiarch/strncase_l.S.  */
+  IFUNC_IMPL (i, name, strncasecmp_l,
+	      IFUNC_IMPL_ADD (array, i, strncasecmp_l,
+			      HAS_CPU_FEATURE (SSE4_2),
+			      __strncasecmp_l_sse4_2)
+	      IFUNC_IMPL_ADD (array, i, strncasecmp_l,
+			      HAS_CPU_FEATURE (SSSE3),
+			      __strncasecmp_l_ssse3)
+	      IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1,
+			      __strncasecmp_l_ia32))
+
+  /* Support sysdeps/i386/i686/multiarch/strncat.S.  */
+  IFUNC_IMPL (i, name, strncat,
+	      IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSSE3),
+			      __strncat_ssse3)
+	      IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSE2),
+			      __strncat_sse2)
+	      IFUNC_IMPL_ADD (array, i, strncat, 1, __strncat_ia32))
+
+  /* Support sysdeps/i386/i686/multiarch/strncpy.S.  */
+  IFUNC_IMPL (i, name, strncpy,
+	      IFUNC_IMPL_ADD (array, i, strncpy, HAS_CPU_FEATURE (SSSE3),
+			      __strncpy_ssse3)
+	      IFUNC_IMPL_ADD (array, i, strncpy, HAS_CPU_FEATURE (SSE2),
+			      __strncpy_sse2)
+	      IFUNC_IMPL_ADD (array, i, strncpy, 1, __strncpy_ia32))
+
+  /* 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))
+
+  /* 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))
+
+  /* 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))
+
+  /* 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))
+
+  /* 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))
+
+  /* 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))
+
+  /* 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))
+
+  /* Support sysdeps/i386/i686/multiarch/wcslen.S.  */
+  IFUNC_IMPL (i, name, wcslen,
+	      IFUNC_IMPL_ADD (array, i, wcslen, HAS_CPU_FEATURE (SSE2),
+			      __wcslen_sse2)
+	      IFUNC_IMPL_ADD (array, i, wcslen, 1, __wcslen_ia32))
+
+  /* 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))
+
+  /* Support sysdeps/i386/i686/multiarch/wmemcmp.S.  */
+  IFUNC_IMPL (i, name, wmemcmp,
+	      IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSE4_2),
+			      __wmemcmp_sse4_2)
+	      IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSSE3),
+			      __wmemcmp_ssse3)
+	      IFUNC_IMPL_ADD (array, i, wmemcmp, 1, __wmemcmp_ia32))
+
+#ifdef SHARED
+  /* Support sysdeps/i386/i686/multiarch/memcpy_chk.S.  */
+  IFUNC_IMPL (i, name, __memcpy_chk,
+	      IFUNC_IMPL_ADD (array, i, __memcpy_chk,
+			      HAS_CPU_FEATURE (SSSE3),
+			      __memcpy_chk_ssse3_rep)
+	      IFUNC_IMPL_ADD (array, i, __memcpy_chk,
+			      HAS_CPU_FEATURE (SSSE3),
+			      __memcpy_chk_ssse3)
+	      IFUNC_IMPL_ADD (array, i, __memcpy_chk,
+			      HAS_CPU_FEATURE (SSE2),
+			      __memcpy_chk_sse2_unaligned)
+	      IFUNC_IMPL_ADD (array, i, __memcpy_chk, 1,
+			      __memcpy_chk_ia32))
+
+  /* Support sysdeps/i386/i686/multiarch/memcpy.S.  */
+  IFUNC_IMPL (i, name, memcpy,
+	      IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSSE3),
+			      __memcpy_ssse3_rep)
+	      IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSSE3),
+			      __memcpy_ssse3)
+	      IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSE2),
+			      __memcpy_sse2_unaligned)
+	      IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ia32))
+
+  /* Support sysdeps/i386/i686/multiarch/mempcpy_chk.S.  */
+  IFUNC_IMPL (i, name, __mempcpy_chk,
+	      IFUNC_IMPL_ADD (array, i, __mempcpy_chk,
+			      HAS_CPU_FEATURE (SSSE3),
+			      __mempcpy_chk_ssse3_rep)
+	      IFUNC_IMPL_ADD (array, i, __mempcpy_chk,
+			      HAS_CPU_FEATURE (SSSE3),
+			      __mempcpy_chk_ssse3)
+	      IFUNC_IMPL_ADD (array, i, __mempcpy_chk,
+			      HAS_CPU_FEATURE (SSE2),
+			      __mempcpy_chk_sse2_unaligned)
+	      IFUNC_IMPL_ADD (array, i, __mempcpy_chk, 1,
+			      __mempcpy_chk_ia32))
+
+  /* Support sysdeps/i386/i686/multiarch/mempcpy.S.  */
+  IFUNC_IMPL (i, name, mempcpy,
+	      IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSSE3),
+			      __mempcpy_ssse3_rep)
+	      IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSSE3),
+			      __mempcpy_ssse3)
+	      IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSE2),
+			      __mempcpy_sse2_unaligned)
+	      IFUNC_IMPL_ADD (array, i, mempcpy, 1, __mempcpy_ia32))
+
+  /* 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))
+
+  /* Support sysdeps/i386/i686/multiarch/strncmp.S.  */
+  IFUNC_IMPL (i, name, strncmp,
+	      IFUNC_IMPL_ADD (array, i, strncmp, HAS_CPU_FEATURE (SSE4_2),
+			      __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
+#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..1790a44
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset-i386.S
@@ -0,0 +1,14 @@
+#include <init-arch.h>
+#if !SUPPORT_I586 && !SUPPORT_I686
+# 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>
+
+# ifdef SHARED
+	.globl __GI_memset
+	.hidden __GI_memset
+	__GI_memset = __memset_i386
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/memset-i586.S b/sysdeps/i386/multiarch/memset-i586.S
new file mode 100644
index 0000000..961a1cf
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset-i586.S
@@ -0,0 +1,16 @@
+#include <init-arch.h>
+#if !SUPPORT_I686
+# 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>
+
+# ifdef SHARED
+#  if SUPPORT_I586
+	.globl __GI_memset
+	.hidden __GI_memset
+	__GI_memset = __memset_i586
+#  endif
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/memset-i686.S b/sysdeps/i386/multiarch/memset-i686.S
new file mode 100644
index 0000000..9ef9eea
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset-i686.S
@@ -0,0 +1,14 @@
+#include <init-arch.h>
+#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>
+
+#ifdef SHARED
+# if SUPPORT_I686
+	.globl __GI_memset
+	.hidden __GI_memset
+	__GI_memset = __memset_i686
+# endif
+#endif
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..d35f720
--- /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 (HAS_I686)
+    return __memset_i686;
+  else if (HAS_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.S b/sysdeps/i386/multiarch/memset_chk.S
new file mode 100644
index 0000000..350f0d1
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset_chk.S
@@ -0,0 +1,113 @@
+/* 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/>.  */
+
+/* Define multiple versions only for the definition in lib.  */
+#if IS_IN (libc)
+# include <sysdep.h>
+# include <init-arch.h>
+
+	.text
+ENTRY(__memset_chk)
+	.type	__memset_chk, @gnu_indirect_function
+	LOAD_GOT_AND_RTLD_GLOBAL_RO
+# if !SUPPORT_I686
+	LOAD_FUNC_GOT_EAX (__memset_chk_i386)
+	HAS_ARCH_FEATURE (I686)
+	jz	2f
+# endif
+	LOAD_FUNC_GOT_EAX (__memset_chk_i686)
+	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_i686, @function
+	.p2align 4;
+__memset_chk_i686:
+	cfi_startproc
+	CALL_MCOUNT
+	movl	12(%esp), %eax
+	cmpl	%eax, 16(%esp)
+	jb	__chk_fail
+	jmp	__memset_i686
+	cfi_endproc
+	.size __memset_chk_i686, .-__memset_chk_i686
+
+	.type __memset_chk_i586, @function
+	.p2align 4;
+__memset_chk_i586:
+	cfi_startproc
+	CALL_MCOUNT
+	movl	12(%esp), %eax
+	cmpl	%eax, 16(%esp)
+	jb	__chk_fail
+	jmp	__memset_i586
+	cfi_endproc
+	.size __memset_chk_i586, .-__memset_chk_i586
+
+#  if !SUPPORT_I686
+	.type __memset_chk_i386, @function
+	.p2align 4;
+__memset_chk_i386:
+	cfi_startproc
+	CALL_MCOUNT
+	movl	12(%esp), %eax
+	cmpl	%eax, 16(%esp)
+	jb	__chk_fail
+	jmp	__memset_i386
+	cfi_endproc
+	.size __memset_chk_i386, .-__memset_chk_i386
+#  endif
+# endif
+#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=946c7560df4e17131d827d614d1bf7a9452132a6

commit 946c7560df4e17131d827d614d1bf7a9452132a6
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=64005474fb0a34ba72b0acd0dd2a1ab369409fbc

commit 64005474fb0a34ba72b0acd0dd2a1ab369409fbc
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=3baf7dacf518ea97e1268f230befbf13f9a86ba9

commit 3baf7dacf518ea97e1268f230befbf13f9a86ba9
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/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/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=afa529c867d677f9f5ab5223ca76d92f7ac5a5c3

commit afa529c867d677f9f5ab5223ca76d92f7ac5a5c3
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.  HAS_I586 and HAS_I686 are changed
    run-time check.  SUPPORT_I586 and SUPPORT_I686 are added for
    compile-time check.
    
    	* 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): Renamed to ...
    	(SUPPORT_I586): This.
    	(HAS_I686): Renamed to ...
    	(SUPPORT_I686): This.
    	(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.

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..2c0a3fd 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,9 @@ 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)
+# define SUPPORT_I586 1
+# define SUPPORT_I686 0
 #elif (defined __i686__ || defined __pentiumpro__		\
        || defined __pentium4__ || defined __nocona__		\
        || defined __atom__ || defined __core2__			\
@@ -259,10 +275,14 @@ extern const struct cpu_features *__get_cpu_features (void)
 # define HAS_CPUID 1
 # define HAS_I586 1
 # define HAS_I686 1
+# define SUPPORT_I586 1
+# define SUPPORT_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)
+# define SUPPORT_I586 0
+# define SUPPORT_I686 0
 #endif
 
 #endif  /* cpu_features_h */

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


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]