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-212-gf75ad15


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  f75ad150d9051d467cfd25405d968aa50ad38a51 (commit)

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

commit f75ad150d9051d467cfd25405d968aa50ad38a51
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Aug 26 04:20:42 2015 -0700

    Add i386 math multiarch functions

diff --git a/sysdeps/i386/i686/fpu/multiarch/Makefile b/sysdeps/i386/fpu/multiarch/Makefile
similarity index 54%
rename from sysdeps/i386/i686/fpu/multiarch/Makefile
rename to sysdeps/i386/fpu/multiarch/Makefile
index 7d90892..300758f 100644
--- a/sysdeps/i386/i686/fpu/multiarch/Makefile
+++ b/sysdeps/i386/fpu/multiarch/Makefile
@@ -1,4 +1,4 @@
 ifeq ($(subdir),math)
-libm-sysdep_routines += e_expf-sse2 e_expf-ia32 s_sinf-sse2 s_cosf-sse2 \
+libm-sysdep_routines += e_expf-sse2 e_expf-i386 s_sinf-sse2 s_cosf-sse2 \
                         s_sincosf-sse2
 endif
diff --git a/sysdeps/i386/i686/fpu/multiarch/e_expf-ia32.S b/sysdeps/i386/fpu/multiarch/e_expf-i386.S
similarity index 90%
rename from sysdeps/i386/i686/fpu/multiarch/e_expf-ia32.S
rename to sysdeps/i386/fpu/multiarch/e_expf-i386.S
index 8ceb172..3a7eb5d 100644
--- a/sysdeps/i386/i686/fpu/multiarch/e_expf-ia32.S
+++ b/sysdeps/i386/fpu/multiarch/e_expf-i386.S
@@ -16,7 +16,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#define __ieee754_expf __ieee754_expf_ia32
-#define __expf_finite __expf_finite_ia32
+#define __ieee754_expf __ieee754_expf_i386
+#define __expf_finite __expf_finite_i386
 
 #include <sysdeps/i386/fpu/e_expf.S>
diff --git a/sysdeps/i386/i686/fpu/multiarch/e_expf-sse2.S b/sysdeps/i386/fpu/multiarch/e_expf-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/fpu/multiarch/e_expf-sse2.S
rename to sysdeps/i386/fpu/multiarch/e_expf-sse2.S
diff --git a/sysdeps/i386/i686/fpu/multiarch/e_expf.c b/sysdeps/i386/fpu/multiarch/e_expf.c
similarity index 88%
rename from sysdeps/i386/i686/fpu/multiarch/e_expf.c
rename to sysdeps/i386/fpu/multiarch/e_expf.c
index 6978883..773812d 100644
--- a/sysdeps/i386/i686/fpu/multiarch/e_expf.c
+++ b/sysdeps/i386/fpu/multiarch/e_expf.c
@@ -19,19 +19,19 @@
 #include <init-arch.h>
 
 extern double __ieee754_expf_sse2 (double);
-extern double __ieee754_expf_ia32 (double);
+extern double __ieee754_expf_i386 (double);
 
 double __ieee754_expf (double);
 libm_ifunc (__ieee754_expf,
 	    HAS_CPU_FEATURE (SSE2)
 	    ? __ieee754_expf_sse2
-	    : __ieee754_expf_ia32);
+	    : __ieee754_expf_i386);
 
 extern double __expf_finite_sse2 (double);
-extern double __expf_finite_ia32 (double);
+extern double __expf_finite_i386 (double);
 
 double __expf_finite (double);
 libm_ifunc (__expf_finite,
 	    HAS_CPU_FEATURE (SSE2)
 	    ? __expf_finite_sse2
-	    : __expf_finite_ia32);
+	    : __expf_finite_i386);
diff --git a/sysdeps/i386/i686/fpu/multiarch/s_cosf-sse2.S b/sysdeps/i386/fpu/multiarch/s_cosf-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/fpu/multiarch/s_cosf-sse2.S
rename to sysdeps/i386/fpu/multiarch/s_cosf-sse2.S
diff --git a/sysdeps/i386/i686/fpu/multiarch/s_cosf.c b/sysdeps/i386/fpu/multiarch/s_cosf.c
similarity index 93%
rename from sysdeps/i386/i686/fpu/multiarch/s_cosf.c
rename to sysdeps/i386/fpu/multiarch/s_cosf.c
index e32b2f4..1a9c3e8 100644
--- a/sysdeps/i386/i686/fpu/multiarch/s_cosf.c
+++ b/sysdeps/i386/fpu/multiarch/s_cosf.c
@@ -19,11 +19,11 @@
 #include <init-arch.h>
 
 extern float __cosf_sse2 (float);
-extern float __cosf_ia32 (float);
+extern float __cosf_i386 (float);
 float __cosf (float);
 
-libm_ifunc (__cosf, HAS_CPU_FEATURE (SSE2) ? __cosf_sse2 : __cosf_ia32);
+libm_ifunc (__cosf, HAS_CPU_FEATURE (SSE2) ? __cosf_sse2 : __cosf_i386);
 weak_alias (__cosf, cosf);
 
-#define COSF __cosf_ia32
+#define COSF __cosf_i386
 #include <sysdeps/ieee754/flt-32/s_cosf.c>
diff --git a/sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S b/sysdeps/i386/fpu/multiarch/s_sincosf-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/fpu/multiarch/s_sincosf-sse2.S
rename to sysdeps/i386/fpu/multiarch/s_sincosf-sse2.S
diff --git a/sysdeps/i386/i686/fpu/multiarch/s_sincosf.c b/sysdeps/i386/fpu/multiarch/s_sincosf.c
similarity index 87%
rename from sysdeps/i386/i686/fpu/multiarch/s_sincosf.c
rename to sysdeps/i386/fpu/multiarch/s_sincosf.c
index 0d827e0..2132d47 100644
--- a/sysdeps/i386/i686/fpu/multiarch/s_sincosf.c
+++ b/sysdeps/i386/fpu/multiarch/s_sincosf.c
@@ -19,12 +19,12 @@
 #include <init-arch.h>
 
 extern void __sincosf_sse2 (float, float *, float *);
-extern void __sincosf_ia32 (float, float *, float *);
+extern void __sincosf_i386 (float, float *, float *);
 void __sincosf (float, float *, float *);
 
 libm_ifunc (__sincosf,
-	    HAS_CPU_FEATURE (SSE2) ? __sincosf_sse2 : __sincosf_ia32);
+	    HAS_CPU_FEATURE (SSE2) ? __sincosf_sse2 : __sincosf_i386);
 weak_alias (__sincosf, sincosf);
 
-#define SINCOSF __sincosf_ia32
+#define SINCOSF __sincosf_i386
 #include <sysdeps/ieee754/flt-32/s_sincosf.c>
diff --git a/sysdeps/i386/i686/fpu/multiarch/s_sinf-sse2.S b/sysdeps/i386/fpu/multiarch/s_sinf-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/fpu/multiarch/s_sinf-sse2.S
rename to sysdeps/i386/fpu/multiarch/s_sinf-sse2.S
diff --git a/sysdeps/i386/i686/fpu/multiarch/s_sinf.c b/sysdeps/i386/fpu/multiarch/s_sinf.c
similarity index 93%
rename from sysdeps/i386/i686/fpu/multiarch/s_sinf.c
rename to sysdeps/i386/fpu/multiarch/s_sinf.c
index 18afaa2..b4e0b7d 100644
--- a/sysdeps/i386/i686/fpu/multiarch/s_sinf.c
+++ b/sysdeps/i386/fpu/multiarch/s_sinf.c
@@ -19,10 +19,10 @@
 #include <init-arch.h>
 
 extern float __sinf_sse2 (float);
-extern float __sinf_ia32 (float);
+extern float __sinf_i386 (float);
 float __sinf (float);
 
-libm_ifunc (__sinf, HAS_CPU_FEATURE (SSE2) ? __sinf_sse2 : __sinf_ia32);
+libm_ifunc (__sinf, HAS_CPU_FEATURE (SSE2) ? __sinf_sse2 : __sinf_i386);
 weak_alias (__sinf, sinf);
-#define SINF __sinf_ia32
+#define SINF __sinf_i386
 #include <sysdeps/ieee754/flt-32/s_sinf.c>

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

commit 8988d795a0e71b3473f20eceafd44ae0b93f4bcd
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Aug 25 07:45:24 2015 -0700

    Add i386 wmemcmp multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
deleted file mode 100644
index 3e078b7..0000000
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ /dev/null
@@ -1,3 +0,0 @@
-ifeq ($(subdir),wcsmbs)
-sysdep_routines += wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c
-endif
diff --git a/sysdeps/i386/i686/multiarch/wmemcmp-c.c b/sysdeps/i386/i686/multiarch/wmemcmp-c.c
deleted file mode 100644
index 75ab4b9..0000000
--- a/sysdeps/i386/i686/multiarch/wmemcmp-c.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#include <wchar.h>
-
-#if IS_IN (libc)
-# define WMEMCMP  __wmemcmp_ia32
-#endif
-
-extern __typeof (wmemcmp) __wmemcmp_ia32;
-
-#include "wcsmbs/wmemcmp.c"
diff --git a/sysdeps/i386/i686/multiarch/wmemcmp.S b/sysdeps/i386/i686/multiarch/wmemcmp.S
deleted file mode 100644
index 6025942..0000000
--- a/sysdeps/i386/i686/multiarch/wmemcmp.S
+++ /dev/null
@@ -1,40 +0,0 @@
-/* Multiple versions of wmemcmp
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in libc. */
-
-#if IS_IN (libc)
-	.text
-ENTRY(wmemcmp)
-	.type	wmemcmp, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wmemcmp_ia32)
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wmemcmp_ssse3)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wmemcmp_sse4_2)
-2:	ret
-END(wmemcmp)
-#endif
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 6d594f8..b638fa5 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -52,7 +52,8 @@ endif
 ifeq ($(subdir),wcsmbs)
 sysdep_routines += wcschr-i386 wcschr-sse2 wcsrchr-i386 wcsrchr-sse2 \
 		   wcscmp-i386 wcscmp-sse2 wcscpy-i386 wcscpy-ssse3 \
-		   wcslen-i386 wcslen-sse2
+		   wcslen-i386 wcslen-sse2 \
+		   wmemcmp-i386 wmemcmp-sse4 wmemcmp-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 a10e700..df63c2c 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -346,15 +346,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __wcsrchr_sse2)
 	      IFUNC_IMPL_ADD (array, i, wcsrchr, 1, __wcsrchr_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/wmemcmp.S.  */
   IFUNC_IMPL (i, name, wmemcmp,
 	      IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSE4_2),
 			      __wmemcmp_sse4_2)
 	      IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSSE3),
 			      __wmemcmp_ssse3)
-	      IFUNC_IMPL_ADD (array, i, wmemcmp, 1, __wmemcmp_ia32))
-#endif
+	      IFUNC_IMPL_ADD (array, i, wmemcmp, 1, __wmemcmp_i386))
 
 #ifdef SHARED
   /* Support sysdeps/i386/i686/multiarch/memcpy_chk.S.  */
diff --git a/sysdeps/i386/multiarch/wmemcmp-i386.c b/sysdeps/i386/multiarch/wmemcmp-i386.c
new file mode 100644
index 0000000..cb34db2
--- /dev/null
+++ b/sysdeps/i386/multiarch/wmemcmp-i386.c
@@ -0,0 +1,9 @@
+#include <wchar.h>
+
+#if IS_IN (libc)
+# define WMEMCMP  __wmemcmp_i386
+#endif
+
+extern __typeof (wmemcmp) __wmemcmp_i386;
+
+#include "wcsmbs/wmemcmp.c"
diff --git a/sysdeps/i386/i686/multiarch/wmemcmp-sse4.S b/sysdeps/i386/multiarch/wmemcmp-sse4.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/wmemcmp-sse4.S
rename to sysdeps/i386/multiarch/wmemcmp-sse4.S
diff --git a/sysdeps/i386/i686/multiarch/wmemcmp-ssse3.S b/sysdeps/i386/multiarch/wmemcmp-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/wmemcmp-ssse3.S
rename to sysdeps/i386/multiarch/wmemcmp-ssse3.S
diff --git a/sysdeps/i386/multiarch/wmemcmp.c b/sysdeps/i386/multiarch/wmemcmp.c
new file mode 100644
index 0000000..94b1644
--- /dev/null
+++ b/sysdeps/i386/multiarch/wmemcmp.c
@@ -0,0 +1,54 @@
+/* Multiple versions of wmemcmp.
+   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 wmemcmp so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef wmemcmp
+# define wmemcmp __redirect_wmemcmp
+# include <wchar.h>
+# undef wmemcmp
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_wmemcmp) __wmemcmp_i386 attribute_hidden;
+extern __typeof (__redirect_wmemcmp) __wmemcmp_ssse3 attribute_hidden;
+extern __typeof (__redirect_wmemcmp) __wmemcmp_sse4_2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_wmemcmp) wmemcmp;
+extern void *wmemcmp_ifunc (void) __asm__ ("wmemcmp");
+
+void *
+wmemcmp_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    {
+      if (HAS_CPU_FEATURE (SSE4_2))
+	return __wmemcmp_sse4_2;
+      else
+	return __wmemcmp_ssse3;
+    }
+
+  return __wmemcmp_i386;
+}
+__asm__ (".type wmemcmp, %gnu_indirect_function");
+#endif

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

commit 39ecf822e2a5be93b2132d21aacfb7466073879e
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Aug 25 06:51:45 2015 -0700

    Add i386 wcslen multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 57cd608..3e078b7 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,4 +1,3 @@
 ifeq ($(subdir),wcsmbs)
-sysdep_routines += wcslen-sse2 wcslen-c \
-		   wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c
+sysdep_routines += wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c
 endif
diff --git a/sysdeps/i386/i686/multiarch/wcslen.S b/sysdeps/i386/i686/multiarch/wcslen.S
deleted file mode 100644
index 7740404..0000000
--- a/sysdeps/i386/i686/multiarch/wcslen.S
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Multiple versions of wcslen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(__wcslen)
-	.type	__wcslen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcslen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcslen_sse2)
-2:	ret
-END(__wcslen)
-
-weak_alias(__wcslen, wcslen)
-#endif
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index d06b2ad..6d594f8 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -51,7 +51,8 @@ endif
 
 ifeq ($(subdir),wcsmbs)
 sysdep_routines += wcschr-i386 wcschr-sse2 wcsrchr-i386 wcsrchr-sse2 \
-		   wcscmp-i386 wcscmp-sse2 wcscpy-i386 wcscpy-ssse3
+		   wcscmp-i386 wcscmp-sse2 wcscpy-i386 wcscpy-ssse3 \
+		   wcslen-i386 wcslen-sse2
 endif
 
 ifeq (mathyes,$(subdir)$(config-cflags-avx))
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index c5cc501..a10e700 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -334,13 +334,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __wcscpy_ssse3)
 	      IFUNC_IMPL_ADD (array, i, wcscpy, 1, __wcscpy_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/wcslen.S.  */
   IFUNC_IMPL (i, name, wcslen,
 	      IFUNC_IMPL_ADD (array, i, wcslen, HAS_CPU_FEATURE (SSE2),
 			      __wcslen_sse2)
-	      IFUNC_IMPL_ADD (array, i, wcslen, 1, __wcslen_ia32))
-#endif
+	      IFUNC_IMPL_ADD (array, i, wcslen, 1, __wcslen_i386))
 
   /* Support sysdeps/i386/i686/multiarch/wcsrchr.S.  */
   IFUNC_IMPL (i, name, wcsrchr,
diff --git a/sysdeps/i386/i686/multiarch/wcslen-c.c b/sysdeps/i386/multiarch/wcslen-i386.c
similarity index 50%
rename from sysdeps/i386/i686/multiarch/wcslen-c.c
rename to sysdeps/i386/multiarch/wcslen-i386.c
index a335dc0..9c7b94e 100644
--- a/sysdeps/i386/i686/multiarch/wcslen-c.c
+++ b/sysdeps/i386/multiarch/wcslen-i386.c
@@ -1,9 +1,9 @@
 #include <wchar.h>
 
 #if IS_IN (libc)
-# define WCSLEN  __wcslen_ia32
+# define WCSLEN  __wcslen_i386
 #endif
 
-extern __typeof (wcslen) __wcslen_ia32;
+extern __typeof (wcslen) __wcslen_i386;
 
 #include "wcsmbs/wcslen.c"
diff --git a/sysdeps/i386/i686/multiarch/wcslen-sse2.S b/sysdeps/i386/multiarch/wcslen-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/wcslen-sse2.S
rename to sysdeps/i386/multiarch/wcslen-sse2.S
diff --git a/sysdeps/i386/multiarch/wcslen.c b/sysdeps/i386/multiarch/wcslen.c
new file mode 100644
index 0000000..4a7970e
--- /dev/null
+++ b/sysdeps/i386/multiarch/wcslen.c
@@ -0,0 +1,50 @@
+/* Multiple versions of wcslen.
+   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 wcslen so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef wcslen
+# define wcslen __redirect_wcslen
+# include <wchar.h>
+# undef wcslen
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_wcslen) __wcslen_i386 attribute_hidden;
+extern __typeof (__redirect_wcslen) __wcslen_sse2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_wcslen) __wcslen;
+extern void *wcslen_ifunc (void) __asm__ ("__wcslen");
+
+void *
+wcslen_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    return __wcslen_sse2;
+
+  return __wcslen_i386;
+}
+__asm__ (".type __wcslen, %gnu_indirect_function");
+
+weak_alias (__wcslen, wcslen)
+#endif

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

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

    Add i386 wcscpy multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index a9d032f..57cd608 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,5 +1,4 @@
 ifeq ($(subdir),wcsmbs)
 sysdep_routines += wcslen-sse2 wcslen-c \
-		   wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c \
-		   wcscpy-ssse3 wcscpy-c
+		   wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c
 endif
diff --git a/sysdeps/i386/i686/multiarch/wcscpy.S b/sysdeps/i386/i686/multiarch/wcscpy.S
deleted file mode 100644
index 5f14970..0000000
--- a/sysdeps/i386/i686/multiarch/wcscpy.S
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Multiple versions of wcscpy
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in libc. */
-#if IS_IN (libc)
-	.text
-ENTRY(wcscpy)
-	.type	wcscpy, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcscpy_ia32)
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcscpy_ssse3)
-2:	ret
-END(wcscpy)
-#endif
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 084307b..d06b2ad 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -51,7 +51,7 @@ endif
 
 ifeq ($(subdir),wcsmbs)
 sysdep_routines += wcschr-i386 wcschr-sse2 wcsrchr-i386 wcsrchr-sse2 \
-		   wcscmp-i386 wcscmp-sse2
+		   wcscmp-i386 wcscmp-sse2 wcscpy-i386 wcscpy-ssse3
 endif
 
 ifeq (mathyes,$(subdir)$(config-cflags-avx))
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 63d7ecf..c5cc501 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -328,13 +328,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __wcscmp_sse2)
 	      IFUNC_IMPL_ADD (array, i, wcscmp, 1, __wcscmp_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/wcscpy.S.  */
   IFUNC_IMPL (i, name, wcscpy,
 	      IFUNC_IMPL_ADD (array, i, wcscpy, HAS_CPU_FEATURE (SSSE3),
 			      __wcscpy_ssse3)
-	      IFUNC_IMPL_ADD (array, i, wcscpy, 1, __wcscpy_ia32))
+	      IFUNC_IMPL_ADD (array, i, wcscpy, 1, __wcscpy_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/wcslen.S.  */
   IFUNC_IMPL (i, name, wcslen,
 	      IFUNC_IMPL_ADD (array, i, wcslen, HAS_CPU_FEATURE (SSE2),
diff --git a/sysdeps/i386/i686/multiarch/wcscpy-c.c b/sysdeps/i386/multiarch/wcscpy-i386.c
similarity index 62%
rename from sysdeps/i386/i686/multiarch/wcscpy-c.c
rename to sysdeps/i386/multiarch/wcscpy-i386.c
index fb30003..3207110 100644
--- a/sysdeps/i386/i686/multiarch/wcscpy-c.c
+++ b/sysdeps/i386/multiarch/wcscpy-i386.c
@@ -1,5 +1,5 @@
 #if IS_IN (libc)
-# define wcscpy  __wcscpy_ia32
+# define wcscpy  __wcscpy_i386
 #endif
 
 #include "wcsmbs/wcscpy.c"
diff --git a/sysdeps/i386/i686/multiarch/wcscpy-ssse3.S b/sysdeps/i386/multiarch/wcscpy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/wcscpy-ssse3.S
rename to sysdeps/i386/multiarch/wcscpy-ssse3.S
diff --git a/sysdeps/i386/multiarch/wcscpy.c b/sysdeps/i386/multiarch/wcscpy.c
new file mode 100644
index 0000000..ac5f3e5
--- /dev/null
+++ b/sysdeps/i386/multiarch/wcscpy.c
@@ -0,0 +1,48 @@
+/* Multiple versions of wcscpy.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+/* Redefine wcscpy so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef wcscpy
+# define wcscpy __redirect_wcscpy
+# include <wchar.h>
+# undef wcscpy
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_wcscpy) __wcscpy_i386 attribute_hidden;
+extern __typeof (__redirect_wcscpy) __wcscpy_ssse3 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_wcscpy) wcscpy;
+extern void *wcscpy_ifunc (void) __asm__ ("wcscpy");
+
+void *
+wcscpy_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    return __wcscpy_ssse3;
+
+  return __wcscpy_i386;
+}
+__asm__ (".type wcscpy, %gnu_indirect_function");
+#endif

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

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

    Add i386 wcscmp multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 289f0f9..a9d032f 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,5 +1,5 @@
 ifeq ($(subdir),wcsmbs)
-sysdep_routines += wcscmp-sse2 wcscmp-c wcslen-sse2 wcslen-c \
+sysdep_routines += wcslen-sse2 wcslen-c \
 		   wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c \
 		   wcscpy-ssse3 wcscpy-c
 endif
diff --git a/sysdeps/i386/i686/multiarch/wcscmp.S b/sysdeps/i386/i686/multiarch/wcscmp.S
deleted file mode 100644
index db9c05a..0000000
--- a/sysdeps/i386/i686/multiarch/wcscmp.S
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Multiple versions of wcscmp
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in libc and for the
-   DSO.  In static binaries, we need wcscmp before the initialization
-   happened.  */
-#if IS_IN (libc)
-	.text
-ENTRY(__wcscmp)
-	.type	__wcscmp, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcscmp_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcscmp_sse2)
-2:	ret
-END(__wcscmp)
-weak_alias (__wcscmp, wcscmp)
-#endif
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 3515759..084307b 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -50,7 +50,8 @@ endif
 endif
 
 ifeq ($(subdir),wcsmbs)
-sysdep_routines += wcschr-i386 wcschr-sse2 wcsrchr-i386 wcsrchr-sse2
+sysdep_routines += wcschr-i386 wcschr-sse2 wcsrchr-i386 wcsrchr-sse2 \
+		   wcscmp-i386 wcscmp-sse2
 endif
 
 ifeq (mathyes,$(subdir)$(config-cflags-avx))
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 851d231..63d7ecf 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -322,13 +322,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __wcschr_sse2)
 	      IFUNC_IMPL_ADD (array, i, wcschr, 1, __wcschr_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/wcscmp.S.  */
   IFUNC_IMPL (i, name, wcscmp,
 	      IFUNC_IMPL_ADD (array, i, wcscmp, HAS_CPU_FEATURE (SSE2),
 			      __wcscmp_sse2)
-	      IFUNC_IMPL_ADD (array, i, wcscmp, 1, __wcscmp_ia32))
+	      IFUNC_IMPL_ADD (array, i, wcscmp, 1, __wcscmp_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/wcscpy.S.  */
   IFUNC_IMPL (i, name, wcscpy,
 	      IFUNC_IMPL_ADD (array, i, wcscpy, HAS_CPU_FEATURE (SSSE3),
diff --git a/sysdeps/i386/i686/multiarch/wcscmp-c.c b/sysdeps/i386/multiarch/wcscmp-i386.c
similarity index 57%
rename from sysdeps/i386/i686/multiarch/wcscmp-c.c
rename to sysdeps/i386/multiarch/wcscmp-i386.c
index e3337d7..538a823 100644
--- a/sysdeps/i386/i686/multiarch/wcscmp-c.c
+++ b/sysdeps/i386/multiarch/wcscmp-i386.c
@@ -1,14 +1,14 @@
 #include <wchar.h>
 
-#define WCSCMP __wcscmp_ia32
+#define WCSCMP __wcscmp_i386
 #ifdef SHARED
 # undef libc_hidden_def
 # define libc_hidden_def(name) \
-  __hidden_ver1 (__wcscmp_ia32, __GI___wcscmp, __wcscmp_ia32);
+  __hidden_ver1 (__wcscmp_i386, __GI___wcscmp, __wcscmp_i386);
 #endif
 #undef weak_alias
 #define weak_alias(name, alias)
 
-extern __typeof (wcscmp) __wcscmp_ia32;
+extern __typeof (wcscmp) __wcscmp_i386;
 
 #include "wcsmbs/wcscmp.c"
diff --git a/sysdeps/i386/i686/multiarch/wcscmp-sse2.S b/sysdeps/i386/multiarch/wcscmp-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/wcscmp-sse2.S
rename to sysdeps/i386/multiarch/wcscmp-sse2.S
diff --git a/sysdeps/i386/multiarch/wcscmp.c b/sysdeps/i386/multiarch/wcscmp.c
new file mode 100644
index 0000000..48b56f8
--- /dev/null
+++ b/sysdeps/i386/multiarch/wcscmp.c
@@ -0,0 +1,50 @@
+/* Multiple versions of wcscmp.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+/* Redefine wcscmp so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef wcscmp
+# define wcscmp __redirect_wcscmp
+# include <wchar.h>
+# undef wcscmp
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_wcscmp) __wcscmp_i386 attribute_hidden;
+extern __typeof (__redirect_wcscmp) __wcscmp_sse2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_wcscmp) __wcscmp;
+extern void *wcscmp_ifunc (void) __asm__ ("__wcscmp");
+
+void *
+wcscmp_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    return __wcscmp_sse2;
+
+  return __wcscmp_i386;
+}
+__asm__ (".type __wcscmp, %gnu_indirect_function");
+
+weak_alias (__wcscmp, wcscmp)
+#endif

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

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

    Add i386 wcschr/wcsrchr multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index ff54ee9..289f0f9 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,5 +1,5 @@
 ifeq ($(subdir),wcsmbs)
 sysdep_routines += wcscmp-sse2 wcscmp-c wcslen-sse2 wcslen-c \
-		   wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c wcschr-sse2 \
-		   wcschr-c wcsrchr-sse2 wcsrchr-c wcscpy-ssse3 wcscpy-c
+		   wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c \
+		   wcscpy-ssse3 wcscpy-c
 endif
diff --git a/sysdeps/i386/i686/multiarch/wcschr.S b/sysdeps/i386/i686/multiarch/wcschr.S
deleted file mode 100644
index 5918b12..0000000
--- a/sysdeps/i386/i686/multiarch/wcschr.S
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Multiple versions of wcschr
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(__wcschr)
-	.type	wcschr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcschr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcschr_sse2)
-2:	ret
-END(__wcschr)
-weak_alias (__wcschr, wcschr)
-#endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr.S b/sysdeps/i386/i686/multiarch/wcsrchr.S
deleted file mode 100644
index 9ed6810..0000000
--- a/sysdeps/i386/i686/multiarch/wcsrchr.S
+++ /dev/null
@@ -1,35 +0,0 @@
-/* Multiple versions of wcsrchr
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(wcsrchr)
-	.type	wcsrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__wcsrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__wcsrchr_sse2)
-2:	ret
-END(wcsrchr)
-#endif
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 89c86b4..3515759 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -49,6 +49,10 @@ CFLAGS-strspn-sse4.c += -msse4
 endif
 endif
 
+ifeq ($(subdir),wcsmbs)
+sysdep_routines += wcschr-i386 wcschr-sse2 wcsrchr-i386 wcsrchr-sse2
+endif
+
 ifeq (mathyes,$(subdir)$(config-cflags-avx))
 libm-sysdep_routines += s_fma-fma s_fmaf-fma
 CFLAGS-s_fma-fma.c += -mavx -mfpmath=sse
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 94a376d..851d231 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -316,13 +316,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strspn_sse42)
 	      IFUNC_IMPL_ADD (array, i, strspn, 1, __strspn_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/wcschr.S.  */
   IFUNC_IMPL (i, name, wcschr,
 	      IFUNC_IMPL_ADD (array, i, wcschr, HAS_CPU_FEATURE (SSE2),
 			      __wcschr_sse2)
-	      IFUNC_IMPL_ADD (array, i, wcschr, 1, __wcschr_ia32))
+	      IFUNC_IMPL_ADD (array, i, wcschr, 1, __wcschr_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/wcscmp.S.  */
   IFUNC_IMPL (i, name, wcscmp,
 	      IFUNC_IMPL_ADD (array, i, wcscmp, HAS_CPU_FEATURE (SSE2),
@@ -340,13 +340,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, wcslen, HAS_CPU_FEATURE (SSE2),
 			      __wcslen_sse2)
 	      IFUNC_IMPL_ADD (array, i, wcslen, 1, __wcslen_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/wcsrchr.S.  */
   IFUNC_IMPL (i, name, wcsrchr,
 	      IFUNC_IMPL_ADD (array, i, wcsrchr, HAS_CPU_FEATURE (SSE2),
 			      __wcsrchr_sse2)
-	      IFUNC_IMPL_ADD (array, i, wcsrchr, 1, __wcsrchr_ia32))
+	      IFUNC_IMPL_ADD (array, i, wcsrchr, 1, __wcsrchr_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/wmemcmp.S.  */
   IFUNC_IMPL (i, name, wmemcmp,
 	      IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSE4_2),
diff --git a/sysdeps/i386/i686/multiarch/wcschr-c.c b/sysdeps/i386/multiarch/wcschr-i386.c
similarity index 51%
rename from sysdeps/i386/i686/multiarch/wcschr-c.c
rename to sysdeps/i386/multiarch/wcschr-i386.c
index 38d41d0..de06c24 100644
--- a/sysdeps/i386/i686/multiarch/wcschr-c.c
+++ b/sysdeps/i386/multiarch/wcschr-i386.c
@@ -10,13 +10,13 @@
 # ifdef SHARED
 #  undef libc_hidden_def
 #  define libc_hidden_def(name) \
-   __hidden_ver1 (__wcschr_ia32, __GI_wcschr, __wcschr_ia32); \
-   strong_alias (__wcschr_ia32, __wcschr_ia32_1); \
-   __hidden_ver1 (__wcschr_ia32_1, __GI___wcschr, __wcschr_ia32_1);
+   __hidden_ver1 (__wcschr_i386, __GI_wcschr, __wcschr_i386); \
+   strong_alias (__wcschr_i386, __wcschr_i386_1); \
+   __hidden_ver1 (__wcschr_i386_1, __GI___wcschr, __wcschr_i386_1);
 # endif
 #endif
 
-extern __typeof (wcschr) __wcschr_ia32;
+extern __typeof (wcschr) __wcschr_i386;
 
-#define WCSCHR  __wcschr_ia32
+#define WCSCHR  __wcschr_i386
 #include <wcsmbs/wcschr.c>
diff --git a/sysdeps/i386/i686/multiarch/wcschr-sse2.S b/sysdeps/i386/multiarch/wcschr-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/wcschr-sse2.S
rename to sysdeps/i386/multiarch/wcschr-sse2.S
diff --git a/sysdeps/i386/multiarch/wcschr.c b/sysdeps/i386/multiarch/wcschr.c
new file mode 100644
index 0000000..25cc0db
--- /dev/null
+++ b/sysdeps/i386/multiarch/wcschr.c
@@ -0,0 +1,50 @@
+/* Multiple versions of wcschr.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+/* Redefine wcschr so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef wcschr
+# define wcschr __redirect_wcschr
+# include <wchar.h>
+# undef wcschr
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_wcschr) __wcschr_i386 attribute_hidden;
+extern __typeof (__redirect_wcschr) __wcschr_sse2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_wcschr) __wcschr;
+extern void *wcschr_ifunc (void) __asm__ ("__wcschr");
+
+void *
+wcschr_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    return __wcschr_sse2;
+
+  return __wcschr_i386;
+}
+__asm__ (".type __wcschr, %gnu_indirect_function");
+
+weak_alias (__wcschr, wcschr)
+#endif
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr-c.c b/sysdeps/i386/multiarch/wcsrchr-i386.c
similarity index 61%
rename from sysdeps/i386/i686/multiarch/wcsrchr-c.c
rename to sysdeps/i386/multiarch/wcsrchr-i386.c
index 8d8a335..1f7583a 100644
--- a/sysdeps/i386/i686/multiarch/wcsrchr-c.c
+++ b/sysdeps/i386/multiarch/wcsrchr-i386.c
@@ -1,5 +1,5 @@
 #if IS_IN (libc)
-# define wcsrchr  __wcsrchr_ia32
+# define wcsrchr  __wcsrchr_i386
 #endif
 
 #include "wcsmbs/wcsrchr.c"
diff --git a/sysdeps/i386/i686/multiarch/wcsrchr-sse2.S b/sysdeps/i386/multiarch/wcsrchr-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/wcsrchr-sse2.S
rename to sysdeps/i386/multiarch/wcsrchr-sse2.S
diff --git a/sysdeps/i386/multiarch/wcsrchr.c b/sysdeps/i386/multiarch/wcsrchr.c
new file mode 100644
index 0000000..1420690
--- /dev/null
+++ b/sysdeps/i386/multiarch/wcsrchr.c
@@ -0,0 +1,48 @@
+/* Multiple versions of wcsrchr.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+/* Redefine wcsrchr so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef wcsrchr
+# define wcsrchr __redirect_wcsrchr
+# include <wchar.h>
+# undef wcsrchr
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_wcsrchr) __wcsrchr_i386 attribute_hidden;
+extern __typeof (__redirect_wcsrchr) __wcsrchr_sse2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_wcsrchr) wcsrchr;
+extern void *wcsrchr_ifunc (void) __asm__ ("wcsrchr");
+
+void *
+wcsrchr_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    return __wcsrchr_sse2;
+
+  return __wcsrchr_i386;
+}
+__asm__ (".type wcsrchr, %gnu_indirect_function");
+#endif

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

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

    Add i386 strspn multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 77f01df..ff54ee9 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,10 +1,3 @@
-ifeq ($(subdir),string)
-ifeq (yes,$(config-cflags-sse4))
-sysdep_routines += strspn-c
-CFLAGS-strspn-c.c += -msse4
-endif
-endif
-
 ifeq ($(subdir),wcsmbs)
 sysdep_routines += wcscmp-sse2 wcscmp-c wcslen-sse2 wcslen-c \
 		   wmemcmp-sse4 wmemcmp-ssse3 wmemcmp-c wcschr-sse2 \
diff --git a/sysdeps/i386/i686/multiarch/strspn.S b/sysdeps/i386/i686/multiarch/strspn.S
deleted file mode 100644
index 4ba87be..0000000
--- a/sysdeps/i386/i686/multiarch/strspn.S
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Multiple versions of strspn
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2009-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <config.h>
-
-#ifdef HAVE_SSE4_SUPPORT
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in libc.  */
-#if IS_IN (libc)
-	.text
-ENTRY(strspn)
-	.type	strspn, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strspn_ia32)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strspn_sse42)
-2:	ret
-END(strspn)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __strspn_ia32, @function; \
-	.globl __strspn_ia32; \
-	.p2align 4; \
-__strspn_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __strspn_ia32, .-__strspn_ia32
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_strspn; __GI_strspn = __strspn_ia32
-#endif
-
-#endif /* HAVE_SSE4_SUPPORT */
-
-#include "../../strspn.S"
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 5e636ed..89c86b4 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -38,12 +38,14 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   strcspn-i386 strpbrk-i386 \
 		   strlen-i386 strlen-i586 strlen-sse2 strlen-sse2-bsf \
 		   strnlen-sse2 strnlen-i386 static-strlen \
-		   strrchr-i386 strrchr-sse2-bsf strrchr-sse2
+		   strrchr-i386 strrchr-sse2-bsf strrchr-sse2 \
+		   strspn-i386 strspn-sse4
 ifeq (yes,$(config-cflags-sse4))
-sysdep_routines += varshift strcspn-sse4 strpbrk-sse4
+sysdep_routines += varshift strcspn-sse4 strpbrk-sse4 strspn-sse4
 CFLAGS-varshift.c += -msse4
 CFLAGS-strcspn-sse4.c += -msse4
 CFLAGS-strpbrk-sse4.c += -msse4
+CFLAGS-strspn-sse4.c += -msse4
 endif
 endif
 
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index a53c49f..94a376d 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -310,13 +310,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strrchr_sse2)
 	      IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/strspn.S.  */
   IFUNC_IMPL (i, name, strspn,
 	      IFUNC_IMPL_ADD (array, i, strspn, HAS_CPU_FEATURE (SSE4_2),
 			      __strspn_sse42)
-	      IFUNC_IMPL_ADD (array, i, strspn, 1, __strspn_ia32))
+	      IFUNC_IMPL_ADD (array, i, strspn, 1, __strspn_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/wcschr.S.  */
   IFUNC_IMPL (i, name, wcschr,
 	      IFUNC_IMPL_ADD (array, i, wcschr, HAS_CPU_FEATURE (SSE2),
diff --git a/sysdeps/i386/multiarch/strspn-i386.S b/sysdeps/i386/multiarch/strspn-i386.S
new file mode 100644
index 0000000..c6d4d67
--- /dev/null
+++ b/sysdeps/i386/multiarch/strspn-i386.S
@@ -0,0 +1,8 @@
+#define strspn __strspn_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/strspn.S>
+
+	.globl __GI_strspn
+	.hidden __GI_strspn
+	__GI_strspn = __strspn_i386
diff --git a/sysdeps/i386/i686/multiarch/strspn-c.c b/sysdeps/i386/multiarch/strspn-sse4.c
similarity index 56%
rename from sysdeps/i386/i686/multiarch/strspn-c.c
rename to sysdeps/i386/multiarch/strspn-sse4.c
index bea09de..fc84a3d 100644
--- a/sysdeps/i386/i686/multiarch/strspn-c.c
+++ b/sysdeps/i386/multiarch/strspn-sse4.c
@@ -1,2 +1,2 @@
-#define __strspn_sse2 __strspn_ia32
+#define __strspn_sse2 __strspn_i386
 #include <sysdeps/x86_64/multiarch/strspn-c.c>
diff --git a/sysdeps/i386/multiarch/strspn.c b/sysdeps/i386/multiarch/strspn.c
new file mode 100644
index 0000000..91d5a5f
--- /dev/null
+++ b/sysdeps/i386/multiarch/strspn.c
@@ -0,0 +1,49 @@
+/* Multiple versions of strspn.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define _HAVE_STRING_ARCH_strspn
+/* Redefine strspn so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strspn
+# define strspn __redirect_strspn
+# include <string.h>
+# undef strspn
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strspn) __strspn_i386 attribute_hidden;
+extern __typeof (__redirect_strspn) __strspn_sse42 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strspn) strspn;
+extern void *strspn_ifunc (void) __asm__ ("strspn");
+
+void *
+strspn_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE4_2))
+    return __strspn_sse42;
+
+  return __strspn_i386;
+}
+__asm__ (".type strspn, %gnu_indirect_function");
+#endif

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

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

    Add i386 strlen family multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i586/multiarch/rtld-strlen.S
similarity index 59%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i586/multiarch/rtld-strlen.S
index baf21fc..70fc5f3 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i586/multiarch/rtld-strlen.S
@@ -1,7 +1,5 @@
-/* Multiple versions of strnlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* strlen for ld.so
+   Copyright (C) 2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -18,20 +16,4 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
-
-weak_alias(__strnlen, strnlen)
-#endif
+#include <sysdeps/i386/i586/strlen.S>
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/i586/multiarch/static-strlen.S
similarity index 60%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/i586/multiarch/static-strlen.S
index baf21fc..96befd4 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/i586/multiarch/static-strlen.S
@@ -1,7 +1,5 @@
-/* Multiple versions of strnlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* strlen for libc.a
+   Copyright (C) 2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -18,20 +16,6 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
-
-weak_alias(__strnlen, strnlen)
+#if !defined SHARED && IS_IN (libc)
+# include <sysdeps/i386/i586/strlen.S>
 #endif
diff --git a/sysdeps/i386/i586/multiarch/strlen-i386.S b/sysdeps/i386/i586/multiarch/strlen-i386.S
new file mode 100644
index 0000000..216bbf5
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strlen-i386.S
@@ -0,0 +1,4 @@
+#define strlen __strlen_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/strlen.S>
diff --git a/sysdeps/i386/i586/multiarch/strlen-i586.S b/sysdeps/i386/i586/multiarch/strlen-i586.S
new file mode 100644
index 0000000..69c3170
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strlen-i586.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/strlen-i586.S>
+
+#ifdef SHARED
+	.globl __GI_strlen
+	.hidden __GI_strlen
+	__GI_strlen = __strlen_i586
+#endif
diff --git a/sysdeps/i386/i586/multiarch/strlen.c b/sysdeps/i386/i586/multiarch/strlen.c
new file mode 100644
index 0000000..fb40868
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strlen.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/strlen.c>
diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 2733c2a..77f01df 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,6 +1,4 @@
 ifeq ($(subdir),string)
-sysdep_routines += strlen-sse2 strlen-sse2-bsf \
-		   strnlen-sse2 strnlen-c
 ifeq (yes,$(config-cflags-sse4))
 sysdep_routines += strspn-c
 CFLAGS-strspn-c.c += -msse4
diff --git a/sysdeps/i386/i686/multiarch/strlen.S b/sysdeps/i386/i686/multiarch/strlen.S
deleted file mode 100644
index 613559c..0000000
--- a/sysdeps/i386/i686/multiarch/strlen.S
+++ /dev/null
@@ -1,60 +0,0 @@
-/* Multiple versions of strlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2009-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in libc and for the
-   DSO.  In static binaries, we need strlen before the initialization
-   happened.  */
-#if defined SHARED && IS_IN (libc)
-	.text
-ENTRY(strlen)
-	.type	strlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strlen_sse2_bsf)
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strlen_sse2)
-2:	ret
-END(strlen)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __strlen_ia32, @function; \
-	.globl __strlen_ia32; \
-	.p2align 4; \
-	__strlen_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __strlen_ia32, .-__strlen_ia32
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_strlen; __GI_strlen = __strlen_ia32
-#endif
-
-#include "../../i586/strlen.S"
diff --git a/sysdeps/i386/i686/multiarch/strnlen-c.c b/sysdeps/i386/i686/multiarch/strnlen-c.c
deleted file mode 100644
index 351e939..0000000
--- a/sysdeps/i386/i686/multiarch/strnlen-c.c
+++ /dev/null
@@ -1,10 +0,0 @@
-#define STRNLEN  __strnlen_ia32
-#ifdef SHARED
-# undef libc_hidden_def
-# define libc_hidden_def(name)  \
-    __hidden_ver1 (__strnlen_ia32, __GI_strnlen, __strnlen_ia32); \
-    strong_alias (__strnlen_ia32, __strnlen_ia32_1); \
-    __hidden_ver1 (__strnlen_ia32_1, __GI___strnlen, __strnlen_ia32_1);
-#endif
-
-#include "string/strnlen.c"
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index a4161b0..5e636ed 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -36,6 +36,8 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   strncat-i386 strncat-sse2 strncat-ssse3 \
 		   strchr-i386 strchr-i586 strchr-sse2-bsf strchr-sse2 \
 		   strcspn-i386 strpbrk-i386 \
+		   strlen-i386 strlen-i586 strlen-sse2 strlen-sse2-bsf \
+		   strnlen-sse2 strnlen-i386 static-strlen \
 		   strrchr-i386 strrchr-sse2-bsf strrchr-sse2
 ifeq (yes,$(config-cflags-sse4))
 sysdep_routines += varshift strcspn-sse4 strpbrk-sse4
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index f3bea9c..a53c49f 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -290,13 +290,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strncpy_sse2)
 	      IFUNC_IMPL_ADD (array, i, strncpy, 1, __strncpy_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/strnlen.S.  */
   IFUNC_IMPL (i, name, strnlen,
 	      IFUNC_IMPL_ADD (array, i, strnlen, HAS_CPU_FEATURE (SSE2),
 			      __strnlen_sse2)
-	      IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_ia32))
-#endif
+	      IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_i386))
 
   /* Support sysdeps/i386/i686/multiarch/strpbrk.S.  */
   IFUNC_IMPL (i, name, strpbrk,
@@ -431,15 +429,14 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 # endif
 	      )
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/strlen.S.  */
   IFUNC_IMPL (i, name, strlen,
 	      IFUNC_IMPL_ADD (array, i, strlen, HAS_CPU_FEATURE (SSE2),
 			      __strlen_sse2_bsf)
 	      IFUNC_IMPL_ADD (array, i, strlen, HAS_CPU_FEATURE (SSE2),
 			      __strlen_sse2)
-	      IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_ia32))
-#endif
+	      IFUNC_IMPL_ADD (array, i, strlen, HAS_I586, __strlen_i586)
+	      IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_i386))
 
   /* Support sysdeps/i386/i686/multiarch/strncmp.S.  */
   IFUNC_IMPL (i, name, strncmp,
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/multiarch/rtld-strlen.S
similarity index 59%
copy from sysdeps/i386/i686/multiarch/strnlen.S
copy to sysdeps/i386/multiarch/rtld-strlen.S
index baf21fc..9ee1dbc 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/multiarch/rtld-strlen.S
@@ -1,7 +1,5 @@
-/* Multiple versions of strnlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* strlen for ld.so
+   Copyright (C) 2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -18,20 +16,4 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
-
-weak_alias(__strnlen, strnlen)
-#endif
+#include <sysdeps/i386/strlen.S>
diff --git a/sysdeps/i386/i686/multiarch/rtld-strnlen.c b/sysdeps/i386/multiarch/rtld-strnlen.c
similarity index 100%
rename from sysdeps/i386/i686/multiarch/rtld-strnlen.c
rename to sysdeps/i386/multiarch/rtld-strnlen.c
diff --git a/sysdeps/i386/i686/multiarch/strnlen.S b/sysdeps/i386/multiarch/static-strlen.S
similarity index 60%
rename from sysdeps/i386/i686/multiarch/strnlen.S
rename to sysdeps/i386/multiarch/static-strlen.S
index baf21fc..f4318e1 100644
--- a/sysdeps/i386/i686/multiarch/strnlen.S
+++ b/sysdeps/i386/multiarch/static-strlen.S
@@ -1,7 +1,5 @@
-/* Multiple versions of strnlen
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
+/* strlen for libc.a
+   Copyright (C) 2015 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -18,20 +16,6 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(__strnlen)
-	.type	__strnlen, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strnlen_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strnlen_sse2)
-2:	ret
-END(__strnlen)
-
-weak_alias(__strnlen, strnlen)
+#if !defined SHARED && IS_IN (libc)
+# include <sysdeps/i386/strlen.S>
 #endif
diff --git a/sysdeps/i386/multiarch/strlen-i386.S b/sysdeps/i386/multiarch/strlen-i386.S
new file mode 100644
index 0000000..15dbe7d
--- /dev/null
+++ b/sysdeps/i386/multiarch/strlen-i386.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/i586/multiarch/strlen-i386.S>
+
+#ifdef SHARED
+	.globl __GI_strlen
+	.hidden __GI_strlen
+	__GI_strlen = __strlen_i386
+#endif
diff --git a/sysdeps/i386/multiarch/strlen-i586.S b/sysdeps/i386/multiarch/strlen-i586.S
new file mode 100644
index 0000000..2f53490
--- /dev/null
+++ b/sysdeps/i386/multiarch/strlen-i586.S
@@ -0,0 +1,6 @@
+#define strlen __strlen_i586
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/i586/strlen.S>
diff --git a/sysdeps/i386/i686/multiarch/strlen-sse2-bsf.S b/sysdeps/i386/multiarch/strlen-sse2-bsf.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strlen-sse2-bsf.S
rename to sysdeps/i386/multiarch/strlen-sse2-bsf.S
diff --git a/sysdeps/i386/multiarch/strlen.c b/sysdeps/i386/multiarch/strlen.c
new file mode 100644
index 0000000..9e376a3
--- /dev/null
+++ b/sysdeps/i386/multiarch/strlen.c
@@ -0,0 +1,58 @@
+/* Multiple versions of strlen.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if defined SHARED && IS_IN (libc)
+/* Redefine strlen so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strlen
+# define strlen __redirect_strlen
+# include <string.h>
+# undef strlen
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strlen) __strlen_i386 attribute_hidden;
+extern __typeof (__redirect_strlen) __strlen_i586 attribute_hidden;
+extern __typeof (__redirect_strlen) __strlen_sse2 attribute_hidden;
+extern __typeof (__redirect_strlen) __strlen_sse2_bsf attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strlen) strlen;
+extern void *strlen_ifunc (void) __asm__ ("strlen");
+
+void *
+strlen_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Slow_BSF))
+	return __strlen_sse2;
+      else
+	return __strlen_sse2_bsf;
+    }
+
+  if (USE_I586)
+    return __strlen_i586;
+  else
+    return __strlen_i386;
+}
+__asm__ (".type strlen, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/multiarch/strnlen-i386.c b/sysdeps/i386/multiarch/strnlen-i386.c
new file mode 100644
index 0000000..dd4dbda
--- /dev/null
+++ b/sysdeps/i386/multiarch/strnlen-i386.c
@@ -0,0 +1,10 @@
+#define STRNLEN  __strnlen_i386
+#ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name)  \
+    __hidden_ver1 (__strnlen_i386, __GI_strnlen, __strnlen_i386); \
+    strong_alias (__strnlen_i386, __strnlen_i386_1); \
+    __hidden_ver1 (__strnlen_i386_1, __GI___strnlen, __strnlen_i386_1);
+#endif
+
+#include "string/strnlen.c"
diff --git a/sysdeps/i386/i686/multiarch/strnlen-sse2.S b/sysdeps/i386/multiarch/strnlen-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strnlen-sse2.S
rename to sysdeps/i386/multiarch/strnlen-sse2.S
diff --git a/sysdeps/i386/multiarch/strnlen.c b/sysdeps/i386/multiarch/strnlen.c
new file mode 100644
index 0000000..3e97c9e
--- /dev/null
+++ b/sysdeps/i386/multiarch/strnlen.c
@@ -0,0 +1,50 @@
+/* Multiple versions of strnlen.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+/* Redefine strnlen so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strnlen
+# define strnlen __redirect_strnlen
+# include <string.h>
+# undef strnlen
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strnlen) __strnlen_i386 attribute_hidden;
+extern __typeof (__redirect_strnlen) __strnlen_sse2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strnlen) __strnlen;
+extern void *strnlen_ifunc (void) __asm__ ("__strnlen");
+
+void *
+strnlen_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    return __strnlen_sse2;
+
+  return __strnlen_i386;
+}
+__asm__ (".type __strnlen, %gnu_indirect_function");
+
+weak_alias (__strnlen, strnlen)
+#endif

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

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

    Add i386 strrchr multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 8f8e450..2733c2a 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,6 +1,5 @@
 ifeq ($(subdir),string)
 sysdep_routines += strlen-sse2 strlen-sse2-bsf \
-		   strrchr-sse2 strrchr-sse2-bsf \
 		   strnlen-sse2 strnlen-c
 ifeq (yes,$(config-cflags-sse4))
 sysdep_routines += strspn-c
diff --git a/sysdeps/i386/i686/multiarch/strrchr.S b/sysdeps/i386/i686/multiarch/strrchr.S
deleted file mode 100644
index 6aa3321..0000000
--- a/sysdeps/i386/i686/multiarch/strrchr.S
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Multiple versions of strrchr
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(strrchr)
-	.type	strrchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strrchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strrchr_sse2_bsf)
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strrchr_sse2)
-2:	ret
-END(strrchr)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __strrchr_ia32, @function; \
-	.globl __strrchr_ia32; \
-	.p2align 4; \
-	__strrchr_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __strrchr_ia32, .-__strrchr_ia32
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_strrchr; __GI_strrchr = __strrchr_ia32
-#endif
-
-#include "../../strrchr.S"
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 23c1f8b..a4161b0 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -35,7 +35,8 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   strcat-i386 strcat-sse2 strcat-ssse3 \
 		   strncat-i386 strncat-sse2 strncat-ssse3 \
 		   strchr-i386 strchr-i586 strchr-sse2-bsf strchr-sse2 \
-		   strcspn-i386 strpbrk-i386
+		   strcspn-i386 strpbrk-i386 \
+		   strrchr-i386 strrchr-sse2-bsf strrchr-sse2
 ifeq (yes,$(config-cflags-sse4))
 sysdep_routines += varshift strcspn-sse4 strpbrk-sse4
 CFLAGS-varshift.c += -msse4
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 2fc97a3..f3bea9c 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -304,15 +304,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strpbrk_sse42)
 	      IFUNC_IMPL_ADD (array, i, strpbrk, 1, __strpbrk_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/strrchr.S.  */
   IFUNC_IMPL (i, name, strrchr,
 	      IFUNC_IMPL_ADD (array, i, strrchr, HAS_CPU_FEATURE (SSE2),
 			      __strrchr_sse2_bsf)
 	      IFUNC_IMPL_ADD (array, i, strrchr, HAS_CPU_FEATURE (SSE2),
 			      __strrchr_sse2)
-	      IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_ia32))
+	      IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strspn.S.  */
   IFUNC_IMPL (i, name, strspn,
 	      IFUNC_IMPL_ADD (array, i, strspn, HAS_CPU_FEATURE (SSE4_2),
diff --git a/sysdeps/i386/multiarch/strrchr-i386.S b/sysdeps/i386/multiarch/strrchr-i386.S
new file mode 100644
index 0000000..a7941e6
--- /dev/null
+++ b/sysdeps/i386/multiarch/strrchr-i386.S
@@ -0,0 +1,14 @@
+#define strrchr __strrchr_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef libc_hidden_def
+#define libc_hidden_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/strrchr.S>
+
+#ifdef SHARED
+	.globl __GI_strrchr
+	.hidden __GI_strrchr
+	__GI_strrchr = __strrchr_i386
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strrchr-sse2-bsf.S b/sysdeps/i386/multiarch/strrchr-sse2-bsf.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strrchr-sse2-bsf.S
rename to sysdeps/i386/multiarch/strrchr-sse2-bsf.S
diff --git a/sysdeps/i386/i686/multiarch/strrchr-sse2.S b/sysdeps/i386/multiarch/strrchr-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strrchr-sse2.S
rename to sysdeps/i386/multiarch/strrchr-sse2.S
diff --git a/sysdeps/i386/multiarch/strrchr.c b/sysdeps/i386/multiarch/strrchr.c
new file mode 100644
index 0000000..995e007
--- /dev/null
+++ b/sysdeps/i386/multiarch/strrchr.c
@@ -0,0 +1,55 @@
+/* Multiple versions of strrchr
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+/* Redefine strrchr so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strrchr
+# define strrchr __redirect_strrchr
+# include <string.h>
+# undef strrchr
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strrchr) __strrchr_i386 attribute_hidden;
+extern __typeof (__redirect_strrchr) __strrchr_sse2 attribute_hidden;
+extern __typeof (__redirect_strrchr) __strrchr_sse2_bsf attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strrchr) strrchr;
+extern void *strrchr_ifunc (void) __asm__ ("strrchr");
+
+void *
+strrchr_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Slow_BSF))
+	return __strrchr_sse2;
+      else
+	return __strrchr_sse2_bsf;
+    }
+
+  return __strrchr_i386;
+}
+__asm__ (".type strrchr, %gnu_indirect_function");
+weak_alias (strrchr, rindex)
+#endif

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

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

    Add i386 strcspn family multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 788dccb..8f8e450 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,13 +1,9 @@
 ifeq ($(subdir),string)
-sysdep_routines += varshift \
-		   strlen-sse2 strlen-sse2-bsf \
+sysdep_routines += strlen-sse2 strlen-sse2-bsf \
 		   strrchr-sse2 strrchr-sse2-bsf \
 		   strnlen-sse2 strnlen-c
 ifeq (yes,$(config-cflags-sse4))
-sysdep_routines += strcspn-c strpbrk-c strspn-c
-CFLAGS-varshift.c += -msse4
-CFLAGS-strcspn-c.c += -msse4
-CFLAGS-strpbrk-c.c += -msse4
+sysdep_routines += strspn-c
 CFLAGS-strspn-c.c += -msse4
 endif
 endif
diff --git a/sysdeps/i386/i686/multiarch/strcspn.S b/sysdeps/i386/i686/multiarch/strcspn.S
deleted file mode 100644
index b669b97..0000000
--- a/sysdeps/i386/i686/multiarch/strcspn.S
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Multiple versions of strcspn
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2009-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <config.h>
-
-#ifdef HAVE_SSE4_SUPPORT
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#ifdef USE_AS_STRPBRK
-#define STRCSPN_SSE42	__strpbrk_sse42
-#define STRCSPN_IA32	__strpbrk_ia32
-#define __GI_STRCSPN	__GI_strpbrk
-#else
-#ifndef STRCSPN
-#define STRCSPN		strcspn
-#define STRCSPN_SSE42	__strcspn_sse42
-#define STRCSPN_IA32	__strcspn_ia32
-#define __GI_STRCSPN	__GI_strcspn
-#endif
-#endif
-
-/* Define multiple versions only for the definition in libc.  Don't
-   define multiple versions for strpbrk in static library since we
-   need strpbrk before the initialization happened.  */
-#if (defined SHARED || !defined USE_AS_STRPBRK) && IS_IN (libc)
-	.text
-ENTRY(STRCSPN)
-	.type	STRCSPN, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (STRCSPN_IA32)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCSPN_SSE42)
-2:	ret
-END(STRCSPN)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type STRCSPN_IA32, @function; \
-	.globl STRCSPN_IA32; \
-	.p2align 4; \
-	STRCSPN_IA32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size STRCSPN_IA32, .-STRCSPN_IA32
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_STRCSPN; __GI_STRCSPN = STRCSPN_IA32
-#endif
-
-#endif /* HAVE_SSE4_SUPPORT */
-
-#ifdef USE_AS_STRPBRK
-#include "../../strpbrk.S"
-#else
-#include "../../strcspn.S"
-#endif
diff --git a/sysdeps/i386/i686/multiarch/strpbrk.S b/sysdeps/i386/i686/multiarch/strpbrk.S
deleted file mode 100644
index 7201d63..0000000
--- a/sysdeps/i386/i686/multiarch/strpbrk.S
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Multiple versions of strpbrk
-   All versions must be listed in ifunc-impl-list.c.  */
-#define STRCSPN strpbrk
-#define USE_AS_STRPBRK
-#include "strcspn.S"
diff --git a/sysdeps/i386/i686/multiarch/varshift.h b/sysdeps/i386/i686/multiarch/varshift.h
deleted file mode 100644
index 7c72c70..0000000
--- a/sysdeps/i386/i686/multiarch/varshift.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <sysdeps/x86_64/multiarch/varshift.h>
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 369a566..23c1f8b 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -34,7 +34,14 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   strncmp-i386 strncmp-ssse3 strncmp-sse4 \
 		   strcat-i386 strcat-sse2 strcat-ssse3 \
 		   strncat-i386 strncat-sse2 strncat-ssse3 \
-		   strchr-i386 strchr-i586 strchr-sse2-bsf strchr-sse2
+		   strchr-i386 strchr-i586 strchr-sse2-bsf strchr-sse2 \
+		   strcspn-i386 strpbrk-i386
+ifeq (yes,$(config-cflags-sse4))
+sysdep_routines += varshift strcspn-sse4 strpbrk-sse4
+CFLAGS-varshift.c += -msse4
+CFLAGS-strcspn-sse4.c += -msse4
+CFLAGS-strpbrk-sse4.c += -msse4
+endif
 endif
 
 ifeq (mathyes,$(subdir)$(config-cflags-avx))
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index b938329..2fc97a3 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -246,13 +246,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 #endif
 	     )
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/strcspn.S.  */
   IFUNC_IMPL (i, name, strcspn,
 	      IFUNC_IMPL_ADD (array, i, strcspn, HAS_CPU_FEATURE (SSE4_2),
 			      __strcspn_sse42)
-	      IFUNC_IMPL_ADD (array, i, strcspn, 1, __strcspn_ia32))
-#endif
+	      IFUNC_IMPL_ADD (array, i, strcspn, 1, __strcspn_i386))
 
   /* Support sysdeps/i386/i686/multiarch/strncase.S.  */
   IFUNC_IMPL (i, name, strncasecmp,
@@ -298,13 +296,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strnlen, HAS_CPU_FEATURE (SSE2),
 			      __strnlen_sse2)
 	      IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/strpbrk.S.  */
   IFUNC_IMPL (i, name, strpbrk,
 	      IFUNC_IMPL_ADD (array, i, strpbrk, HAS_CPU_FEATURE (SSE4_2),
 			      __strpbrk_sse42)
-	      IFUNC_IMPL_ADD (array, i, strpbrk, 1, __strpbrk_ia32))
+	      IFUNC_IMPL_ADD (array, i, strpbrk, 1, __strpbrk_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strrchr.S.  */
   IFUNC_IMPL (i, name, strrchr,
 	      IFUNC_IMPL_ADD (array, i, strrchr, HAS_CPU_FEATURE (SSE2),
diff --git a/sysdeps/i386/multiarch/strcspn-i386.S b/sysdeps/i386/multiarch/strcspn-i386.S
new file mode 100644
index 0000000..fd8d97b
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcspn-i386.S
@@ -0,0 +1,8 @@
+#define strcspn __strcspn_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/strcspn.S>
+
+	.globl __GI_strcspn
+	.hidden __GI_strcspn
+	__GI_strcspn = __strcspn_i386
diff --git a/sysdeps/i386/i686/multiarch/strcspn-c.c b/sysdeps/i386/multiarch/strcspn-sse4.c
similarity index 55%
rename from sysdeps/i386/i686/multiarch/strcspn-c.c
rename to sysdeps/i386/multiarch/strcspn-sse4.c
index 6d61e19..920da4d 100644
--- a/sysdeps/i386/i686/multiarch/strcspn-c.c
+++ b/sysdeps/i386/multiarch/strcspn-sse4.c
@@ -1,2 +1,2 @@
-#define __strcspn_sse2 __strcspn_ia32
+#define __strcspn_sse2 __strcspn_i386
 #include <sysdeps/x86_64/multiarch/strcspn-c.c>
diff --git a/sysdeps/i386/multiarch/strcspn.c b/sysdeps/i386/multiarch/strcspn.c
new file mode 100644
index 0000000..6d8674b
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcspn.c
@@ -0,0 +1,49 @@
+/* Multiple versions of strcspn.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define _HAVE_STRING_ARCH_strcspn
+/* Redefine strcspn so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strcspn
+# define strcspn __redirect_strcspn
+# include <string.h>
+# undef strcspn
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strcspn) __strcspn_i386 attribute_hidden;
+extern __typeof (__redirect_strcspn) __strcspn_sse42 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strcspn) strcspn;
+extern void *strcspn_ifunc (void) __asm__ ("strcspn");
+
+void *
+strcspn_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE4_2))
+    return __strcspn_sse42;
+
+  return __strcspn_i386;
+}
+__asm__ (".type strcspn, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/multiarch/strpbrk-i386.S b/sysdeps/i386/multiarch/strpbrk-i386.S
new file mode 100644
index 0000000..94e9133
--- /dev/null
+++ b/sysdeps/i386/multiarch/strpbrk-i386.S
@@ -0,0 +1,13 @@
+#ifdef SHARED
+# define strpbrk __strpbrk_i386
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+#endif
+
+#include <sysdeps/i386/strpbrk.S>
+
+#ifdef SHARED
+	.globl __GI_strpbrk
+	.hidden __GI_strpbrk
+	__GI_strpbrk = __strpbrk_i386
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strpbrk-c.c b/sysdeps/i386/multiarch/strpbrk-sse4.c
similarity index 55%
rename from sysdeps/i386/i686/multiarch/strpbrk-c.c
rename to sysdeps/i386/multiarch/strpbrk-sse4.c
index 5db6205..a63afc1 100644
--- a/sysdeps/i386/i686/multiarch/strpbrk-c.c
+++ b/sysdeps/i386/multiarch/strpbrk-sse4.c
@@ -1,2 +1,2 @@
-#define __strpbrk_sse2 __strpbrk_ia32
+#define __strpbrk_sse2 __strpbrk_i386
 #include <sysdeps/x86_64/multiarch/strpbrk-c.c>
diff --git a/sysdeps/i386/multiarch/strpbrk.c b/sysdeps/i386/multiarch/strpbrk.c
new file mode 100644
index 0000000..b857135
--- /dev/null
+++ b/sysdeps/i386/multiarch/strpbrk.c
@@ -0,0 +1,51 @@
+/* Multiple versions of strpbrk.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  Don't
+   define multiple versions for strpbrk in static library since we
+   need strpbrk before the initialization happened.  */
+#if defined SHARED && IS_IN (libc)
+# define _HAVE_STRING_ARCH_strpbrk
+/* Redefine strpbrk so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strpbrk
+# define strpbrk __redirect_strpbrk
+# include <string.h>
+# undef strpbrk
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strpbrk) __strpbrk_i386 attribute_hidden;
+extern __typeof (__redirect_strpbrk) __strpbrk_sse42 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strpbrk) strpbrk;
+extern void *strpbrk_ifunc (void) __asm__ ("strpbrk");
+
+void *
+strpbrk_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE4_2))
+    return __strpbrk_sse42;
+
+  return __strpbrk_i386;
+}
+__asm__ (".type strpbrk, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/i686/multiarch/varshift.c b/sysdeps/i386/multiarch/varshift.c
similarity index 100%
rename from sysdeps/i386/i686/multiarch/varshift.c
rename to sysdeps/i386/multiarch/varshift.c

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

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

    Add i386 strchr multiarch functions

diff --git a/sysdeps/i386/i586/multiarch/rtld-strchr.S b/sysdeps/i386/i586/multiarch/rtld-strchr.S
new file mode 100644
index 0000000..a26da1c
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/rtld-strchr.S
@@ -0,0 +1,19 @@
+/* strchr for ld.so
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdeps/i386/i586/strchr.S>
diff --git a/sysdeps/i386/i586/multiarch/strchr-i386.S b/sysdeps/i386/i586/multiarch/strchr-i386.S
new file mode 100644
index 0000000..74850fa
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strchr-i386.S
@@ -0,0 +1,8 @@
+#define strchr __strchr_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef libc_hidden_def
+#define libc_hidden_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/strchr.S>
diff --git a/sysdeps/i386/i586/multiarch/strchr-i586.S b/sysdeps/i386/i586/multiarch/strchr-i586.S
new file mode 100644
index 0000000..48e71aa
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strchr-i586.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/strchr-i586.S>
+
+#ifdef SHARED
+	.globl __GI_strchr
+	.hidden __GI_strchr
+	__GI_strchr = __strchr_i586
+#endif
diff --git a/sysdeps/i386/i586/multiarch/strchr.c b/sysdeps/i386/i586/multiarch/strchr.c
new file mode 100644
index 0000000..61c2f14
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strchr.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/strchr.c>
diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 830c77d..788dccb 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,7 +1,7 @@
 ifeq ($(subdir),string)
 sysdep_routines += varshift \
 		   strlen-sse2 strlen-sse2-bsf \
-		   strchr-sse2 strrchr-sse2 strchr-sse2-bsf strrchr-sse2-bsf \
+		   strrchr-sse2 strrchr-sse2-bsf \
 		   strnlen-sse2 strnlen-c
 ifeq (yes,$(config-cflags-sse4))
 sysdep_routines += strcspn-c strpbrk-c strspn-c
diff --git a/sysdeps/i386/i686/multiarch/strchr-i586.S b/sysdeps/i386/i686/multiarch/strchr-i586.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/strchr-i586.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/strchr.S b/sysdeps/i386/i686/multiarch/strchr.S
deleted file mode 100644
index 6b46565..0000000
--- a/sysdeps/i386/i686/multiarch/strchr.S
+++ /dev/null
@@ -1,57 +0,0 @@
-/* Multiple versions of strchr
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if IS_IN (libc)
-	.text
-ENTRY(strchr)
-	.type	strchr, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__strchr_ia32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strchr_sse2_bsf)
-	HAS_ARCH_FEATURE (Slow_BSF)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__strchr_sse2)
-2:	ret
-END(strchr)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __strchr_ia32, @function; \
-	.globl __strchr_ia32; \
-	.p2align 4; \
-	__strchr_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __strchr_ia32, .-__strchr_ia32
-# undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-# define libc_hidden_builtin_def(name) \
-	.globl __GI_strchr; __GI_strchr = __strchr_ia32
-#endif
-
-#include "../../i586/strchr.S"
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 87d36a4..369a566 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -33,7 +33,8 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   strncase_l-ssse3 \
 		   strncmp-i386 strncmp-ssse3 strncmp-sse4 \
 		   strcat-i386 strcat-sse2 strcat-ssse3 \
-		   strncat-i386 strncat-sse2 strncat-ssse3
+		   strncat-i386 strncat-sse2 strncat-ssse3 \
+		   strchr-i386 strchr-i586 strchr-sse2-bsf strchr-sse2
 endif
 
 ifeq (mathyes,$(subdir)$(config-cflags-avx))
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 05b9bcd..b938329 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -214,15 +214,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strcat_sse2)
 	      IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/strchr.S.  */
   IFUNC_IMPL (i, name, strchr,
 	      IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2),
 			      __strchr_sse2_bsf)
 	      IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2),
 			      __strchr_sse2)
-	      IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_ia32))
-#endif
+	      IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_i386))
 
   /* Support sysdeps/i386/i686/multiarch/strcmp.S.  */
   IFUNC_IMPL (i, name, strcmp,
diff --git a/sysdeps/i386/multiarch/rtld-strchr.S b/sysdeps/i386/multiarch/rtld-strchr.S
new file mode 100644
index 0000000..a032fdb
--- /dev/null
+++ b/sysdeps/i386/multiarch/rtld-strchr.S
@@ -0,0 +1,19 @@
+/* strchr for ld.so
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdeps/i386/strchr.S>
diff --git a/sysdeps/i386/multiarch/strchr-i386.S b/sysdeps/i386/multiarch/strchr-i386.S
new file mode 100644
index 0000000..aff0f7a
--- /dev/null
+++ b/sysdeps/i386/multiarch/strchr-i386.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/i586/multiarch/strchr-i386.S>
+
+#ifdef SHARED
+	.globl __GI_strchr
+	.hidden __GI_strchr
+	__GI_strchr = __strchr_i386
+#endif
diff --git a/sysdeps/i386/multiarch/strchr-i586.S b/sysdeps/i386/multiarch/strchr-i586.S
new file mode 100644
index 0000000..b4327f4
--- /dev/null
+++ b/sysdeps/i386/multiarch/strchr-i586.S
@@ -0,0 +1,8 @@
+#define strchr __strchr_i586
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef libc_hidden_def
+#define libc_hidden_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/i586/strchr.S>
diff --git a/sysdeps/i386/i686/multiarch/strchr-sse2-bsf.S b/sysdeps/i386/multiarch/strchr-sse2-bsf.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strchr-sse2-bsf.S
rename to sysdeps/i386/multiarch/strchr-sse2-bsf.S
diff --git a/sysdeps/i386/i686/multiarch/strchr-sse2.S b/sysdeps/i386/multiarch/strchr-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strchr-sse2.S
rename to sysdeps/i386/multiarch/strchr-sse2.S
diff --git a/sysdeps/i386/multiarch/strchr.c b/sysdeps/i386/multiarch/strchr.c
new file mode 100644
index 0000000..015b51c
--- /dev/null
+++ b/sysdeps/i386/multiarch/strchr.c
@@ -0,0 +1,60 @@
+/* Multiple versions of strchr
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define _HAVE_STRING_ARCH_strchr
+/* Redefine strchr so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strchr
+# define strchr __redirect_strchr
+# include <string.h>
+# undef strchr
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strchr) __strchr_i386 attribute_hidden;
+extern __typeof (__redirect_strchr) __strchr_i586 attribute_hidden;
+extern __typeof (__redirect_strchr) __strchr_sse2 attribute_hidden;
+extern __typeof (__redirect_strchr) __strchr_sse2_bsf attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strchr) strchr;
+extern void *strchr_ifunc (void) __asm__ ("strchr");
+
+void *
+strchr_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE2))
+    {
+      if (HAS_ARCH_FEATURE (Slow_BSF))
+	return __strchr_sse2;
+      else
+	return __strchr_sse2_bsf;
+    }
+
+  if (USE_I586)
+    return __strchr_i586;
+  else
+    return __strchr_i386;
+}
+__asm__ (".type strchr, %gnu_indirect_function");
+weak_alias (strchr, index)
+#endif

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

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

    Add i386 strcat multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index d38a051..830c77d 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,8 +1,6 @@
 ifeq ($(subdir),string)
 sysdep_routines += varshift \
 		   strlen-sse2 strlen-sse2-bsf \
-		   strcat-ssse3 \
-		   strcat-sse2 strncat-ssse3 strncat-sse2 strncat-c \
 		   strchr-sse2 strrchr-sse2 strchr-sse2-bsf strrchr-sse2-bsf \
 		   strnlen-sse2 strnlen-c
 ifeq (yes,$(config-cflags-sse4))
diff --git a/sysdeps/i386/i686/multiarch/strcat.S b/sysdeps/i386/i686/multiarch/strcat.S
deleted file mode 100644
index e893815..0000000
--- a/sysdeps/i386/i686/multiarch/strcat.S
+++ /dev/null
@@ -1,92 +0,0 @@
-/* Multiple versions of strcat
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#ifndef USE_AS_STRNCAT
-# ifndef STRCAT
-#  define STRCAT strcat
-# endif
-#endif
-
-#ifdef USE_AS_STRNCAT
-# define STRCAT_SSSE3	__strncat_ssse3
-# define STRCAT_SSE2		__strncat_sse2
-# define STRCAT_IA32		__strncat_ia32
-# define __GI_STRCAT		__GI_strncat
-#else
-# define STRCAT_SSSE3	__strcat_ssse3
-# define STRCAT_SSE2		__strcat_sse2
-# define STRCAT_IA32		__strcat_ia32
-# define __GI_STRCAT		__GI_strcat
-#endif
-
-
-/* Define multiple versions only for the definition in libc.  Don't
-   define multiple versions for strncat in static library since we
-   need strncat before the initialization happened.  */
-#if IS_IN (libc)
-
-	.text
-ENTRY(STRCAT)
-	.type	STRCAT, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (STRCAT_IA32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCAT_SSE2)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCAT_SSSE3)
-2:	ret
-END(STRCAT)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type STRCAT_IA32, @function; \
-	.align 16; \
-	.globl STRCAT_IA32; \
-	.hidden STRCAT_IA32; \
-	STRCAT_IA32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size STRCAT_IA32, .-STRCAT_IA32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* It doesn't make sense to send libc-internal strcat calls through a PLT.
-   The speedup we get from using SSSE3 instruction is likely eaten away
-   by the indirect call in the PLT.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_STRCAT; __GI_STRCAT = STRCAT_IA32
-#  undef libc_hidden_def
-#  define libc_hidden_def(name) \
-	.globl __GI___STRCAT; __GI___STRCAT = STRCAT_IA32
-
-# endif
-#endif
-
-#ifndef USE_AS_STRNCAT
-# include "../../strcat.S"
-#endif
diff --git a/sysdeps/i386/i686/multiarch/strncat.S b/sysdeps/i386/i686/multiarch/strncat.S
deleted file mode 100644
index 5c1bf41..0000000
--- a/sysdeps/i386/i686/multiarch/strncat.S
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Multiple versions of strncat
-   All versions must be listed in ifunc-impl-list.c.  */
-#define STRCAT strncat
-#define USE_AS_STRNCAT
-#include "strcat.S"
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 78a99a7..87d36a4 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -31,7 +31,9 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   strcasecmp_l-ssse3 \
 		   strncase-i386 strncase_l-i386 strncase_l-sse4 \
 		   strncase_l-ssse3 \
-		   strncmp-i386 strncmp-ssse3 strncmp-sse4 
+		   strncmp-i386 strncmp-ssse3 strncmp-sse4 \
+		   strcat-i386 strcat-sse2 strcat-ssse3 \
+		   strncat-i386 strncat-sse2 strncat-ssse3
 endif
 
 ifeq (mathyes,$(subdir)$(config-cflags-avx))
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index bddc9e7..05b9bcd 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -206,15 +206,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1,
 			      __strcasecmp_l_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/strcat.S.  */
   IFUNC_IMPL (i, name, strcat,
 	      IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSSE3),
 			      __strcat_ssse3)
 	      IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSE2),
 			      __strcat_sse2)
-	      IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_ia32))
+	      IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strchr.S.  */
   IFUNC_IMPL (i, name, strchr,
 	      IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2),
@@ -278,15 +278,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1,
 			      __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),
 			      __strncat_ssse3)
 	      IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSE2),
 			      __strncat_sse2)
-	      IFUNC_IMPL_ADD (array, i, strncat, 1, __strncat_ia32))
-#endif
+	      IFUNC_IMPL_ADD (array, i, strncat, 1, __strncat_i386))
 
   /* Support sysdeps/i386/i686/multiarch/strncpy.S.  */
   IFUNC_IMPL (i, name, strncpy,
diff --git a/sysdeps/i386/multiarch/strcat-i386.S b/sysdeps/i386/multiarch/strcat-i386.S
new file mode 100644
index 0000000..c13503d
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcat-i386.S
@@ -0,0 +1,10 @@
+#define strcat __strcat_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/strcat.S>
+
+#ifdef SHARED
+	.globl __GI_strcat
+	.hidden __GI_strcat
+	__GI_strcat = __strcat_i386
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strcat-sse2.S b/sysdeps/i386/multiarch/strcat-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strcat-sse2.S
rename to sysdeps/i386/multiarch/strcat-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/strcat-ssse3.S b/sysdeps/i386/multiarch/strcat-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strcat-ssse3.S
rename to sysdeps/i386/multiarch/strcat-ssse3.S
diff --git a/sysdeps/i386/multiarch/strcat.c b/sysdeps/i386/multiarch/strcat.c
new file mode 100644
index 0000000..5a2aa9c
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcat.c
@@ -0,0 +1,51 @@
+/* Multiple versions of strcat.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+/* Redefine strcat so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strcat
+# define strcat __redirect_strcat
+# include <string.h>
+# undef strcat
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strcat) __strcat_i386 attribute_hidden;
+extern __typeof (__redirect_strcat) __strcat_sse2 attribute_hidden;
+extern __typeof (__redirect_strcat) __strcat_ssse3 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strcat) strcat;
+extern void *strcat_ifunc (void) __asm__ ("strcat");
+
+void *
+strcat_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    return __strcat_ssse3;
+  else if (HAS_CPU_FEATURE (SSE2))
+    return __strcat_sse2;
+
+  return __strcat_i386;
+}
+__asm__ (".type strcat, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/i686/multiarch/strlen-sse2.S b/sysdeps/i386/multiarch/strlen-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strlen-sse2.S
rename to sysdeps/i386/multiarch/strlen-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/strncat-c.c b/sysdeps/i386/multiarch/strncat-i386.c
similarity index 52%
rename from sysdeps/i386/i686/multiarch/strncat-c.c
rename to sysdeps/i386/multiarch/strncat-i386.c
index 132a000..0f22fbc 100644
--- a/sysdeps/i386/i686/multiarch/strncat-c.c
+++ b/sysdeps/i386/multiarch/strncat-i386.c
@@ -1,8 +1,8 @@
-#define STRNCAT __strncat_ia32
+#define STRNCAT __strncat_i386
 #ifdef SHARED
 #undef libc_hidden_def
 #define libc_hidden_def(name) \
-  __hidden_ver1 (__strncat_ia32, __GI___strncat, __strncat_ia32);
+  __hidden_ver1 (__strncat_i386, __GI___strncat, __strncat_i386);
 #endif
 
 #include "string/strncat.c"
diff --git a/sysdeps/i386/i686/multiarch/strncat-sse2.S b/sysdeps/i386/multiarch/strncat-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strncat-sse2.S
rename to sysdeps/i386/multiarch/strncat-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/strncat-ssse3.S b/sysdeps/i386/multiarch/strncat-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strncat-ssse3.S
rename to sysdeps/i386/multiarch/strncat-ssse3.S
diff --git a/sysdeps/i386/multiarch/strncat.c b/sysdeps/i386/multiarch/strncat.c
new file mode 100644
index 0000000..7ab3e38
--- /dev/null
+++ b/sysdeps/i386/multiarch/strncat.c
@@ -0,0 +1,54 @@
+/* Multiple versions of strncat.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  Don't
+   define multiple versions for strncat in static library since we
+   need strncat before the initialization happened.  */
+#if defined  SHARED && IS_IN (libc)
+# define _HAVE_STRING_ARCH_strncat
+/* Redefine strncat so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strncat
+# define strncat __redirect_strncat
+# include <string.h>
+# undef strncat
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strncat) __strncat_i386 attribute_hidden;
+extern __typeof (__redirect_strncat) __strncat_sse2 attribute_hidden;
+extern __typeof (__redirect_strncat) __strncat_ssse3 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strncat) strncat;
+extern void *strncat_ifunc (void) __asm__ ("strncat");
+
+void *
+strncat_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    return __strncat_ssse3;
+  else if (HAS_CPU_FEATURE (SSE2))
+    return __strncat_sse2;
+
+  return __strncat_i386;
+}
+__asm__ (".type strncat, %gnu_indirect_function");
+#endif

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

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

    Add i386 strcmp family multiarch functions

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

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

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

    Add i386 strcpy family multiarch functions

diff --git a/sysdeps/i386/i586/multiarch/rtld-stpcpy.S b/sysdeps/i386/i586/multiarch/rtld-stpcpy.S
new file mode 100644
index 0000000..dc0e337
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/rtld-stpcpy.S
@@ -0,0 +1,19 @@
+/* stpcpy for ld.so
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdeps/i386/i586/stpcpy.S>
diff --git a/sysdeps/i386/i586/multiarch/stpcpy-i386.S b/sysdeps/i386/i586/multiarch/stpcpy-i386.S
new file mode 100644
index 0000000..80d8bea
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/stpcpy-i386.S
@@ -0,0 +1,8 @@
+#define __stpcpy __stpcpy_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef libc_hidden_def
+#define libc_hidden_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/stpcpy.S>
diff --git a/sysdeps/i386/i586/multiarch/stpcpy-i586.S b/sysdeps/i386/i586/multiarch/stpcpy-i586.S
new file mode 100644
index 0000000..ad942bf
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/stpcpy-i586.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/stpcpy-i586.S>
+
+#ifdef SHARED
+	.globl __GI_stpcpy
+	.hidden __GI_stpcpy
+	__GI_stpcpy = __stpcpy_i586
+#endif
diff --git a/sysdeps/i386/i586/multiarch/stpcpy.c b/sysdeps/i386/i586/multiarch/stpcpy.c
new file mode 100644
index 0000000..ab6cc06
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/stpcpy.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/stpcpy.c>
diff --git a/sysdeps/i386/i586/multiarch/strcpy-i586.S b/sysdeps/i386/i586/multiarch/strcpy-i586.S
new file mode 100644
index 0000000..b9b15b5
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strcpy-i586.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/strcpy-i586.S>
+
+#ifdef SHARED
+	.globl __GI_strcpy
+	.hidden __GI_strcpy
+	__GI_strcpy = __strcpy_i586
+#endif
diff --git a/sysdeps/i386/i586/multiarch/strcpy.c b/sysdeps/i386/i586/multiarch/strcpy.c
new file mode 100644
index 0000000..65f5398
--- /dev/null
+++ b/sysdeps/i386/i586/multiarch/strcpy.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/strcpy.c>
diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 101bb7d..2a14fe8 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -2,9 +2,8 @@ ifeq ($(subdir),string)
 sysdep_routines += strcmp-ssse3 \
 		   strcmp-sse4 strncmp-c strncmp-ssse3 strncmp-sse4 \
 		   varshift \
-		   strlen-sse2 strlen-sse2-bsf strncpy-c strcpy-ssse3 \
-		   strncpy-ssse3 stpcpy-ssse3 stpncpy-ssse3 strcpy-sse2 \
-		   strncpy-sse2 stpcpy-sse2 stpncpy-sse2 strcat-ssse3 \
+		   strlen-sse2 strlen-sse2-bsf \
+		   strcat-ssse3 \
 		   strcat-sse2 strncat-ssse3 strncat-sse2 strncat-c \
 		   strchr-sse2 strrchr-sse2 strchr-sse2-bsf strrchr-sse2-bsf \
 		   strnlen-sse2 strnlen-c \
diff --git a/sysdeps/i386/i686/multiarch/stpcpy.S b/sysdeps/i386/i686/multiarch/stpcpy.S
deleted file mode 100644
index ee81ab6..0000000
--- a/sysdeps/i386/i686/multiarch/stpcpy.S
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Multiple versions of stpcpy
-   All versions must be listed in ifunc-impl-list.c.  */
-#define USE_AS_STPCPY
-#define STRCPY __stpcpy
-#include "strcpy.S"
-
-weak_alias (__stpcpy, stpcpy)
-libc_hidden_def (__stpcpy)
-libc_hidden_builtin_def (stpcpy)
diff --git a/sysdeps/i386/i686/multiarch/stpncpy.S b/sysdeps/i386/i686/multiarch/stpncpy.S
deleted file mode 100644
index 2698ca6..0000000
--- a/sysdeps/i386/i686/multiarch/stpncpy.S
+++ /dev/null
@@ -1,8 +0,0 @@
-/* Multiple versions of stpncpy
-   All versions must be listed in ifunc-impl-list.c.  */
-#define STRCPY __stpncpy
-#define USE_AS_STPCPY
-#define USE_AS_STRNCPY
-#include "strcpy.S"
-
-weak_alias (__stpncpy, stpncpy)
diff --git a/sysdeps/i386/i686/multiarch/strcpy.S b/sysdeps/i386/i686/multiarch/strcpy.S
deleted file mode 100644
index e9db766..0000000
--- a/sysdeps/i386/i686/multiarch/strcpy.S
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Multiple versions of strcpy
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2011-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-#if !defined (USE_AS_STPCPY) && !defined (USE_AS_STRNCPY)
-# ifndef STRCPY
-#  define STRCPY strcpy
-# endif
-#endif
-
-#ifdef USE_AS_STPCPY
-# ifdef USE_AS_STRNCPY
-#  define STRCPY_SSSE3	__stpncpy_ssse3
-#  define STRCPY_SSE2		__stpncpy_sse2
-#  define STRCPY_IA32		__stpncpy_ia32
-#  define __GI_STRCPY		__GI_stpncpy
-#  define __GI___STRCPY		__GI___stpncpy
-# else
-#  define STRCPY_SSSE3	__stpcpy_ssse3
-#  define STRCPY_SSE2		__stpcpy_sse2
-#  define STRCPY_IA32		__stpcpy_ia32
-#  define __GI_STRCPY		__GI_stpcpy
-#  define __GI___STRCPY		__GI___stpcpy
-# endif
-#else
-# ifdef USE_AS_STRNCPY
-#  define STRCPY_SSSE3	__strncpy_ssse3
-#  define STRCPY_SSE2		__strncpy_sse2
-#  define STRCPY_IA32		__strncpy_ia32
-#  define __GI_STRCPY		__GI_strncpy
-# else
-#  define STRCPY_SSSE3	__strcpy_ssse3
-#  define STRCPY_SSE2		__strcpy_sse2
-#  define STRCPY_IA32		__strcpy_ia32
-#  define __GI_STRCPY		__GI_strcpy
-# endif
-#endif
-
-
-/* Define multiple versions only for the definition in libc.  Don't
-   define multiple versions for strncpy in static library since we
-   need strncpy before the initialization happened.  */
-#if IS_IN (libc)
-
-	.text
-ENTRY(STRCPY)
-	.type	STRCPY, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (STRCPY_IA32)
-	HAS_CPU_FEATURE (SSE2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCPY_SSE2)
-	HAS_ARCH_FEATURE (Fast_Unaligned_Load)
-	jnz	2f
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (STRCPY_SSSE3)
-2:	ret
-END(STRCPY)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type STRCPY_IA32, @function; \
-	.align 16; \
-	.globl STRCPY_IA32; \
-	.hidden STRCPY_IA32; \
-	STRCPY_IA32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size STRCPY_IA32, .-STRCPY_IA32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* It doesn't make sense to send libc-internal strcpy calls through a PLT.
-   The speedup we get from using SSSE3 instruction is likely eaten away
-   by the indirect call in the PLT.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_STRCPY; __GI_STRCPY = STRCPY_IA32
-#  undef libc_hidden_def
-#  define libc_hidden_def(name) \
-	.globl __GI___STRCPY; __GI___STRCPY = STRCPY_IA32
-
-# endif
-#endif
-
-#ifdef USE_AS_STPCPY
-# ifdef USE_AS_STRNCPY
-#  include "../../stpncpy.S"
-# else
-#  include "../../i586/stpcpy.S"
-# endif
-#else
-# ifndef USE_AS_STRNCPY
-#  include "../../i586/strcpy.S"
-# endif
-#endif
diff --git a/sysdeps/i386/i686/multiarch/strncpy-c.c b/sysdeps/i386/i686/multiarch/strncpy-c.c
deleted file mode 100644
index 201e3f9..0000000
--- a/sysdeps/i386/i686/multiarch/strncpy-c.c
+++ /dev/null
@@ -1,8 +0,0 @@
-#define STRNCPY __strncpy_ia32
-#ifdef SHARED
-# undef libc_hidden_builtin_def
-# define libc_hidden_builtin_def(name)  \
-    __hidden_ver1 (__strncpy_ia32, __GI_strncpy, __strncpy_ia32);
-#endif
-
-#include "string/strncpy.c"
diff --git a/sysdeps/i386/i686/multiarch/strncpy.S b/sysdeps/i386/i686/multiarch/strncpy.S
deleted file mode 100644
index 9c257ef..0000000
--- a/sysdeps/i386/i686/multiarch/strncpy.S
+++ /dev/null
@@ -1,5 +0,0 @@
-/* Multiple versions of strncpy
-   All versions must be listed in ifunc-impl-list.c.  */
-#define USE_AS_STRNCPY
-#define STRCPY strncpy
-#include "strcpy.S"
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 32d3783..1518cae 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -21,7 +21,11 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   memchr-sse2-bsf memchr-sse2 \
 		   memcmp-i386 memcmp-i686 memcmp-ssse3 memcmp-sse4 \
 		   memrchr-i386 memrchr-sse2-bsf memrchr-sse2 \
-		   rawmemchr-sse2-bsf rawmemchr-sse2
+		   rawmemchr-sse2-bsf rawmemchr-sse2 \
+		   stpcpy-i386 stpcpy-i586 stpcpy-sse2 stpcpy-ssse3 \
+		   stpncpy-i386 stpncpy-sse2 stpncpy-ssse3 \
+		   strcpy-i386 strcpy-i586 strcpy-sse2 strcpy-ssse3 \
+		   strncpy-i386 strncpy-sse2 strncpy-ssse3
 endif
 
 ifeq (mathyes,$(subdir)$(config-cflags-avx))
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index ce5abeb..412f227 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -165,14 +165,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __rawmemchr_sse2)
 	      IFUNC_IMPL_ADD (array, i, rawmemchr, 1, __rawmemchr_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/stpncpy.S.  */
   IFUNC_IMPL (i, name, stpncpy,
 	      IFUNC_IMPL_ADD (array, i, stpncpy, HAS_CPU_FEATURE (SSSE3),
 			      __stpncpy_ssse3)
 	      IFUNC_IMPL_ADD (array, i, stpncpy, HAS_CPU_FEATURE (SSE2),
 			      __stpncpy_sse2)
-	      IFUNC_IMPL_ADD (array, i, stpncpy, 1, __stpncpy_ia32))
+	      IFUNC_IMPL_ADD (array, i, stpncpy, 1, __stpncpy_i386))
 
   /* Support sysdeps/i386/i686/multiarch/stpcpy.S.  */
   IFUNC_IMPL (i, name, stpcpy,
@@ -180,8 +179,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __stpcpy_ssse3)
 	      IFUNC_IMPL_ADD (array, i, stpcpy, HAS_CPU_FEATURE (SSE2),
 			      __stpcpy_sse2)
-	      IFUNC_IMPL_ADD (array, i, stpcpy, 1, __stpcpy_ia32))
+	      IFUNC_IMPL_ADD (array, i, stpcpy, HAS_I586, __stpcpy_i586)
+#if MINIMUM_ISA < 586
+	      IFUNC_IMPL_ADD (array, i, stpcpy, 1, __stpcpy_i386)
+#endif
+	     )
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strcasecmp.S.  */
   IFUNC_IMPL (i, name, strcasecmp,
 	      IFUNC_IMPL_ADD (array, i, strcasecmp,
@@ -226,6 +230,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSSE3),
 			      __strcmp_ssse3)
 	      IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/strcpy.S.  */
   IFUNC_IMPL (i, name, strcpy,
@@ -233,8 +238,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strcpy_ssse3)
 	      IFUNC_IMPL_ADD (array, i, strcpy, HAS_CPU_FEATURE (SSE2),
 			      __strcpy_sse2)
-	      IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_ia32))
+	      IFUNC_IMPL_ADD (array, i, strcpy, HAS_I586, __strcpy_i586)
+#if MINIMUM_ISA < 586
+	      IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_i386)
+#endif
+	     )
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strcspn.S.  */
   IFUNC_IMPL (i, name, strcspn,
 	      IFUNC_IMPL_ADD (array, i, strcspn, HAS_CPU_FEATURE (SSE4_2),
@@ -270,6 +280,7 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 	      IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSE2),
 			      __strncat_sse2)
 	      IFUNC_IMPL_ADD (array, i, strncat, 1, __strncat_ia32))
+#endif
 
   /* Support sysdeps/i386/i686/multiarch/strncpy.S.  */
   IFUNC_IMPL (i, name, strncpy,
@@ -277,8 +288,9 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __strncpy_ssse3)
 	      IFUNC_IMPL_ADD (array, i, strncpy, HAS_CPU_FEATURE (SSE2),
 			      __strncpy_sse2)
-	      IFUNC_IMPL_ADD (array, i, strncpy, 1, __strncpy_ia32))
+	      IFUNC_IMPL_ADD (array, i, strncpy, 1, __strncpy_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/strnlen.S.  */
   IFUNC_IMPL (i, name, strnlen,
 	      IFUNC_IMPL_ADD (array, i, strnlen, HAS_CPU_FEATURE (SSE2),
diff --git a/sysdeps/i386/multiarch/rtld-stpcpy.S b/sysdeps/i386/multiarch/rtld-stpcpy.S
new file mode 100644
index 0000000..5a49821
--- /dev/null
+++ b/sysdeps/i386/multiarch/rtld-stpcpy.S
@@ -0,0 +1,19 @@
+/* stpcpy for ld.so
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdeps/i386/stpcpy.S>
diff --git a/sysdeps/i386/multiarch/stpcpy-i386.S b/sysdeps/i386/multiarch/stpcpy-i386.S
new file mode 100644
index 0000000..ef1ff41
--- /dev/null
+++ b/sysdeps/i386/multiarch/stpcpy-i386.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/i586/multiarch/stpcpy-i386.S>
+
+#ifdef SHARED
+	.globl __GI_stpcpy
+	.hidden __GI_stpcpy
+	__GI_stpcpy = __stpcpy_i386
+#endif
diff --git a/sysdeps/i386/multiarch/stpcpy-i586.S b/sysdeps/i386/multiarch/stpcpy-i586.S
new file mode 100644
index 0000000..f797959
--- /dev/null
+++ b/sysdeps/i386/multiarch/stpcpy-i586.S
@@ -0,0 +1,8 @@
+#define __stpcpy __stpcpy_i586
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef libc_hidden_def
+#define libc_hidden_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/i586/stpcpy.S>
diff --git a/sysdeps/i386/i686/multiarch/stpcpy-sse2.S b/sysdeps/i386/multiarch/stpcpy-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/stpcpy-sse2.S
rename to sysdeps/i386/multiarch/stpcpy-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/stpcpy-ssse3.S b/sysdeps/i386/multiarch/stpcpy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/stpcpy-ssse3.S
rename to sysdeps/i386/multiarch/stpcpy-ssse3.S
diff --git a/sysdeps/i386/multiarch/stpcpy.c b/sysdeps/i386/multiarch/stpcpy.c
new file mode 100644
index 0000000..58a54fc
--- /dev/null
+++ b/sysdeps/i386/multiarch/stpcpy.c
@@ -0,0 +1,59 @@
+/* Multiple versions of stpcpy.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define _HAVE_STRING_ARCH_stpcpy
+# define NO_MEMPCPY_STPCPY_REDIRECT
+/* Redefine stpcpy so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef stpcpy
+# define stpcpy __redirect_stpcpy
+# include <string.h>
+# undef stpcpy
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_stpcpy) __stpcpy_i386 attribute_hidden;
+extern __typeof (__redirect_stpcpy) __stpcpy_i586 attribute_hidden;
+extern __typeof (__redirect_stpcpy) __stpcpy_sse2 attribute_hidden;
+extern __typeof (__redirect_stpcpy) __stpcpy_ssse3 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_stpcpy) __stpcpy;
+extern void *stpcpy_ifunc (void) __asm__ ("__stpcpy");
+
+void *
+stpcpy_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    return __stpcpy_ssse3;
+  else if (HAS_CPU_FEATURE (SSE2))
+    return __stpcpy_sse2;
+
+  if (USE_I586)
+    return __stpcpy_i586;
+  else
+    return __stpcpy_i386;
+}
+__asm__ (".type __stpcpy, %gnu_indirect_function");
+
+weak_alias (__stpcpy, stpcpy)
+#endif
diff --git a/sysdeps/i386/multiarch/stpncpy-i386.S b/sysdeps/i386/multiarch/stpncpy-i386.S
new file mode 100644
index 0000000..3cd0903
--- /dev/null
+++ b/sysdeps/i386/multiarch/stpncpy-i386.S
@@ -0,0 +1,12 @@
+#define __stpncpy __stpncpy_i386
+#undef libc_hidden_def
+#define libc_hidden_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/stpncpy.S>
+
+#ifdef SHARED
+	.globl __GI___stpncpy
+	.hidden __GI___stpncpy
+	__GI___stpncpy = __stpncpy_i386
+#endif
diff --git a/sysdeps/i386/i686/multiarch/stpncpy-sse2.S b/sysdeps/i386/multiarch/stpncpy-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/stpncpy-sse2.S
rename to sysdeps/i386/multiarch/stpncpy-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/stpncpy-ssse3.S b/sysdeps/i386/multiarch/stpncpy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/stpncpy-ssse3.S
rename to sysdeps/i386/multiarch/stpncpy-ssse3.S
diff --git a/sysdeps/i386/multiarch/stpncpy.c b/sysdeps/i386/multiarch/stpncpy.c
new file mode 100644
index 0000000..609d8d4
--- /dev/null
+++ b/sysdeps/i386/multiarch/stpncpy.c
@@ -0,0 +1,54 @@
+/* Multiple versions of stpncpy.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define _HAVE_STRING_ARCH_stpncpy
+/* Redefine stpncpy so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef stpncpy
+# define stpncpy __redirect_stpncpy
+# include <string.h>
+# undef stpncpy
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_stpncpy) __stpncpy_i386 attribute_hidden;
+extern __typeof (__redirect_stpncpy) __stpncpy_sse2 attribute_hidden;
+extern __typeof (__redirect_stpncpy) __stpncpy_ssse3 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_stpncpy) __stpncpy;
+extern void *stpncpy_ifunc (void) __asm__ ("__stpncpy");
+
+void *
+stpncpy_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    return __stpncpy_ssse3;
+  else if (HAS_CPU_FEATURE (SSE2))
+    return __stpncpy_sse2;
+
+  return __stpncpy_i386;
+}
+__asm__ (".type __stpncpy, %gnu_indirect_function");
+
+weak_alias (__stpncpy, stpncpy)
+#endif
diff --git a/sysdeps/i386/multiarch/strcpy-i386.c b/sysdeps/i386/multiarch/strcpy-i386.c
new file mode 100644
index 0000000..e577628
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcpy-i386.c
@@ -0,0 +1,11 @@
+#include <init-arch.h>
+#undef libc_hidden_builtin_def
+#if defined SHARED && MINIMUM_ISA != 586
+# define libc_hidden_builtin_def(name)  \
+   __hidden_ver1 (__strcpy_i386, __GI_strcpy, __strcpy_i386);
+#else
+# define libc_hidden_builtin_def(name)
+#endif
+
+#define STRCPY __strcpy_i386
+#include "string/strcpy.c"
diff --git a/sysdeps/i386/multiarch/strcpy-i586.S b/sysdeps/i386/multiarch/strcpy-i586.S
new file mode 100644
index 0000000..65e0641
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcpy-i586.S
@@ -0,0 +1,4 @@
+#define strcpy __strcpy_i586
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/i586/strcpy.S>
diff --git a/sysdeps/i386/i686/multiarch/strcpy-sse2.S b/sysdeps/i386/multiarch/strcpy-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strcpy-sse2.S
rename to sysdeps/i386/multiarch/strcpy-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/strcpy-ssse3.S b/sysdeps/i386/multiarch/strcpy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strcpy-ssse3.S
rename to sysdeps/i386/multiarch/strcpy-ssse3.S
diff --git a/sysdeps/i386/multiarch/strcpy.c b/sysdeps/i386/multiarch/strcpy.c
new file mode 100644
index 0000000..ede627c
--- /dev/null
+++ b/sysdeps/i386/multiarch/strcpy.c
@@ -0,0 +1,55 @@
+/* Multiple versions of strcpy.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+/* Redefine strcpy so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strcpy
+# define strcpy __redirect_strcpy
+# include <string.h>
+# undef strcpy
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strcpy) __strcpy_i386 attribute_hidden;
+extern __typeof (__redirect_strcpy) __strcpy_i586 attribute_hidden;
+extern __typeof (__redirect_strcpy) __strcpy_sse2 attribute_hidden;
+extern __typeof (__redirect_strcpy) __strcpy_ssse3 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strcpy) strcpy;
+extern void *strcpy_ifunc (void) __asm__ ("strcpy");
+
+void *
+strcpy_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    return __strcpy_ssse3;
+  else if (HAS_CPU_FEATURE (SSE2))
+    return __strcpy_sse2;
+
+  if (USE_I586)
+    return __strcpy_i586;
+  else
+    return __strcpy_i386;
+}
+__asm__ (".type strcpy, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/multiarch/strncpy-i386.c b/sysdeps/i386/multiarch/strncpy-i386.c
new file mode 100644
index 0000000..b584d83
--- /dev/null
+++ b/sysdeps/i386/multiarch/strncpy-i386.c
@@ -0,0 +1,12 @@
+#include <init-arch.h>
+#undef libc_hidden_builtin_def
+#ifdef SHARED
+# define libc_hidden_builtin_def(name)  \
+    __hidden_ver1 (__strncpy_i386, __GI_strncpy, __strncpy_i386);
+#else
+# define libc_hidden_builtin_def(name)
+#endif
+
+#define _HAVE_STRING_ARCH_strncpy
+#define STRNCPY __strncpy_i386
+#include "string/strncpy.c"
diff --git a/sysdeps/i386/i686/multiarch/strncpy-sse2.S b/sysdeps/i386/multiarch/strncpy-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strncpy-sse2.S
rename to sysdeps/i386/multiarch/strncpy-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/strncpy-ssse3.S b/sysdeps/i386/multiarch/strncpy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/strncpy-ssse3.S
rename to sysdeps/i386/multiarch/strncpy-ssse3.S
diff --git a/sysdeps/i386/multiarch/strncpy.c b/sysdeps/i386/multiarch/strncpy.c
new file mode 100644
index 0000000..aa98708
--- /dev/null
+++ b/sysdeps/i386/multiarch/strncpy.c
@@ -0,0 +1,52 @@
+/* Multiple versions of strncpy.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in libc.  */
+#if IS_IN (libc)
+# define _HAVE_STRING_ARCH_strncpy
+/* Redefine strncpy so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef strncpy
+# define strncpy __redirect_strncpy
+# include <string.h>
+# undef strncpy
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_strncpy) __strncpy_i386 attribute_hidden;
+extern __typeof (__redirect_strncpy) __strncpy_sse2 attribute_hidden;
+extern __typeof (__redirect_strncpy) __strncpy_ssse3 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_strncpy) strncpy;
+extern void *strncpy_ifunc (void) __asm__ ("strncpy");
+
+void *
+strncpy_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSSE3))
+    return __strncpy_ssse3;
+  else if (HAS_CPU_FEATURE (SSE2))
+    return __strncpy_sse2;
+
+  return __strncpy_i386;
+}
+__asm__ (".type strncpy, %gnu_indirect_function");
+#endif

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

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

    Add i386 s_fma family multiarch functions

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

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

commit e6a76afbe075a9b838580390ce90cf06af310e81
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=7408c1ec242bd20f99509a80d2bde335876e4a29

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

    Add i386 rawmemchr multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index 0b91d00..74333ca 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -7,7 +7,6 @@ sysdep_routines += strcmp-ssse3 \
 		   strncpy-sse2 stpcpy-sse2 stpncpy-sse2 strcat-ssse3 \
 		   strcat-sse2 strncat-ssse3 strncat-sse2 strncat-c \
 		   strchr-sse2 strrchr-sse2 strchr-sse2-bsf strrchr-sse2-bsf \
-		   rawmemchr-sse2 rawmemchr-sse2-bsf \
 		   strnlen-sse2 strnlen-c \
 		   strcasecmp_l-c strcasecmp-c strcasecmp_l-ssse3 \
 		   strncase_l-c strncase-c strncase_l-ssse3 \
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index fc9364f..8a9ecf3 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -20,5 +20,6 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   memset-sse2 memset-sse2-rep \
 		   memchr-sse2-bsf memchr-sse2 \
 		   memcmp-i386 memcmp-i686 memcmp-ssse3 memcmp-sse4 \
-		   memrchr-i386 memrchr-sse2-bsf memrchr-sse2
+		   memrchr-i386 memrchr-sse2-bsf memrchr-sse2 \
+		   rawmemchr-sse2-bsf rawmemchr-sse2
 endif
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 15c2009..ce5abeb 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -157,15 +157,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 #endif
 	      )
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/rawmemchr.S.  */
   IFUNC_IMPL (i, name, rawmemchr,
 	      IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_CPU_FEATURE (SSE2),
 			      __rawmemchr_sse2_bsf)
 	      IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_CPU_FEATURE (SSE2),
 			      __rawmemchr_sse2)
-	      IFUNC_IMPL_ADD (array, i, rawmemchr, 1, __rawmemchr_ia32))
+	      IFUNC_IMPL_ADD (array, i, rawmemchr, 1, __rawmemchr_i386))
 
+#if 0
   /* Support sysdeps/i386/i686/multiarch/stpncpy.S.  */
   IFUNC_IMPL (i, name, stpncpy,
 	      IFUNC_IMPL_ADD (array, i, stpncpy, HAS_CPU_FEATURE (SSSE3),
diff --git a/sysdeps/i386/i686/multiarch/rawmemchr-sse2-bsf.S b/sysdeps/i386/multiarch/rawmemchr-sse2-bsf.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/rawmemchr-sse2-bsf.S
rename to sysdeps/i386/multiarch/rawmemchr-sse2-bsf.S
diff --git a/sysdeps/i386/i686/multiarch/rawmemchr-sse2.S b/sysdeps/i386/multiarch/rawmemchr-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/rawmemchr-sse2.S
rename to sysdeps/i386/multiarch/rawmemchr-sse2.S
diff --git a/sysdeps/i386/i686/multiarch/rawmemchr.S b/sysdeps/i386/multiarch/rawmemchr.S
similarity index 84%
rename from sysdeps/i386/i686/multiarch/rawmemchr.S
rename to sysdeps/i386/multiarch/rawmemchr.S
index 2cfbe1b..27cc9f3 100644
--- a/sysdeps/i386/i686/multiarch/rawmemchr.S
+++ b/sysdeps/i386/multiarch/rawmemchr.S
@@ -34,7 +34,7 @@ ENTRY(__rawmemchr)
 	LOAD_FUNC_GOT_EAX (__rawmemchr_sse2)
 	ret
 
-2:	LOAD_FUNC_GOT_EAX (__rawmemchr_ia32)
+2:	LOAD_FUNC_GOT_EAX (__rawmemchr_i386)
 	ret
 
 3:	LOAD_FUNC_GOT_EAX (__rawmemchr_sse2_bsf)
@@ -45,21 +45,21 @@ weak_alias(__rawmemchr, rawmemchr)
 
 # undef ENTRY
 # define ENTRY(name) \
-	.type __rawmemchr_ia32, @function; \
-	.globl __rawmemchr_ia32; \
+	.type __rawmemchr_i386, @function; \
+	.globl __rawmemchr_i386; \
 	.p2align 4; \
-	__rawmemchr_ia32: cfi_startproc; \
+	__rawmemchr_i386: cfi_startproc; \
 	CALL_MCOUNT
 # undef END
 # define END(name) \
-	cfi_endproc; .size __rawmemchr_ia32, .-__rawmemchr_ia32
+	cfi_endproc; .size __rawmemchr_i386, .-__rawmemchr_i386
 
 # undef libc_hidden_def
 /* IFUNC doesn't work with the hidden functions in shared library since
    they will be called without setting up EBX needed for PLT which is
    used by IFUNC.  */
 # define libc_hidden_def(name) \
-	.globl __GI___rawmemchr; __GI___rawmemchr = __rawmemchr_ia32
+	.globl __GI___rawmemchr; __GI___rawmemchr = __rawmemchr_i386
 
 #endif
-#include "../../rawmemchr.S"
+#include <sysdeps/i386/rawmemchr.S>
diff --git a/sysdeps/i386/multiarch/rtld-rawmemchr.S b/sysdeps/i386/multiarch/rtld-rawmemchr.S
new file mode 100644
index 0000000..9d5c196
--- /dev/null
+++ b/sysdeps/i386/multiarch/rtld-rawmemchr.S
@@ -0,0 +1,20 @@
+/* rawmemchr for ld.so
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <init-arch.h>
+#include <sysdeps/i386/rawmemchr.S>

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

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

    Add i386 memrchr multiarch functions

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

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

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

    Add i386 memcmp multiarch functions

diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile
index c088a39..ec128d7 100644
--- a/sysdeps/i386/i686/multiarch/Makefile
+++ b/sysdeps/i386/i686/multiarch/Makefile
@@ -1,7 +1,7 @@
 ifeq ($(subdir),string)
 sysdep_routines += strcmp-ssse3 \
 		   strcmp-sse4 strncmp-c strncmp-ssse3 strncmp-sse4 \
-		   memcmp-ssse3 memcmp-sse4 varshift \
+		   varshift \
 		   strlen-sse2 strlen-sse2-bsf strncpy-c strcpy-ssse3 \
 		   strncpy-ssse3 stpcpy-ssse3 stpncpy-ssse3 strcpy-sse2 \
 		   strncpy-sse2 stpcpy-sse2 stpncpy-sse2 strcat-ssse3 \
diff --git a/sysdeps/i386/i686/multiarch/memcmp-i386.S b/sysdeps/i386/i686/multiarch/memcmp-i386.S
new file mode 100644
index 0000000..9d841c9
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memcmp-i386.S
@@ -0,0 +1 @@
+/* Dummy file.  */
diff --git a/sysdeps/i386/i686/multiarch/memcmp-i686.S b/sysdeps/i386/i686/multiarch/memcmp-i686.S
new file mode 100644
index 0000000..7aaf48b
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memcmp-i686.S
@@ -0,0 +1,7 @@
+#include <sysdeps/i386/multiarch/memcmp-i686.S>
+
+#ifdef SHARED
+	.globl __GI_memcmp
+	.hidden __GI_memcmp
+	__GI_memcmp = __memcmp_i686
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memcmp.S b/sysdeps/i386/i686/multiarch/memcmp.S
deleted file mode 100644
index d4d7d2e..0000000
--- a/sysdeps/i386/i686/multiarch/memcmp.S
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Multiple versions of memcmp
-   All versions must be listed in ifunc-impl-list.c.
-   Copyright (C) 2010-2015 Free Software Foundation, Inc.
-   Contributed by Intel Corporation.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in libc. */
-#if IS_IN (libc)
-	.text
-ENTRY(memcmp)
-	.type	memcmp, @gnu_indirect_function
-	LOAD_GOT_AND_RTLD_GLOBAL_RO
-	LOAD_FUNC_GOT_EAX (__memcmp_ia32)
-	HAS_CPU_FEATURE (SSSE3)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcmp_ssse3)
-	HAS_CPU_FEATURE (SSE4_2)
-	jz	2f
-	LOAD_FUNC_GOT_EAX (__memcmp_sse4_2)
-2:	ret
-END(memcmp)
-
-# undef ENTRY
-# define ENTRY(name) \
-	.type __memcmp_ia32, @function; \
-	.p2align 4; \
-	.globl __memcmp_ia32; \
-	.hidden __memcmp_ia32; \
-	__memcmp_ia32: cfi_startproc; \
-	CALL_MCOUNT
-# undef END
-# define END(name) \
-	cfi_endproc; .size __memcmp_ia32, .-__memcmp_ia32
-
-# ifdef SHARED
-#  undef libc_hidden_builtin_def
-/* IFUNC doesn't work with the hidden functions in shared library since
-   they will be called without setting up EBX needed for PLT which is
-   used by IFUNC.  */
-#  define libc_hidden_builtin_def(name) \
-	.globl __GI_memcmp; __GI_memcmp = __memcmp_ia32
-# endif
-#endif
-
-#include "../memcmp.S"
diff --git a/sysdeps/i386/i686/multiarch/memcmp.c b/sysdeps/i386/i686/multiarch/memcmp.c
new file mode 100644
index 0000000..63103a0
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/memcmp.c
@@ -0,0 +1 @@
+#include <sysdeps/i386/multiarch/memcmp.c>
diff --git a/sysdeps/i386/i686/multiarch/rtld-memcmp.S b/sysdeps/i386/i686/multiarch/rtld-memcmp.S
new file mode 100644
index 0000000..85ec290
--- /dev/null
+++ b/sysdeps/i386/i686/multiarch/rtld-memcmp.S
@@ -0,0 +1,19 @@
+/* memcmp for ld.so
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdeps/i386/i686/memcmp.S>
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index 937cea9..577bbb6 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -18,5 +18,6 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
 		   bzero-sse2 bzero-sse2-rep \
 		   memset-i386 memset-i586 memset-i686 \
 		   memset-sse2 memset-sse2-rep \
-		   memchr-sse2-bsf memchr-sse2
+		   memchr-sse2-bsf memchr-sse2 \
+		   memcmp-i386 memcmp-i686 memcmp-ssse3 memcmp-sse4
 endif
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 420efb2..e57134d 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -71,15 +71,17 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
 			      __memchr_sse2)
 	      IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_i386))
 
-#if 0
   /* Support sysdeps/i386/i686/multiarch/memcmp.S.  */
   IFUNC_IMPL (i, name, memcmp,
 	      IFUNC_IMPL_ADD (array, i, memcmp, HAS_CPU_FEATURE (SSE4_2),
 			      __memcmp_sse4_2)
 	      IFUNC_IMPL_ADD (array, i, memcmp, HAS_CPU_FEATURE (SSSE3),
 			      __memcmp_ssse3)
-	      IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_ia32))
+	      IFUNC_IMPL_ADD (array, i, memcmp, HAS_I686, __memcmp_i686)
+#if MINIMUM_ISA < 686
+	      IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_i386)
 #endif
+	      )
 
   /* Support sysdeps/i386/i686/multiarch/memmove_chk.S.  */
   IFUNC_IMPL (i, name, __memmove_chk,
diff --git a/sysdeps/i386/multiarch/memcmp-i386.S b/sysdeps/i386/multiarch/memcmp-i386.S
new file mode 100644
index 0000000..18e7424
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcmp-i386.S
@@ -0,0 +1,12 @@
+#define memcmp __memcmp_i386
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/memcmp.S>
+
+#ifdef SHARED
+	.globl __GI_memcmp
+	.hidden __GI_memcmp
+	__GI_memcmp = __memcmp_i386
+#endif
diff --git a/sysdeps/i386/multiarch/memcmp-i686.S b/sysdeps/i386/multiarch/memcmp-i686.S
new file mode 100644
index 0000000..32d1a4d
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcmp-i686.S
@@ -0,0 +1,6 @@
+#define memcmp __memcmp_i686
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/i686/memcmp.S>
diff --git a/sysdeps/i386/i686/multiarch/memcmp-sse4.S b/sysdeps/i386/multiarch/memcmp-sse4.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memcmp-sse4.S
rename to sysdeps/i386/multiarch/memcmp-sse4.S
diff --git a/sysdeps/i386/i686/multiarch/memcmp-ssse3.S b/sysdeps/i386/multiarch/memcmp-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memcmp-ssse3.S
rename to sysdeps/i386/multiarch/memcmp-ssse3.S
diff --git a/sysdeps/i386/multiarch/memcmp.c b/sysdeps/i386/multiarch/memcmp.c
new file mode 100644
index 0000000..36ca7da
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcmp.c
@@ -0,0 +1,57 @@
+/* Multiple versions of memcmp.
+   All versions must be listed in ifunc-impl-list.c.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/* Define multiple versions only for the definition in lib.  */
+#if IS_IN (libc)
+/* Redefine memcmp so that the compiler won't complain about the type
+   mismatch with the IFUNC selector in strong_alias, below.  */
+# undef memcmp
+# define memcmp __redirect_memcmp
+# include <string.h>
+# undef memcmp
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_memcmp) __memcmp_i386 attribute_hidden;
+extern __typeof (__redirect_memcmp) __memcmp_i686 attribute_hidden;
+extern __typeof (__redirect_memcmp) __memcmp_ssse3 attribute_hidden;
+extern __typeof (__redirect_memcmp) __memcmp_sse4_2 attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+   ifunc symbol properly.  */
+extern __typeof (__redirect_memcmp) memcmp;
+extern void *memcmp_ifunc (void) __asm__ ("memcmp");
+
+void *
+memcmp_ifunc (void)
+{
+  if (HAS_CPU_FEATURE (SSE4_2))
+    return __memcmp_sse4_2;
+  else if (HAS_CPU_FEATURE (SSSE3))
+    return __memcmp_ssse3;
+
+  if (USE_I686)
+    return __memcmp_i686;
+  else
+    return __memcmp_i386;
+}
+__asm__ (".type memcmp, %gnu_indirect_function");
+
+weak_alias (memcmp, bcmp)
+#endif
diff --git a/sysdeps/i386/multiarch/rtld-memcmp.S b/sysdeps/i386/multiarch/rtld-memcmp.S
new file mode 100644
index 0000000..d3a07fe
--- /dev/null
+++ b/sysdeps/i386/multiarch/rtld-memcmp.S
@@ -0,0 +1,19 @@
+/* memcmp for ld.so
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <sysdeps/i386/memcmp.S>

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

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

    Add i386 memchr multiarch functions

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

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

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

    Add i386 memcpy family multiarch functions

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

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

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

    Add i386 memset family multiarch functions

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

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


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]