This is the mail archive of the
glibc-cvs@sourceware.org
mailing list for the glibc project.
GNU C Library master sources branch hjl/i486/multiarch created. glibc-2.22-113-gaef129c
- From: hjl at sourceware dot org
- To: glibc-cvs at sourceware dot org
- Date: 20 Aug 2015 13:47:59 -0000
- Subject: GNU C Library master sources branch hjl/i486/multiarch created. glibc-2.22-113-gaef129c
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 aef129c05b25b529fed4deadfdc4006c4dd11f3d (commit)
- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=aef129c05b25b529fed4deadfdc4006c4dd11f3d
commit aef129c05b25b529fed4deadfdc4006c4dd11f3d
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Thu Aug 20 06:28:49 2015 -0700
Add i386 memcpy family multiarch functions
diff --git a/sysdeps/i386/i686/multiarch/memset_chk.S b/sysdeps/i386/i686/multiarch/memset_chk.S
deleted file mode 100644
index 7be45e7..0000000
--- a/sysdeps/i386/i686/multiarch/memset_chk.S
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Multiple versions of __memset_chk
- All versions must be listed in ifunc-impl-list.c.
- Copyright (C) 2010-2015 Free Software Foundation, Inc.
- Contributed by Intel Corporation.
- This file is part of the GNU C Library.
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#include <sysdep.h>
-#include <init-arch.h>
-
-/* Define multiple versions only for the definition in lib. */
-#if IS_IN (libc)
- .text
-ENTRY(__memset_chk)
- .type __memset_chk, @gnu_indirect_function
- LOAD_GOT_AND_RTLD_GLOBAL_RO
- LOAD_FUNC_GOT_EAX (__memset_chk_ia32)
- HAS_CPU_FEATURE (SSE2)
- jz 2f
- LOAD_FUNC_GOT_EAX (__memset_chk_sse2)
- HAS_CPU_FEATURE (Fast_Rep_String)
- jz 2f
- LOAD_FUNC_GOT_EAX (__memset_chk_sse2_rep)
-2: ret
-END(__memset_chk)
-
-# ifdef SHARED
-strong_alias (__memset_chk, __memset_zero_constant_len_parameter)
- .section .gnu.warning.__memset_zero_constant_len_parameter
- .string "memset used with constant zero length parameter; this could be due to transposed parameters"
-# else
- .text
- .type __memset_chk_sse2, @function
- .p2align 4;
-__memset_chk_sse2:
- cfi_startproc
- CALL_MCOUNT
- movl 12(%esp), %eax
- cmpl %eax, 16(%esp)
- jb __chk_fail
- jmp __memset_sse2
- cfi_endproc
- .size __memset_chk_sse2, .-__memset_chk_sse2
-
- .type __memset_chk_sse2_rep, @function
- .p2align 4;
-__memset_chk_sse2_rep:
- cfi_startproc
- CALL_MCOUNT
- movl 12(%esp), %eax
- cmpl %eax, 16(%esp)
- jb __chk_fail
- jmp __memset_sse2_rep
- cfi_endproc
- .size __memset_chk_sse2_rep, .-__memset_chk_sse2_rep
-
- .type __memset_chk_ia32, @function
- .p2align 4;
-__memset_chk_ia32:
- cfi_startproc
- CALL_MCOUNT
- movl 12(%esp), %eax
- cmpl %eax, 16(%esp)
- jb __chk_fail
- jmp __memset_ia32
- cfi_endproc
- .size __memset_chk_ia32, .-__memset_chk_ia32
-# endif
-#endif
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
index a1ae676..bd03635 100644
--- a/sysdeps/i386/multiarch/Makefile
+++ b/sysdeps/i386/multiarch/Makefile
@@ -5,6 +5,15 @@ endif
ifeq ($(subdir),string)
gen-as-const-headers += locale-defines.sym
-sysdep_routines += bzero-i386 bzero-i686 bzero-sse2 bzero-sse2-rep \
+sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \
+ bcopy-ssse3 bcopy-ssse3-rep \
+ memcpy-i386 memcpy-i686 memcpy-sse2-unaligned \
+ memcpy-ssse3 memcpy-ssse3-rep \
+ memmove-i386 memmove-i686 memmove-sse2-unaligned \
+ memmove-ssse3 memmove-ssse3-rep \
+ static-memmove \
+ mempcpy-i386 mempcpy-i686 mempcpy-sse2-unaligned \
+ mempcpy-ssse3 mempcpy-ssse3-rep \
+ bzero-i386 bzero-i686 bzero-sse2 bzero-sse2-rep \
memset-i386 memset-i686 memset-sse2 memset-sse2-rep
endif
diff --git a/sysdeps/i386/multiarch/bcopy-i386.S b/sysdeps/i386/multiarch/bcopy-i386.S
new file mode 100644
index 0000000..ad85776
--- /dev/null
+++ b/sysdeps/i386/multiarch/bcopy-i386.S
@@ -0,0 +1,15 @@
+#include <init-arch.h>
+#if !SUPPORT_I686
+# define bcopy __bcopy_i386
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# undef weak_alias
+# define weak_alias(name, aliasname)
+# include <sysdeps/i386/bcopy.S>
+
+# ifdef SHARED
+ .globl __GI_bcopy
+ .hidden __GI_bcopy
+ __GI_bcopy = __bcopy_i386
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/bcopy-i686.S b/sysdeps/i386/multiarch/bcopy-i686.S
new file mode 100644
index 0000000..9fc09a3
--- /dev/null
+++ b/sysdeps/i386/multiarch/bcopy-i686.S
@@ -0,0 +1,15 @@
+#include <init-arch.h>
+#define bcopy __bcopy_i686
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+# include <sysdeps/i386/i686/bcopy.S>
+
+#ifdef SHARED
+# if SUPPORT_I686
+ .globl __GI_bcopy
+ .hidden __GI_bcopy
+ __GI_bcopy = __bcopy_i686
+# endif
+#endif
diff --git a/sysdeps/i386/i686/multiarch/bcopy-sse2-unaligned.S b/sysdeps/i386/multiarch/bcopy-sse2-unaligned.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/bcopy-sse2-unaligned.S
rename to sysdeps/i386/multiarch/bcopy-sse2-unaligned.S
diff --git a/sysdeps/i386/i686/multiarch/bcopy-ssse3-rep.S b/sysdeps/i386/multiarch/bcopy-ssse3-rep.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/bcopy-ssse3-rep.S
rename to sysdeps/i386/multiarch/bcopy-ssse3-rep.S
diff --git a/sysdeps/i386/i686/multiarch/bcopy-ssse3.S b/sysdeps/i386/multiarch/bcopy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/bcopy-ssse3.S
rename to sysdeps/i386/multiarch/bcopy-ssse3.S
diff --git a/sysdeps/i386/multiarch/bcopy.c b/sysdeps/i386/multiarch/bcopy.c
new file mode 100644
index 0000000..21ecf62
--- /dev/null
+++ b/sysdeps/i386/multiarch/bcopy.c
@@ -0,0 +1,64 @@
+/* Multiple versions of bcopy.
+ All versions must be listed in ifunc-impl-list.c.
+ Copyright (C) 2015 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Define multiple versions only for the definition in lib. */
+#if IS_IN (libc)
+/* Redefine bcopy so that the compiler won't complain about the type
+ mismatch with the IFUNC selector in strong_alias, below. */
+# undef bcopy
+# define bcopy __redirect_bcopy
+# include <string.h>
+# undef bcopy
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_bcopy) __bcopy_i386 attribute_hidden;
+extern __typeof (__redirect_bcopy) __bcopy_i686 attribute_hidden;
+extern __typeof (__redirect_bcopy) __bcopy_sse2_unaligned attribute_hidden;
+extern __typeof (__redirect_bcopy) __bcopy_ssse3 attribute_hidden;
+extern __typeof (__redirect_bcopy) __bcopy_ssse3_rep attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+ ifunc symbol properly. */
+extern __typeof (__redirect_bcopy) bcopy;
+extern void *bcopy_ifunc (void) __asm__ ("bcopy");
+
+void *
+bcopy_ifunc (void)
+{
+ if (HAS_CPU_FEATURE (SSE2))
+ {
+ if (HAS_ARCH_FEATURE (Fast_Unaligned_Load))
+ return __bcopy_sse2_unaligned;
+ else if (HAS_CPU_FEATURE (SSSE3))
+ {
+ if (HAS_ARCH_FEATURE (Fast_Rep_String))
+ return __bcopy_ssse3_rep;
+ else
+ return __bcopy_ssse3;
+ }
+ }
+
+ if (HAS_I686)
+ return __bcopy_i686;
+ else
+ return __bcopy_i386;
+}
+__asm__ (".type bcopy, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
index 763ad7a..4127276 100644
--- a/sysdeps/i386/multiarch/ifunc-impl-list.c
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -36,7 +36,6 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
size_t i = 0;
-#if 0
/* Support sysdeps/i386/i686/multiarch/bcopy.S. */
IFUNC_IMPL (i, name, bcopy,
IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSSE3),
@@ -45,8 +44,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
__bcopy_ssse3)
IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSE2),
__bcopy_sse2_unaligned)
- IFUNC_IMPL_ADD (array, i, bcopy, 1, __bcopy_ia32))
+ IFUNC_IMPL_ADD (array, i, bcopy, HAS_I686, __bcopy_i686)
+#if !SUPPORT_I686
+ IFUNC_IMPL_ADD (array, i, bcopy, 1, __bcopy_i386)
#endif
+ )
/* Support sysdeps/i386/i686/multiarch/bzero.S. */
IFUNC_IMPL (i, name, bzero,
@@ -76,6 +78,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,
@@ -88,8 +91,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL_ADD (array, i, __memmove_chk,
HAS_CPU_FEATURE (SSE2),
__memmove_chk_sse2_unaligned)
+ IFUNC_IMPL_ADD (array, i, __memmove_chk, HAS_I686,
+ __memmove_chk_i686)
+#if !SUPPORT_I686
IFUNC_IMPL_ADD (array, i, __memmove_chk, 1,
- __memmove_chk_ia32))
+ __memmove_chk_i386)
+#endif
+ )
/* Support sysdeps/i386/i686/multiarch/memmove.S. */
IFUNC_IMPL (i, name, memmove,
@@ -99,8 +107,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
__memmove_ssse3)
IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSE2),
__memmove_sse2_unaligned)
- IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ia32))
+ IFUNC_IMPL_ADD (array, i, memmove, HAS_I686, __memmove_i686)
+#if !SUPPORT_I686
+ IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_i386)
+#endif
+ )
+#if 0
/* Support sysdeps/i386/i686/multiarch/memrchr.S. */
IFUNC_IMPL (i, name, memrchr,
IFUNC_IMPL_ADD (array, i, memrchr, HAS_CPU_FEATURE (SSE2),
@@ -324,6 +337,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. */
@@ -337,8 +351,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL_ADD (array, i, __memcpy_chk,
HAS_CPU_FEATURE (SSE2),
__memcpy_chk_sse2_unaligned)
+ IFUNC_IMPL_ADD (array, i, __memcpy_chk, HAS_I686,
+ __memcpy_chk_i686)
+#if !SUPPORT_I686
IFUNC_IMPL_ADD (array, i, __memcpy_chk, 1,
- __memcpy_chk_ia32))
+ __memcpy_chk_i386)
+#endif
+ )
/* Support sysdeps/i386/i686/multiarch/memcpy.S. */
IFUNC_IMPL (i, name, memcpy,
@@ -348,7 +367,11 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
__memcpy_ssse3)
IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSE2),
__memcpy_sse2_unaligned)
- IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ia32))
+ IFUNC_IMPL_ADD (array, i, memcpy, HAS_I686, __memcpy_i686)
+#if !SUPPORT_I686
+ IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_i386)
+#endif
+ )
/* Support sysdeps/i386/i686/multiarch/mempcpy_chk.S. */
IFUNC_IMPL (i, name, __mempcpy_chk,
@@ -361,8 +384,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
IFUNC_IMPL_ADD (array, i, __mempcpy_chk,
HAS_CPU_FEATURE (SSE2),
__mempcpy_chk_sse2_unaligned)
+ IFUNC_IMPL_ADD (array, i, __mempcpy_chk, HAS_I686,
+ __mempcpy_chk_i686)
+#if !SUPPORT_I686
IFUNC_IMPL_ADD (array, i, __mempcpy_chk, 1,
- __mempcpy_chk_ia32))
+ __mempcpy_chk_i386)
+#endif
+ )
/* Support sysdeps/i386/i686/multiarch/mempcpy.S. */
IFUNC_IMPL (i, name, mempcpy,
@@ -372,8 +400,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
__mempcpy_ssse3)
IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSE2),
__mempcpy_sse2_unaligned)
- IFUNC_IMPL_ADD (array, i, mempcpy, 1, __mempcpy_ia32))
+ IFUNC_IMPL_ADD (array, i, mempcpy, HAS_I686, __mempcpy_i686)
+#if !SUPPORT_I686
+ IFUNC_IMPL_ADD (array, i, mempcpy, 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..b4a778c
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcpy-i386.S
@@ -0,0 +1,14 @@
+#ifdef SHARED
+# include <init-arch.h>
+# if !SUPPORT_I686
+# define memcpy __memcpy_i386
+# define __memcpy_chk __memcpy_chk_i386
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# include <sysdeps/i386/memcpy.S>
+
+ .globl __GI_memcpy
+ .hidden __GI_memcpy
+ __GI_memcpy = __memcpy_i386
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/memcpy-i686.S b/sysdeps/i386/multiarch/memcpy-i686.S
new file mode 100644
index 0000000..c0bf4a4
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcpy-i686.S
@@ -0,0 +1,14 @@
+#ifdef SHARED
+# include <init-arch.h>
+# define memcpy __memcpy_i686
+# define __memcpy_chk __memcpy_chk_i686
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# include <sysdeps/i386/i686/memcpy.S>
+
+# if SUPPORT_I686
+ .globl __GI_memcpy
+ .hidden __GI_memcpy
+ __GI_memcpy = __memcpy_i686
+# endif
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S b/sysdeps/i386/multiarch/memcpy-sse2-unaligned.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memcpy-sse2-unaligned.S
rename to sysdeps/i386/multiarch/memcpy-sse2-unaligned.S
diff --git a/sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S b/sysdeps/i386/multiarch/memcpy-ssse3-rep.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memcpy-ssse3-rep.S
rename to sysdeps/i386/multiarch/memcpy-ssse3-rep.S
diff --git a/sysdeps/i386/i686/multiarch/memcpy-ssse3.S b/sysdeps/i386/multiarch/memcpy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memcpy-ssse3.S
rename to sysdeps/i386/multiarch/memcpy-ssse3.S
diff --git a/sysdeps/i386/multiarch/memcpy.c b/sysdeps/i386/multiarch/memcpy.c
new file mode 100644
index 0000000..b43d5cf
--- /dev/null
+++ b/sysdeps/i386/multiarch/memcpy.c
@@ -0,0 +1,66 @@
+/* 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_i686 attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_sse2_unaligned attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_ssse3 attribute_hidden;
+extern __typeof (__redirect_memcpy) __memcpy_ssse3_rep attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+ ifunc symbol properly. */
+extern __typeof (__redirect_memcpy) memcpy;
+extern void *memcpy_ifunc (void) __asm__ ("memcpy");
+
+void *
+memcpy_ifunc (void)
+{
+ if (HAS_CPU_FEATURE (SSE2))
+ {
+ if (HAS_ARCH_FEATURE (Fast_Unaligned_Load))
+ return __memcpy_sse2_unaligned;
+ else if (HAS_CPU_FEATURE (SSSE3))
+ {
+ if (HAS_ARCH_FEATURE (Fast_Rep_String))
+ return __memcpy_ssse3_rep;
+ else
+ return __memcpy_ssse3;
+ }
+ }
+
+ if (HAS_I686)
+ return __memcpy_i686;
+ else
+ return __memcpy_i386;
+}
+__asm__ (".type memcpy, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memcpy_chk.S b/sysdeps/i386/multiarch/memcpy_chk.S
similarity index 89%
rename from sysdeps/i386/i686/multiarch/memcpy_chk.S
rename to sysdeps/i386/multiarch/memcpy_chk.S
index 3bbd921..b019020 100644
--- a/sysdeps/i386/i686/multiarch/memcpy_chk.S
+++ b/sysdeps/i386/multiarch/memcpy_chk.S
@@ -18,19 +18,24 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <sysdep.h>
-#include <init-arch.h>
-
/* Define multiple versions only for the definition in lib and for
DSO. There are no multiarch memcpy functions for static binaries.
*/
#if IS_IN (libc)
+# include <sysdep.h>
+# include <init-arch.h>
+
# ifdef SHARED
.text
ENTRY(__memcpy_chk)
.type __memcpy_chk, @gnu_indirect_function
LOAD_GOT_AND_RTLD_GLOBAL_RO
- LOAD_FUNC_GOT_EAX (__memcpy_chk_ia32)
+# if !SUPPORT_I686
+ LOAD_FUNC_GOT_EAX (__memcpy_chk_i386)
+ HAS_ARCH_FEATURE (I686)
+ jz 2f
+# endif
+ LOAD_FUNC_GOT_EAX (__memcpy_chk_i686)
HAS_CPU_FEATURE (SSE2)
jz 2f
LOAD_FUNC_GOT_EAX (__memcpy_chk_sse2_unaligned)
diff --git a/sysdeps/i386/multiarch/memmove-i386.S b/sysdeps/i386/multiarch/memmove-i386.S
new file mode 100644
index 0000000..d19cb1f
--- /dev/null
+++ b/sysdeps/i386/multiarch/memmove-i386.S
@@ -0,0 +1,14 @@
+#ifdef SHARED
+# include <init-arch.h>
+# if !SUPPORT_I686
+# define memmove __memmove_i386
+# define __memmove_chk __memmove_chk_i386
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# include <sysdeps/i386/memmove.S>
+
+ .globl __GI_memmove
+ .hidden __GI_memmove
+ __GI_memmove = __memmove_i386
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/memmove-i686.S b/sysdeps/i386/multiarch/memmove-i686.S
new file mode 100644
index 0000000..1ed5c6b
--- /dev/null
+++ b/sysdeps/i386/multiarch/memmove-i686.S
@@ -0,0 +1,14 @@
+#ifdef SHARED
+# include <init-arch.h>
+# define memmove __memmove_i686
+# define __memmove_chk __memmove_chk_i686
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# include <sysdeps/i386/i686/memmove.S>
+
+# if SUPPORT_I686
+ .globl __GI_memmove
+ .hidden __GI_memmvoe
+ __GI_memmove = __memmove i686
+# endif
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memmove-sse2-unaligned.S b/sysdeps/i386/multiarch/memmove-sse2-unaligned.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memmove-sse2-unaligned.S
rename to sysdeps/i386/multiarch/memmove-sse2-unaligned.S
diff --git a/sysdeps/i386/i686/multiarch/memmove-ssse3-rep.S b/sysdeps/i386/multiarch/memmove-ssse3-rep.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memmove-ssse3-rep.S
rename to sysdeps/i386/multiarch/memmove-ssse3-rep.S
diff --git a/sysdeps/i386/i686/multiarch/memmove-ssse3.S b/sysdeps/i386/multiarch/memmove-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memmove-ssse3.S
rename to sysdeps/i386/multiarch/memmove-ssse3.S
diff --git a/sysdeps/i386/multiarch/memmove.c b/sysdeps/i386/multiarch/memmove.c
new file mode 100644
index 0000000..6082844
--- /dev/null
+++ b/sysdeps/i386/multiarch/memmove.c
@@ -0,0 +1,66 @@
+/* Multiple versions of memmove.
+ All versions must be listed in ifunc-impl-list.c.
+ Copyright (C) 2015 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Define multiple versions only for the definition in lib and for
+ DSO. In static binaries we need memmove before the initialization
+ happened. */
+#if defined SHARED && IS_IN (libc)
+/* Redefine memmove so that the compiler won't complain about the type
+ mismatch with the IFUNC selector in strong_alias, below. */
+# undef memmove
+# define memmove __redirect_memmove
+# include <string.h>
+# undef memmove
+
+# include <init-arch.h>
+
+extern __typeof (__redirect_memmove) __memmove_i386 attribute_hidden;
+extern __typeof (__redirect_memmove) __memmove_i686 attribute_hidden;
+extern __typeof (__redirect_memmove) __memmove_sse2_unaligned attribute_hidden;
+extern __typeof (__redirect_memmove) __memmove_ssse3 attribute_hidden;
+extern __typeof (__redirect_memmove) __memmove_ssse3_rep attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+ ifunc symbol properly. */
+extern __typeof (__redirect_memmove) memmove;
+extern void *memmove_ifunc (void) __asm__ ("memmove");
+
+void *
+memmove_ifunc (void)
+{
+ if (HAS_CPU_FEATURE (SSE2))
+ {
+ if (HAS_ARCH_FEATURE (Fast_Unaligned_Load))
+ return __memmove_sse2_unaligned;
+ else if (HAS_CPU_FEATURE (SSSE3))
+ {
+ if (HAS_ARCH_FEATURE (Fast_Rep_String))
+ return __memmove_ssse3_rep;
+ else
+ return __memmove_ssse3;
+ }
+ }
+
+ if (HAS_I686)
+ return __memmove_i686;
+ else
+ return __memmove_i386;
+}
+__asm__ (".type memmove, %gnu_indirect_function");
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memmove_chk.S b/sysdeps/i386/multiarch/memmove_chk.S
similarity index 80%
rename from sysdeps/i386/i686/multiarch/memmove_chk.S
rename to sysdeps/i386/multiarch/memmove_chk.S
index b17f6ed..15e47d5 100644
--- a/sysdeps/i386/i686/multiarch/memmove_chk.S
+++ b/sysdeps/i386/multiarch/memmove_chk.S
@@ -18,16 +18,21 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <sysdep.h>
-#include <init-arch.h>
-
/* Define multiple versions only for the definition in lib. */
#if IS_IN (libc)
+# include <sysdep.h>
+# include <init-arch.h>
+
.text
ENTRY(__memmove_chk)
.type __memmove_chk, @gnu_indirect_function
LOAD_GOT_AND_RTLD_GLOBAL_RO
- LOAD_FUNC_GOT_EAX (__memmove_chk_ia32)
+# if !SUPPORT_I686
+ LOAD_FUNC_GOT_EAX (__memmove_chk_i386)
+ HAS_ARCH_FEATURE (I686)
+ jz 2f
+# endif
+ LOAD_FUNC_GOT_EAX (__memmove_chk_i686)
HAS_CPU_FEATURE (SSE2)
jz 2f
LOAD_FUNC_GOT_EAX (__memmove_chk_sse2_unaligned)
@@ -79,16 +84,30 @@ __memmove_chk_ssse3_rep:
cfi_endproc
.size __memmove_chk_ssse3_rep, .-__memmove_chk_ssse3_rep
- .type __memmove_chk_ia32, @function
+ .type __memmove_chk_i686, @function
+ .p2align 4;
+__memmove_chk_i686:
+ cfi_startproc
+ CALL_MCOUNT
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp __memmove_i686
+ cfi_endproc
+ .size __memmove_chk_i686, .-__memmove_chk_i686
+
+# if !SUPPORT_I686
+ .type __memmove_chk_i386, @function
.p2align 4;
-__memmove_chk_ia32:
+__memmove_chk_i386:
cfi_startproc
CALL_MCOUNT
movl 12(%esp), %eax
cmpl %eax, 16(%esp)
jb __chk_fail
- jmp __memmove_ia32
+ jmp __memmove_i386
cfi_endproc
- .size __memmove_chk_ia32, .-__memmove_chk_ia32
+ .size __memmove_chk_i386, .-__memmove_chk_i386
+# endif
# endif
#endif
diff --git a/sysdeps/i386/multiarch/mempcpy-i386.S b/sysdeps/i386/multiarch/mempcpy-i386.S
new file mode 100644
index 0000000..5719def
--- /dev/null
+++ b/sysdeps/i386/multiarch/mempcpy-i386.S
@@ -0,0 +1,21 @@
+#ifdef SHARED
+# include <init-arch.h>
+# if !SUPPORT_I686
+# define __mempcpy __mempcpy_i386
+# define __mempcpy_chk __mempcpy_chk_i386
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# undef libc_hidden_def
+# define libc_hidden_def(name)
+# undef weak_alias
+# define weak_alias(name, aliasname)
+# include <sysdeps/i386/mempcpy.S>
+
+ .globl __GI_mempcpy
+ .hidden __GI_mempcpy
+ __GI_mempcpy = __mempcpy_i386
+ .globl __GI___mempcpy
+ .hidden __GI___mempcpy
+ __GI___mempcpy = __mempcpy_i386
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/mempcpy-i686.S b/sysdeps/i386/multiarch/mempcpy-i686.S
new file mode 100644
index 0000000..f27c7a9
--- /dev/null
+++ b/sysdeps/i386/multiarch/mempcpy-i686.S
@@ -0,0 +1,21 @@
+#ifdef SHARED
+# include <init-arch.h>
+# define __mempcpy __mempcpy_i686
+# define __mempcpy_chk __mempcpy_chk_i686
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# undef libc_hidden_def
+# define libc_hidden_def(name)
+# undef weak_alias
+# define weak_alias(name, aliasname)
+# include <sysdeps/i386/i686/mempcpy.S>
+
+# if SUPPORT_I686
+ .globl __GI_mempcpy
+ .hidden __GI_mempcpy
+ __GI_mempcpy = __mempcpy_i686
+ .globl __GI___mempcpy
+ .hidden __GI___mempcpy
+ __GI___mempcpy = __mempcpy_i686
+# endif
+#endif
diff --git a/sysdeps/i386/i686/multiarch/mempcpy-sse2-unaligned.S b/sysdeps/i386/multiarch/mempcpy-sse2-unaligned.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/mempcpy-sse2-unaligned.S
rename to sysdeps/i386/multiarch/mempcpy-sse2-unaligned.S
diff --git a/sysdeps/i386/i686/multiarch/mempcpy-ssse3-rep.S b/sysdeps/i386/multiarch/mempcpy-ssse3-rep.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/mempcpy-ssse3-rep.S
rename to sysdeps/i386/multiarch/mempcpy-ssse3-rep.S
diff --git a/sysdeps/i386/i686/multiarch/mempcpy-ssse3.S b/sysdeps/i386/multiarch/mempcpy-ssse3.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/mempcpy-ssse3.S
rename to sysdeps/i386/multiarch/mempcpy-ssse3.S
diff --git a/sysdeps/i386/multiarch/mempcpy.c b/sysdeps/i386/multiarch/mempcpy.c
new file mode 100644
index 0000000..ecf95a4
--- /dev/null
+++ b/sysdeps/i386/multiarch/mempcpy.c
@@ -0,0 +1,68 @@
+/* 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_i686 attribute_hidden;
+extern __typeof (__redirect_mempcpy) __mempcpy_sse2_unaligned attribute_hidden;
+extern __typeof (__redirect_mempcpy) __mempcpy_ssse3 attribute_hidden;
+extern __typeof (__redirect_mempcpy) __mempcpy_ssse3_rep attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+ ifunc symbol properly. */
+extern __typeof (__redirect_mempcpy) __mempcpy;
+extern void *mempcpy_ifunc (void) __asm__ ("__mempcpy");
+
+void *
+mempcpy_ifunc (void)
+{
+ if (HAS_CPU_FEATURE (SSE2))
+ {
+ if (HAS_ARCH_FEATURE (Fast_Unaligned_Load))
+ return __mempcpy_sse2_unaligned;
+ else if (HAS_CPU_FEATURE (SSSE3))
+ {
+ if (HAS_ARCH_FEATURE (Fast_Rep_String))
+ return __mempcpy_ssse3_rep;
+ else
+ return __mempcpy_ssse3;
+ }
+ }
+
+ if (HAS_I686)
+ return __mempcpy_i686;
+ else
+ return __mempcpy_i386;
+}
+__asm__ (".type __mempcpy, %gnu_indirect_function");
+weak_alias (__mempcpy, mempcpy)
+#endif
diff --git a/sysdeps/i386/i686/multiarch/mempcpy_chk.S b/sysdeps/i386/multiarch/mempcpy_chk.S
similarity index 89%
rename from sysdeps/i386/i686/multiarch/mempcpy_chk.S
rename to sysdeps/i386/multiarch/mempcpy_chk.S
index 1bea6ea..d201058 100644
--- a/sysdeps/i386/i686/multiarch/mempcpy_chk.S
+++ b/sysdeps/i386/multiarch/mempcpy_chk.S
@@ -18,19 +18,24 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <sysdep.h>
-#include <init-arch.h>
-
/* Define multiple versions only for the definition in lib and for
DSO. There are no multiarch mempcpy functions for static binaries.
*/
#if IS_IN (libc)
+# include <sysdep.h>
+# include <init-arch.h>
+
# ifdef SHARED
.text
ENTRY(__mempcpy_chk)
.type __mempcpy_chk, @gnu_indirect_function
LOAD_GOT_AND_RTLD_GLOBAL_RO
- LOAD_FUNC_GOT_EAX (__mempcpy_chk_ia32)
+# if !SUPPORT_I686
+ LOAD_FUNC_GOT_EAX (__mempcpy_chk_i386)
+ HAS_ARCH_FEATURE (I686)
+ jz 2f
+# endif
+ LOAD_FUNC_GOT_EAX (__mempcpy_chk_i686)
HAS_CPU_FEATURE (SSE2)
jz 2f
LOAD_FUNC_GOT_EAX (__mempcpy_chk_sse2_unaligned)
diff --git a/sysdeps/i386/multiarch/rtld-memmove.S b/sysdeps/i386/multiarch/rtld-memmove.S
new file mode 100644
index 0000000..b40bb60
--- /dev/null
+++ b/sysdeps/i386/multiarch/rtld-memmove.S
@@ -0,0 +1,24 @@
+/* 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 <init-arch.h>
+#if SUPPORT_I686
+# include <sysdeps/i386/i686/memmove.S>
+#else
+# include <sysdeps/i386/memmove.S>
+#endif
diff --git a/sysdeps/i386/multiarch/static-memmove.S b/sysdeps/i386/multiarch/static-memmove.S
new file mode 100644
index 0000000..ca99523
--- /dev/null
+++ b/sysdeps/i386/multiarch/static-memmove.S
@@ -0,0 +1,26 @@
+/* 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 <init-arch.h>
+# if SUPPORT_I686
+# include <sysdeps/i386/i686/memmove.S>
+# else
+# include <sysdeps/i386/memmove.S>
+# endif
+#endif
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=e6745e3d8560e345e71d921c71271d5c7eb40722
commit e6745e3d8560e345e71d921c71271d5c7eb40722
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Wed Aug 19 14:10:40 2015 -0700
Add i386 memset family multiarch functions
diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile
new file mode 100644
index 0000000..a1ae676
--- /dev/null
+++ b/sysdeps/i386/multiarch/Makefile
@@ -0,0 +1,10 @@
+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-i686 bzero-sse2 bzero-sse2-rep \
+ memset-i386 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..d6150d0
--- /dev/null
+++ b/sysdeps/i386/multiarch/bzero-i386.S
@@ -0,0 +1,15 @@
+#include <init-arch.h>
+#if !SUPPORT_I686
+# define __bzero __bzero_i386
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# undef weak_alias
+# define weak_alias(name, aliasname)
+# include <sysdeps/i386/bzero.S>
+
+# ifdef SHARED
+ .globl __GI_bzero
+ .hidden __GI_bzero
+ __GI_bzero = __bzero_i386
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/bzero-i686.S b/sysdeps/i386/multiarch/bzero-i686.S
new file mode 100644
index 0000000..0711988
--- /dev/null
+++ b/sysdeps/i386/multiarch/bzero-i686.S
@@ -0,0 +1,15 @@
+#include <init-arch.h>
+#define __bzero __bzero_i686
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#undef weak_alias
+#define weak_alias(name, aliasname)
+#include <sysdeps/i386/i686/bzero.S>
+
+#ifdef SHARED
+# if SUPPORT_I686
+ .globl __GI_bzero
+ .hidden __GI_bzero
+ __GI_bzero = __bzero_i686
+# endif
+#endif
diff --git a/sysdeps/i386/i686/multiarch/bzero-sse2-rep.S b/sysdeps/i386/multiarch/bzero-sse2-rep.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/bzero-sse2-rep.S
rename to sysdeps/i386/multiarch/bzero-sse2-rep.S
diff --git a/sysdeps/i386/i686/multiarch/bzero-sse2.S b/sysdeps/i386/multiarch/bzero-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/bzero-sse2.S
rename to sysdeps/i386/multiarch/bzero-sse2.S
diff --git a/sysdeps/i386/multiarch/bzero.c b/sysdeps/i386/multiarch/bzero.c
new file mode 100644
index 0000000..c292d3e
--- /dev/null
+++ b/sysdeps/i386/multiarch/bzero.c
@@ -0,0 +1,60 @@
+/* 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_i686 attribute_hidden;
+extern __typeof (__redirect_bzero) __bzero_sse2 attribute_hidden;
+extern __typeof (__redirect_bzero) __bzero_sse2_rep attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+ ifunc symbol properly. */
+extern __typeof (__redirect_bzero) __bzero;
+extern void *bzero_ifunc (void) __asm__ ("__bzero");
+
+void *
+bzero_ifunc (void)
+{
+ if (HAS_CPU_FEATURE (SSE2))
+ {
+ if (HAS_ARCH_FEATURE (Fast_Rep_String))
+ return __bzero_sse2_rep;
+ else
+ return __bzero_sse2;
+ }
+
+ if (HAS_I686)
+ return __bzero_i686;
+ else
+ return __bzero_i386;
+}
+__asm__ (".type __bzero, %gnu_indirect_function");
+
+weak_alias (__bzero, bzero)
+#endif
diff --git a/sysdeps/i386/i686/multiarch/ifunc-defines.sym b/sysdeps/i386/multiarch/ifunc-defines.sym
similarity index 100%
rename from sysdeps/i386/i686/multiarch/ifunc-defines.sym
rename to sysdeps/i386/multiarch/ifunc-defines.sym
diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c
new file mode 100644
index 0000000..763ad7a
--- /dev/null
+++ b/sysdeps/i386/multiarch/ifunc-impl-list.c
@@ -0,0 +1,396 @@
+/* Enumerate available IFUNC implementations of a function. i386 version.
+ Copyright (C) 2015 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <string.h>
+#include <wchar.h>
+#include <ifunc-impl-list.h>
+#include "init-arch.h"
+
+/* Maximum number of IFUNC implementations. */
+#define MAX_IFUNC 4
+
+/* Fill ARRAY of MAX elements with IFUNC implementations for function
+ NAME and return the number of valid entries. */
+
+size_t
+__libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array,
+ size_t max)
+{
+ assert (max >= MAX_IFUNC);
+
+ size_t i = 0;
+
+#if 0
+ /* Support sysdeps/i386/i686/multiarch/bcopy.S. */
+ IFUNC_IMPL (i, name, bcopy,
+ IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSSE3),
+ __bcopy_ssse3_rep)
+ IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSSE3),
+ __bcopy_ssse3)
+ IFUNC_IMPL_ADD (array, i, bcopy, HAS_CPU_FEATURE (SSE2),
+ __bcopy_sse2_unaligned)
+ IFUNC_IMPL_ADD (array, i, bcopy, 1, __bcopy_ia32))
+#endif
+
+ /* Support sysdeps/i386/i686/multiarch/bzero.S. */
+ IFUNC_IMPL (i, name, bzero,
+ IFUNC_IMPL_ADD (array, i, bzero, HAS_CPU_FEATURE (SSE2),
+ __bzero_sse2_rep)
+ IFUNC_IMPL_ADD (array, i, bzero, HAS_CPU_FEATURE (SSE2),
+ __bzero_sse2)
+ IFUNC_IMPL_ADD (array, i, bzero, HAS_I686, __bzero_i686)
+#if !SUPPORT_I686
+ IFUNC_IMPL_ADD (array, i, bzero, 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),
+ __memchr_sse2_bsf)
+ IFUNC_IMPL_ADD (array, i, memchr, HAS_CPU_FEATURE (SSE2),
+ __memchr_sse2)
+ IFUNC_IMPL_ADD (array, i, memchr, 1, __memchr_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/memcmp.S. */
+ IFUNC_IMPL (i, name, memcmp,
+ IFUNC_IMPL_ADD (array, i, memcmp, HAS_CPU_FEATURE (SSE4_2),
+ __memcmp_sse4_2)
+ IFUNC_IMPL_ADD (array, i, memcmp, HAS_CPU_FEATURE (SSSE3),
+ __memcmp_ssse3)
+ IFUNC_IMPL_ADD (array, i, memcmp, 1, __memcmp_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/memmove_chk.S. */
+ IFUNC_IMPL (i, name, __memmove_chk,
+ IFUNC_IMPL_ADD (array, i, __memmove_chk,
+ HAS_CPU_FEATURE (SSSE3),
+ __memmove_chk_ssse3_rep)
+ IFUNC_IMPL_ADD (array, i, __memmove_chk,
+ HAS_CPU_FEATURE (SSSE3),
+ __memmove_chk_ssse3)
+ IFUNC_IMPL_ADD (array, i, __memmove_chk,
+ HAS_CPU_FEATURE (SSE2),
+ __memmove_chk_sse2_unaligned)
+ IFUNC_IMPL_ADD (array, i, __memmove_chk, 1,
+ __memmove_chk_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/memmove.S. */
+ IFUNC_IMPL (i, name, memmove,
+ IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSSE3),
+ __memmove_ssse3_rep)
+ IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSSE3),
+ __memmove_ssse3)
+ IFUNC_IMPL_ADD (array, i, memmove, HAS_CPU_FEATURE (SSE2),
+ __memmove_sse2_unaligned)
+ IFUNC_IMPL_ADD (array, i, memmove, 1, __memmove_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/memrchr.S. */
+ IFUNC_IMPL (i, name, memrchr,
+ IFUNC_IMPL_ADD (array, i, memrchr, HAS_CPU_FEATURE (SSE2),
+ __memrchr_sse2_bsf)
+ IFUNC_IMPL_ADD (array, i, memrchr, HAS_CPU_FEATURE (SSE2),
+ __memrchr_sse2)
+ IFUNC_IMPL_ADD (array, i, memrchr, 1, __memrchr_ia32))
+#endif
+
+ /* Support sysdeps/i386/i686/multiarch/memset_chk.S. */
+ IFUNC_IMPL (i, name, __memset_chk,
+ IFUNC_IMPL_ADD (array, i, __memset_chk,
+ HAS_CPU_FEATURE (SSE2),
+ __memset_chk_sse2_rep)
+ IFUNC_IMPL_ADD (array, i, __memset_chk,
+ HAS_CPU_FEATURE (SSE2),
+ __memset_chk_sse2)
+ IFUNC_IMPL_ADD (array, i, __memset_chk,
+ HAS_I686, __memset_chk_i686)
+#if !SUPPORT_I686
+ IFUNC_IMPL_ADD (array, i, __memset_chk, 1,
+ __memset_chk_i386)
+#endif
+ )
+
+ /* Support sysdeps/i386/i686/multiarch/memset.S. */
+ IFUNC_IMPL (i, name, memset,
+ IFUNC_IMPL_ADD (array, i, memset, HAS_CPU_FEATURE (SSE2),
+ __memset_sse2_rep)
+ IFUNC_IMPL_ADD (array, i, memset, HAS_CPU_FEATURE (SSE2),
+ __memset_sse2)
+ IFUNC_IMPL_ADD (array, i, memset, HAS_I686,
+ __memset_i686)
+#if !SUPPORT_I686
+ IFUNC_IMPL_ADD (array, i, memset, 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),
+ __rawmemchr_sse2_bsf)
+ IFUNC_IMPL_ADD (array, i, rawmemchr, HAS_CPU_FEATURE (SSE2),
+ __rawmemchr_sse2)
+ IFUNC_IMPL_ADD (array, i, rawmemchr, 1, __rawmemchr_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/stpncpy.S. */
+ IFUNC_IMPL (i, name, stpncpy,
+ IFUNC_IMPL_ADD (array, i, stpncpy, HAS_CPU_FEATURE (SSSE3),
+ __stpncpy_ssse3)
+ IFUNC_IMPL_ADD (array, i, stpncpy, HAS_CPU_FEATURE (SSE2),
+ __stpncpy_sse2)
+ IFUNC_IMPL_ADD (array, i, stpncpy, 1, __stpncpy_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/stpcpy.S. */
+ IFUNC_IMPL (i, name, stpcpy,
+ IFUNC_IMPL_ADD (array, i, stpcpy, HAS_CPU_FEATURE (SSSE3),
+ __stpcpy_ssse3)
+ IFUNC_IMPL_ADD (array, i, stpcpy, HAS_CPU_FEATURE (SSE2),
+ __stpcpy_sse2)
+ IFUNC_IMPL_ADD (array, i, stpcpy, 1, __stpcpy_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strcasecmp.S. */
+ IFUNC_IMPL (i, name, strcasecmp,
+ IFUNC_IMPL_ADD (array, i, strcasecmp,
+ HAS_CPU_FEATURE (SSE4_2),
+ __strcasecmp_sse4_2)
+ IFUNC_IMPL_ADD (array, i, strcasecmp,
+ HAS_CPU_FEATURE (SSSE3),
+ __strcasecmp_ssse3)
+ IFUNC_IMPL_ADD (array, i, strcasecmp, 1, __strcasecmp_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strcasecmp_l.S. */
+ IFUNC_IMPL (i, name, strcasecmp_l,
+ IFUNC_IMPL_ADD (array, i, strcasecmp_l,
+ HAS_CPU_FEATURE (SSE4_2),
+ __strcasecmp_l_sse4_2)
+ IFUNC_IMPL_ADD (array, i, strcasecmp_l,
+ HAS_CPU_FEATURE (SSSE3),
+ __strcasecmp_l_ssse3)
+ IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1,
+ __strcasecmp_l_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strcat.S. */
+ IFUNC_IMPL (i, name, strcat,
+ IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSSE3),
+ __strcat_ssse3)
+ IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSE2),
+ __strcat_sse2)
+ IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strchr.S. */
+ IFUNC_IMPL (i, name, strchr,
+ IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2),
+ __strchr_sse2_bsf)
+ IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2),
+ __strchr_sse2)
+ IFUNC_IMPL_ADD (array, i, strchr, 1, __strchr_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strcmp.S. */
+ IFUNC_IMPL (i, name, strcmp,
+ IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSE4_2),
+ __strcmp_sse4_2)
+ IFUNC_IMPL_ADD (array, i, strcmp, HAS_CPU_FEATURE (SSSE3),
+ __strcmp_ssse3)
+ IFUNC_IMPL_ADD (array, i, strcmp, 1, __strcmp_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strcpy.S. */
+ IFUNC_IMPL (i, name, strcpy,
+ IFUNC_IMPL_ADD (array, i, strcpy, HAS_CPU_FEATURE (SSSE3),
+ __strcpy_ssse3)
+ IFUNC_IMPL_ADD (array, i, strcpy, HAS_CPU_FEATURE (SSE2),
+ __strcpy_sse2)
+ IFUNC_IMPL_ADD (array, i, strcpy, 1, __strcpy_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strcspn.S. */
+ IFUNC_IMPL (i, name, strcspn,
+ IFUNC_IMPL_ADD (array, i, strcspn, HAS_CPU_FEATURE (SSE4_2),
+ __strcspn_sse42)
+ IFUNC_IMPL_ADD (array, i, strcspn, 1, __strcspn_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strncase.S. */
+ IFUNC_IMPL (i, name, strncasecmp,
+ IFUNC_IMPL_ADD (array, i, strncasecmp,
+ HAS_CPU_FEATURE (SSE4_2),
+ __strncasecmp_sse4_2)
+ IFUNC_IMPL_ADD (array, i, strncasecmp,
+ HAS_CPU_FEATURE (SSSE3),
+ __strncasecmp_ssse3)
+ IFUNC_IMPL_ADD (array, i, strncasecmp, 1,
+ __strncasecmp_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strncase_l.S. */
+ IFUNC_IMPL (i, name, strncasecmp_l,
+ IFUNC_IMPL_ADD (array, i, strncasecmp_l,
+ HAS_CPU_FEATURE (SSE4_2),
+ __strncasecmp_l_sse4_2)
+ IFUNC_IMPL_ADD (array, i, strncasecmp_l,
+ HAS_CPU_FEATURE (SSSE3),
+ __strncasecmp_l_ssse3)
+ IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1,
+ __strncasecmp_l_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strncat.S. */
+ IFUNC_IMPL (i, name, strncat,
+ IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSSE3),
+ __strncat_ssse3)
+ IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSE2),
+ __strncat_sse2)
+ IFUNC_IMPL_ADD (array, i, strncat, 1, __strncat_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strncpy.S. */
+ IFUNC_IMPL (i, name, strncpy,
+ IFUNC_IMPL_ADD (array, i, strncpy, HAS_CPU_FEATURE (SSSE3),
+ __strncpy_ssse3)
+ IFUNC_IMPL_ADD (array, i, strncpy, HAS_CPU_FEATURE (SSE2),
+ __strncpy_sse2)
+ IFUNC_IMPL_ADD (array, i, strncpy, 1, __strncpy_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strnlen.S. */
+ IFUNC_IMPL (i, name, strnlen,
+ IFUNC_IMPL_ADD (array, i, strnlen, HAS_CPU_FEATURE (SSE2),
+ __strnlen_sse2)
+ IFUNC_IMPL_ADD (array, i, strnlen, 1, __strnlen_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strpbrk.S. */
+ IFUNC_IMPL (i, name, strpbrk,
+ IFUNC_IMPL_ADD (array, i, strpbrk, HAS_CPU_FEATURE (SSE4_2),
+ __strpbrk_sse42)
+ IFUNC_IMPL_ADD (array, i, strpbrk, 1, __strpbrk_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strrchr.S. */
+ IFUNC_IMPL (i, name, strrchr,
+ IFUNC_IMPL_ADD (array, i, strrchr, HAS_CPU_FEATURE (SSE2),
+ __strrchr_sse2_bsf)
+ IFUNC_IMPL_ADD (array, i, strrchr, HAS_CPU_FEATURE (SSE2),
+ __strrchr_sse2)
+ IFUNC_IMPL_ADD (array, i, strrchr, 1, __strrchr_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strspn.S. */
+ IFUNC_IMPL (i, name, strspn,
+ IFUNC_IMPL_ADD (array, i, strspn, HAS_CPU_FEATURE (SSE4_2),
+ __strspn_sse42)
+ IFUNC_IMPL_ADD (array, i, strspn, 1, __strspn_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/wcschr.S. */
+ IFUNC_IMPL (i, name, wcschr,
+ IFUNC_IMPL_ADD (array, i, wcschr, HAS_CPU_FEATURE (SSE2),
+ __wcschr_sse2)
+ IFUNC_IMPL_ADD (array, i, wcschr, 1, __wcschr_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/wcscmp.S. */
+ IFUNC_IMPL (i, name, wcscmp,
+ IFUNC_IMPL_ADD (array, i, wcscmp, HAS_CPU_FEATURE (SSE2),
+ __wcscmp_sse2)
+ IFUNC_IMPL_ADD (array, i, wcscmp, 1, __wcscmp_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/wcscpy.S. */
+ IFUNC_IMPL (i, name, wcscpy,
+ IFUNC_IMPL_ADD (array, i, wcscpy, HAS_CPU_FEATURE (SSSE3),
+ __wcscpy_ssse3)
+ IFUNC_IMPL_ADD (array, i, wcscpy, 1, __wcscpy_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/wcslen.S. */
+ IFUNC_IMPL (i, name, wcslen,
+ IFUNC_IMPL_ADD (array, i, wcslen, HAS_CPU_FEATURE (SSE2),
+ __wcslen_sse2)
+ IFUNC_IMPL_ADD (array, i, wcslen, 1, __wcslen_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/wcsrchr.S. */
+ IFUNC_IMPL (i, name, wcsrchr,
+ IFUNC_IMPL_ADD (array, i, wcsrchr, HAS_CPU_FEATURE (SSE2),
+ __wcsrchr_sse2)
+ IFUNC_IMPL_ADD (array, i, wcsrchr, 1, __wcsrchr_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/wmemcmp.S. */
+ IFUNC_IMPL (i, name, wmemcmp,
+ IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSE4_2),
+ __wmemcmp_sse4_2)
+ IFUNC_IMPL_ADD (array, i, wmemcmp, HAS_CPU_FEATURE (SSSE3),
+ __wmemcmp_ssse3)
+ IFUNC_IMPL_ADD (array, i, wmemcmp, 1, __wmemcmp_ia32))
+
+#ifdef SHARED
+ /* Support sysdeps/i386/i686/multiarch/memcpy_chk.S. */
+ IFUNC_IMPL (i, name, __memcpy_chk,
+ IFUNC_IMPL_ADD (array, i, __memcpy_chk,
+ HAS_CPU_FEATURE (SSSE3),
+ __memcpy_chk_ssse3_rep)
+ IFUNC_IMPL_ADD (array, i, __memcpy_chk,
+ HAS_CPU_FEATURE (SSSE3),
+ __memcpy_chk_ssse3)
+ IFUNC_IMPL_ADD (array, i, __memcpy_chk,
+ HAS_CPU_FEATURE (SSE2),
+ __memcpy_chk_sse2_unaligned)
+ IFUNC_IMPL_ADD (array, i, __memcpy_chk, 1,
+ __memcpy_chk_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/memcpy.S. */
+ IFUNC_IMPL (i, name, memcpy,
+ IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSSE3),
+ __memcpy_ssse3_rep)
+ IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSSE3),
+ __memcpy_ssse3)
+ IFUNC_IMPL_ADD (array, i, memcpy, HAS_CPU_FEATURE (SSE2),
+ __memcpy_sse2_unaligned)
+ IFUNC_IMPL_ADD (array, i, memcpy, 1, __memcpy_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/mempcpy_chk.S. */
+ IFUNC_IMPL (i, name, __mempcpy_chk,
+ IFUNC_IMPL_ADD (array, i, __mempcpy_chk,
+ HAS_CPU_FEATURE (SSSE3),
+ __mempcpy_chk_ssse3_rep)
+ IFUNC_IMPL_ADD (array, i, __mempcpy_chk,
+ HAS_CPU_FEATURE (SSSE3),
+ __mempcpy_chk_ssse3)
+ IFUNC_IMPL_ADD (array, i, __mempcpy_chk,
+ HAS_CPU_FEATURE (SSE2),
+ __mempcpy_chk_sse2_unaligned)
+ IFUNC_IMPL_ADD (array, i, __mempcpy_chk, 1,
+ __mempcpy_chk_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/mempcpy.S. */
+ IFUNC_IMPL (i, name, mempcpy,
+ IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSSE3),
+ __mempcpy_ssse3_rep)
+ IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSSE3),
+ __mempcpy_ssse3)
+ IFUNC_IMPL_ADD (array, i, mempcpy, HAS_CPU_FEATURE (SSE2),
+ __mempcpy_sse2_unaligned)
+ IFUNC_IMPL_ADD (array, i, mempcpy, 1, __mempcpy_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strlen.S. */
+ IFUNC_IMPL (i, name, strlen,
+ IFUNC_IMPL_ADD (array, i, strlen, HAS_CPU_FEATURE (SSE2),
+ __strlen_sse2_bsf)
+ IFUNC_IMPL_ADD (array, i, strlen, HAS_CPU_FEATURE (SSE2),
+ __strlen_sse2)
+ IFUNC_IMPL_ADD (array, i, strlen, 1, __strlen_ia32))
+
+ /* Support sysdeps/i386/i686/multiarch/strncmp.S. */
+ IFUNC_IMPL (i, name, strncmp,
+ IFUNC_IMPL_ADD (array, i, strncmp, HAS_CPU_FEATURE (SSE4_2),
+ __strncmp_sse4_2)
+ IFUNC_IMPL_ADD (array, i, strncmp, HAS_CPU_FEATURE (SSSE3),
+ __strncmp_ssse3)
+ IFUNC_IMPL_ADD (array, i, strncmp, 1, __strncmp_ia32))
+#endif
+#endif
+
+ return i;
+}
diff --git a/sysdeps/i386/i686/multiarch/locale-defines.sym b/sysdeps/i386/multiarch/locale-defines.sym
similarity index 100%
rename from sysdeps/i386/i686/multiarch/locale-defines.sym
rename to sysdeps/i386/multiarch/locale-defines.sym
diff --git a/sysdeps/i386/multiarch/memset-i386.S b/sysdeps/i386/multiarch/memset-i386.S
new file mode 100644
index 0000000..261915f
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset-i386.S
@@ -0,0 +1,14 @@
+#include <init-arch.h>
+#if !SUPPORT_I686
+# define memset __memset_i386
+# define __memset_chk __memset_chk_i386
+# undef libc_hidden_builtin_def
+# define libc_hidden_builtin_def(name)
+# include <sysdeps/i386/memset.S>
+
+# ifdef SHARED
+ .globl __GI_memset
+ .hidden __GI_memset
+ __GI_memset = __memset_i386
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/memset-i686.S b/sysdeps/i386/multiarch/memset-i686.S
new file mode 100644
index 0000000..9ef9eea
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset-i686.S
@@ -0,0 +1,14 @@
+#include <init-arch.h>
+#define memset __memset_i686
+#define __memset_chk __memset_chk_i686
+#undef libc_hidden_builtin_def
+#define libc_hidden_builtin_def(name)
+#include <sysdeps/i386/i686/memset.S>
+
+#ifdef SHARED
+# if SUPPORT_I686
+ .globl __GI_memset
+ .hidden __GI_memset
+ __GI_memset = __memset_i686
+# endif
+#endif
diff --git a/sysdeps/i386/i686/multiarch/memset-sse2-rep.S b/sysdeps/i386/multiarch/memset-sse2-rep.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memset-sse2-rep.S
rename to sysdeps/i386/multiarch/memset-sse2-rep.S
diff --git a/sysdeps/i386/i686/multiarch/memset-sse2.S b/sysdeps/i386/multiarch/memset-sse2.S
similarity index 100%
rename from sysdeps/i386/i686/multiarch/memset-sse2.S
rename to sysdeps/i386/multiarch/memset-sse2.S
diff --git a/sysdeps/i386/multiarch/memset.c b/sysdeps/i386/multiarch/memset.c
new file mode 100644
index 0000000..db05527
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset.c
@@ -0,0 +1,60 @@
+/* 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_i686 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_sse2 attribute_hidden;
+extern __typeof (__redirect_memset) __memset_sse2_rep attribute_hidden;
+
+/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
+ ifunc symbol properly. */
+extern __typeof (__redirect_memset) __memset;
+extern void *memset_ifunc (void) __asm__ ("__memset");
+
+void *
+memset_ifunc (void)
+{
+ if (HAS_CPU_FEATURE (SSE2))
+ {
+ if (HAS_ARCH_FEATURE (Fast_Rep_String))
+ return __memset_sse2_rep;
+ else
+ return __memset_sse2;
+ }
+
+ if (HAS_I686)
+ return __memset_i686;
+ else
+ return __memset_i386;
+}
+__asm__ (".type __memset, %gnu_indirect_function");
+
+strong_alias (__memset, memset)
+#endif
diff --git a/sysdeps/i386/multiarch/memset_chk.S b/sysdeps/i386/multiarch/memset_chk.S
new file mode 100644
index 0000000..4ac9942
--- /dev/null
+++ b/sysdeps/i386/multiarch/memset_chk.S
@@ -0,0 +1,101 @@
+/* Multiple versions of __memset_chk
+ All versions must be listed in ifunc-impl-list.c.
+ Copyright (C) 2010-2015 Free Software Foundation, Inc.
+ Contributed by Intel Corporation.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+/* Define multiple versions only for the definition in lib. */
+#if IS_IN (libc)
+# include <sysdep.h>
+# include <init-arch.h>
+
+ .text
+ENTRY(__memset_chk)
+ .type __memset_chk, @gnu_indirect_function
+ LOAD_GOT_AND_RTLD_GLOBAL_RO
+# if !SUPPORT_I686
+ LOAD_FUNC_GOT_EAX (__memset_chk_i386)
+ HAS_ARCH_FEATURE (I686)
+ jz 2f
+# endif
+ LOAD_FUNC_GOT_EAX (__memset_chk_i686)
+ HAS_CPU_FEATURE (SSE2)
+ jz 2f
+ LOAD_FUNC_GOT_EAX (__memset_chk_sse2)
+ HAS_CPU_FEATURE (Fast_Rep_String)
+ jz 2f
+ LOAD_FUNC_GOT_EAX (__memset_chk_sse2_rep)
+2: ret
+END(__memset_chk)
+
+# ifdef SHARED
+strong_alias (__memset_chk, __memset_zero_constant_len_parameter)
+ .section .gnu.warning.__memset_zero_constant_len_parameter
+ .string "memset used with constant zero length parameter; this could be due to transposed parameters"
+# else
+ .text
+ .type __memset_chk_sse2, @function
+ .p2align 4;
+__memset_chk_sse2:
+ cfi_startproc
+ CALL_MCOUNT
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp __memset_sse2
+ cfi_endproc
+ .size __memset_chk_sse2, .-__memset_chk_sse2
+
+ .type __memset_chk_sse2_rep, @function
+ .p2align 4;
+__memset_chk_sse2_rep:
+ cfi_startproc
+ CALL_MCOUNT
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp __memset_sse2_rep
+ cfi_endproc
+ .size __memset_chk_sse2_rep, .-__memset_chk_sse2_rep
+
+ .type __memset_chk_i686, @function
+ .p2align 4;
+__memset_chk_i686:
+ cfi_startproc
+ CALL_MCOUNT
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp __memset_i686
+ cfi_endproc
+ .size __memset_chk_i686, .-__memset_chk_i686
+
+# if !SUPPORT_I686
+ .type __memset_chk_i386, @function
+ .p2align 4;
+__memset_chk_i386:
+ cfi_startproc
+ CALL_MCOUNT
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb __chk_fail
+ jmp __memset_i386
+ cfi_endproc
+ .size __memset_chk_i386, .-__memset_chk_i386
+# endif
+# endif
+#endif
diff --git a/sysdeps/i386/multiarch/test-multiarch.c b/sysdeps/i386/multiarch/test-multiarch.c
new file mode 100644
index 0000000..593cfec
--- /dev/null
+++ b/sysdeps/i386/multiarch/test-multiarch.c
@@ -0,0 +1 @@
+#include <sysdeps/x86_64/multiarch/test-multiarch.c>
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=c35685e027b4292463b3de00a1522e7cc19449ac
commit c35685e027b4292463b3de00a1522e7cc19449ac
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Wed Aug 19 13:43:30 2015 -0700
Replace BZERO_P with USE_AS_BZERO
Replace BZERO_P with USE_AS_BZERO in i686 memset.S to support i386
multi-arch bzero.
* sysdeps/i386/i686/bzero.S (USE_AS_BZERO): New.
* sysdeps/i386/i686/memset.S (BZERO_P): Removed.
Check USE_AS_BZERO instead of BZERO_P.
(__memset_zero_constant_len_parameter): Don't define if
__memset_chk or USE_AS_BZERO are defined.
diff --git a/sysdeps/i386/i686/bzero.S b/sysdeps/i386/i686/bzero.S
index 34b0faa..c7898f1 100644
--- a/sysdeps/i386/i686/bzero.S
+++ b/sysdeps/i386/i686/bzero.S
@@ -1,3 +1,4 @@
+#define USE_AS_BZERO
#define memset __bzero
#include <sysdeps/i386/i686/memset.S>
weak_alias (__bzero, bzero)
diff --git a/sysdeps/i386/i686/memset.S b/sysdeps/i386/i686/memset.S
index b6dbf2a..7a55e77 100644
--- a/sysdeps/i386/i686/memset.S
+++ b/sysdeps/i386/i686/memset.S
@@ -21,11 +21,8 @@
#include <sysdep.h>
#include "asm-syntax.h"
-/* BEWARE: `#ifdef memset' means that memset is redefined as `bzero' */
-#define BZERO_P (defined memset)
-
#define PARMS 4+4 /* space for 1 saved reg */
-#if BZERO_P
+#ifdef USE_AS_BZERO
# define DEST PARMS
# define LEN DEST+4
#else
@@ -36,7 +33,7 @@
#endif
.text
-#if defined PIC && IS_IN (libc) && !BZERO_P
+#if defined PIC && IS_IN (libc) && !defined USE_AS_BZERO
ENTRY_CHK (__memset_chk)
movl 12(%esp), %eax
cmpl %eax, 16(%esp)
@@ -50,7 +47,7 @@ ENTRY (memset)
cfi_adjust_cfa_offset (4)
movl DEST(%esp), %edx
movl LEN(%esp), %ecx
-#if BZERO_P
+#ifdef USE_AS_BZERO
xorl %eax, %eax /* fill with 0 */
#else
movzbl CHR(%esp), %eax
@@ -74,7 +71,7 @@ ENTRY (memset)
2: movl %ecx, %edx
shrl $2, %ecx
andl $3, %edx
-#if !BZERO_P
+#ifndef USE_AS_BZERO
imul $0x01010101, %eax
#endif
rep
@@ -84,22 +81,18 @@ ENTRY (memset)
stosb
1:
-#if !BZERO_P
+#ifndef USE_AS_BZERO
movl DEST(%esp), %eax /* start address of destination is result */
#endif
popl %edi
cfi_adjust_cfa_offset (-4)
cfi_restore (edi)
-#if BZERO_P
- ret
-#else
ret
-#endif
END (memset)
libc_hidden_builtin_def (memset)
-#if defined PIC && IS_IN (libc) && !BZERO_P
+#if defined PIC && IS_IN (libc) && !defined __memset_chk && !defined USE_AS_BZERO
strong_alias (__memset_chk, __memset_zero_constant_len_parameter)
.section .gnu.warning.__memset_zero_constant_len_parameter
.string "memset used with constant zero length parameter; this could be due to transposed parameters"
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=ea2e8c801f96ae804210c7566a1ed7f4b9a491b1
commit ea2e8c801f96ae804210c7566a1ed7f4b9a491b1
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Tue Aug 18 13:45:25 2015 -0700
Add i386 memset and memcpy assembly functions
Add i386 memset and memcpy assembly functions with REP MOVSB/STOSB
instructions.
* sysdeps/i386/bcopy.S: New file.
* sysdeps/i386/bzero.S: Likewise.
* sysdeps/i386/memcpy.S: Likewise.
* sysdeps/i386/memmove.S: Likewise.
* sysdeps/i386/mempcpy.S: Likewise.
* sysdeps/i386/memset.S: Likewise.
* sysdeps/i386/bzero.c: Removed.
* sysdeps/i386/memset.c: Likewise.
* sysdeps/i386/i686/memcpy_chk.S: Moved to ...
* sysdeps/i386/memcpy_chk.S: Here.
* sysdeps/i386/i686/memmove_chk.S: Moved to ...
* sysdeps/i386/memmove_chk.S: Here.
* sysdeps/i386/i686/mempcpy_chk.S: Moved to ...
* sysdeps/i386/mempcpy_chk.S: Likewise.
* sysdeps/i386/i686/memset_chk.S: Moved to ...
* sysdeps/i386/memset_chk.S: Likewise.
diff --git a/sysdeps/i386/bcopy.S b/sysdeps/i386/bcopy.S
new file mode 100644
index 0000000..12b8ddb
--- /dev/null
+++ b/sysdeps/i386/bcopy.S
@@ -0,0 +1,4 @@
+#define USE_AS_MEMMOVE
+#define USE_AS_BCOPY
+#define MEMCPY bcopy
+#include "memcpy.S"
diff --git a/sysdeps/i386/bzero.S b/sysdeps/i386/bzero.S
new file mode 100644
index 0000000..c8dd47b
--- /dev/null
+++ b/sysdeps/i386/bzero.S
@@ -0,0 +1,5 @@
+#define USE_AS_BZERO
+#define memset __bzero
+#include "memset.S"
+
+weak_alias (__bzero, bzero)
diff --git a/sysdeps/i386/bzero.c b/sysdeps/i386/bzero.c
deleted file mode 100644
index 1a89444..0000000
--- a/sysdeps/i386/bzero.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* bzero -- set a block of memory to zero. For Intel 80x86, x>=3.
- This file is part of the GNU C Library.
- Copyright (C) 1991-2015 Free Software Foundation, Inc.
- Contributed by Torbjorn Granlund (tege@sics.se).
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#include <string.h>
-#include <memcopy.h>
-
-#undef bzero
-#undef __bzero
-
-#ifdef __GNUC__
-
-void
-__bzero (dstpp, len)
- void *dstpp;
- size_t len;
-{
- /* N.B.: This code is almost verbatim from memset.c. */
- int d0;
- unsigned long int dstp = (unsigned long int) dstpp;
-
- /* This explicit register allocation
- improves code very much indeed. */
- register op_t x asm ("ax");
-
- x = 0;
-
- /* Clear the direction flag, so filling will move forward. */
- asm volatile ("cld");
-
- /* This threshold value is optimal. */
- if (len >= 12)
- {
- /* Adjust LEN for the bytes handled in the first loop. */
- len -= (-dstp) % OPSIZ;
-
- /* There are at least some bytes to set.
- No need to test for LEN == 0 in this alignment loop. */
-
- /* Fill bytes until DSTP is aligned on a longword boundary. */
- asm volatile ("rep\n"
- "stosb" /* %0, %2, %3 */ :
- "=D" (dstp), "=c" (d0) :
- "0" (dstp), "1" ((-dstp) % OPSIZ), "a" (x) :
- "memory");
-
- /* Fill longwords. */
- asm volatile ("rep\n"
- "stosl" /* %0, %2, %3 */ :
- "=D" (dstp), "=c" (d0) :
- "0" (dstp), "1" (len / OPSIZ), "a" (x) :
- "memory");
- len %= OPSIZ;
- }
-
- /* Write the last few bytes. */
- asm volatile ("rep\n"
- "stosb" /* %0, %2, %3 */ :
- "=D" (dstp), "=c" (d0) :
- "0" (dstp), "c" (len), "a" (x) :
- "memory");
-}
-weak_alias (__bzero, bzero)
-
-#else
-#include <string/bzero.c>
-#endif
diff --git a/sysdeps/i386/memcpy.S b/sysdeps/i386/memcpy.S
new file mode 100644
index 0000000..5f0196e
--- /dev/null
+++ b/sysdeps/i386/memcpy.S
@@ -0,0 +1,95 @@
+/* memcpy with REP MOVSB/STOSB
+ Copyright (C) 2015 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include "asm-syntax.h"
+
+#ifndef MEMCPY
+# define MEMCPY memcpy
+# define MEMCPY_CHK __memcpy_chk
+#endif
+
+#ifdef USE_AS_BCOPY
+# define STR2 12
+# define STR1 STR2+4
+# define N STR1+4
+#else
+# define STR1 12
+# define STR2 STR1+4
+# define N STR2+4
+#endif
+
+#define CFI_PUSH(REG) \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (REG, 0)
+
+#define CFI_POP(REG) \
+ cfi_adjust_cfa_offset (-4); \
+ cfi_restore (REG)
+
+#define PUSH(REG) pushl REG; CFI_PUSH (REG)
+#define POP(REG) popl REG; CFI_POP (REG)
+
+ .text
+#if defined SHARED && IS_IN (libc) && !defined USE_AS_BCOPY
+ENTRY (MEMCPY_CHK)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (MEMCPY_CHK)
+#endif
+ENTRY (MEMCPY)
+ PUSH (%esi)
+ PUSH (%edi)
+ movl N(%esp), %ecx
+ movl STR1(%esp), %edi
+ movl STR2(%esp), %esi
+ mov %edi, %eax
+#ifdef USE_AS_MEMPCPY
+ add %ecx, %eax
+#endif
+
+#ifdef USE_AS_MEMMOVE
+ cmp %esi, %edi
+ ja L(copy_backward)
+ je L(bwd_write_0bytes)
+#endif
+
+ rep movsb
+ POP (%edi)
+ POP (%esi)
+ ret
+
+#ifdef USE_AS_MEMMOVE
+L(copy_backward):
+ lea -1(%edi,%ecx), %edi
+ lea -1(%esi,%ecx), %esi
+ std
+ rep movsb
+ cld
+L(bwd_write_0bytes):
+ POP (%edi)
+ POP (%esi)
+ ret
+#endif
+
+END (MEMCPY)
+
+#ifndef USE_AS_BCOPY
+libc_hidden_builtin_def (MEMCPY)
+#endif
diff --git a/sysdeps/i386/i686/memcpy_chk.S b/sysdeps/i386/memcpy_chk.S
similarity index 92%
rename from sysdeps/i386/i686/memcpy_chk.S
rename to sysdeps/i386/memcpy_chk.S
index cdf807f..b3b25de 100644
--- a/sysdeps/i386/i686/memcpy_chk.S
+++ b/sysdeps/i386/memcpy_chk.S
@@ -1,4 +1,4 @@
-/* Checking memcpy for i686.
+/* Checking memcpy for i386.
Copyright (C) 2004-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -16,10 +16,10 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <sysdep.h>
-#include "asm-syntax.h"
+#ifndef SHARED
+# include <sysdep.h>
+# include "asm-syntax.h"
-#ifndef PIC
/* For libc.so this is defined in memcpy.S.
For libc.a, this is a separate source to avoid
memcpy bringing in __chk_fail and all routines
diff --git a/sysdeps/i386/memmove.S b/sysdeps/i386/memmove.S
new file mode 100644
index 0000000..60a45d2
--- /dev/null
+++ b/sysdeps/i386/memmove.S
@@ -0,0 +1,4 @@
+#define USE_AS_MEMMOVE
+#define MEMCPY memmove
+#define MEMCPY_CHK __memmove_chk
+#include "memcpy.S"
diff --git a/sysdeps/i386/i686/memmove_chk.S b/sysdeps/i386/memmove_chk.S
similarity index 78%
rename from sysdeps/i386/i686/memmove_chk.S
rename to sysdeps/i386/memmove_chk.S
index 64bf9e0..26d2abd 100644
--- a/sysdeps/i386/i686/memmove_chk.S
+++ b/sysdeps/i386/memmove_chk.S
@@ -1,4 +1,4 @@
-/* Checking memmove for x86-64.
+/* Checking memmove for i386
Copyright (C) 2004-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -16,14 +16,13 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <sysdep.h>
-#include "asm-syntax.h"
+#ifndef SHARED
+# include <sysdep.h>
+# include "asm-syntax.h"
-#ifndef PIC
- /* For libc.so this is defined in memmove.S.
- For libc.a, this is a separate source to avoid
- memmove bringing in __chk_fail and all routines
- it calls. */
+/* For libc.so this is defined in memmove.S. For libc.a, this is a
+ separate source to avoid memmove bringing in __chk_fail and all
+ routines it calls. */
.text
ENTRY (__memmove_chk)
movl 12(%esp), %eax
diff --git a/sysdeps/i386/mempcpy.S b/sysdeps/i386/mempcpy.S
new file mode 100644
index 0000000..61addb7
--- /dev/null
+++ b/sysdeps/i386/mempcpy.S
@@ -0,0 +1,7 @@
+#define USE_AS_MEMPCPY
+#define MEMCPY __mempcpy
+#define MEMCPY_CHK __mempcpy_chk
+#include "memcpy.S"
+
+weak_alias (__mempcpy, mempcpy)
+libc_hidden_builtin_def (mempcpy)
diff --git a/sysdeps/i386/i686/mempcpy_chk.S b/sysdeps/i386/mempcpy_chk.S
similarity index 78%
rename from sysdeps/i386/i686/mempcpy_chk.S
rename to sysdeps/i386/mempcpy_chk.S
index a61757b..05f86c3 100644
--- a/sysdeps/i386/i686/mempcpy_chk.S
+++ b/sysdeps/i386/mempcpy_chk.S
@@ -1,4 +1,4 @@
-/* Checking mempcpy for x86-64.
+/* Checking mempcpy for i386
Copyright (C) 2004-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -16,14 +16,13 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <sysdep.h>
-#include "asm-syntax.h"
+#ifndef SHARED
+# include <sysdep.h>
+# include "asm-syntax.h"
-#ifndef PIC
- /* For libc.so this is defined in mempcpy.S.
- For libc.a, this is a separate source to avoid
- mempcpy bringing in __chk_fail and all routines
- it calls. */
+/* For libc.so this is defined in mempcpy.S. For libc.a, this is a
+ separate source to avoid mempcpy bringing in __chk_fail and all
+ routines it calls. */
.text
ENTRY (__mempcpy_chk)
movl 12(%esp), %eax
diff --git a/sysdeps/i386/memset.S b/sysdeps/i386/memset.S
new file mode 100644
index 0000000..21b3430
--- /dev/null
+++ b/sysdeps/i386/memset.S
@@ -0,0 +1,68 @@
+/* memset with REP MOVSB/STOSB
+ Copyright (C) 2015 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+
+#define CFI_PUSH(REG) \
+ cfi_adjust_cfa_offset (4); \
+ cfi_rel_offset (REG, 0)
+
+#define CFI_POP(REG) \
+ cfi_adjust_cfa_offset (-4); \
+ cfi_restore (REG)
+
+#define PUSH(REG) pushl REG; CFI_PUSH (REG)
+#define POP(REG) popl REG; CFI_POP (REG)
+
+#define STR1 8
+#ifdef USE_AS_BZERO
+#define N STR1+4
+#else
+#define STR2 STR1+4
+#define N STR2+4
+#endif
+
+ .text
+#if defined SHARED && IS_IN (libc) && !defined USE_AS_BZERO
+ENTRY (__memset_chk)
+ movl 12(%esp), %eax
+ cmpl %eax, 16(%esp)
+ jb HIDDEN_JUMPTARGET (__chk_fail)
+END (__memset_chk)
+#endif
+ENTRY (memset)
+ PUSH (%edi)
+ movl N(%esp), %ecx
+ movl STR1(%esp), %edi
+#ifdef USE_AS_BZERO
+ xor %eax, %eax
+#else
+ movzbl STR2(%esp), %eax
+ mov %edi, %edx
+#endif
+ rep stosb
+#ifndef USE_AS_BZERO
+ mov %edx, %eax
+#endif
+ POP (%edi)
+ ret
+END (memset)
+
+#ifndef USE_AS_BZERO
+libc_hidden_builtin_def (memset)
+#endif
diff --git a/sysdeps/i386/memset.c b/sysdeps/i386/memset.c
deleted file mode 100644
index bf11590..0000000
--- a/sysdeps/i386/memset.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/* Set a block of memory to some byte value.
- For Intel 80x86, x>=3.
- Copyright (C) 1991-2015 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Torbjorn Granlund (tege@sics.se).
-
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
-
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
-
-#include <string.h>
-#include <memcopy.h>
-
-#ifdef __GNUC__
-
-#undef memset
-
-void *
-memset (void *dstpp, int c, size_t len)
-{
- int d0;
- unsigned long int dstp = (unsigned long int) dstpp;
-
- /* This explicit register allocation
- improves code very much indeed. */
- register op_t x asm("ax");
-
- x = (unsigned char) c;
-
- /* Clear the direction flag, so filling will move forward. */
- asm volatile("cld");
-
- /* This threshold value is optimal. */
- if (len >= 12)
- {
- /* Fill X with four copies of the char we want to fill with. */
- x |= (x << 8);
- x |= (x << 16);
-
- /* Adjust LEN for the bytes handled in the first loop. */
- len -= (-dstp) % OPSIZ;
-
- /* There are at least some bytes to set.
- No need to test for LEN == 0 in this alignment loop. */
-
- /* Fill bytes until DSTP is aligned on a longword boundary. */
- asm volatile("rep\n"
- "stosb" /* %0, %2, %3 */ :
- "=D" (dstp), "=c" (d0) :
- "0" (dstp), "1" ((-dstp) % OPSIZ), "a" (x) :
- "memory");
-
- /* Fill longwords. */
- asm volatile("rep\n"
- "stosl" /* %0, %2, %3 */ :
- "=D" (dstp), "=c" (d0) :
- "0" (dstp), "1" (len / OPSIZ), "a" (x) :
- "memory");
- len %= OPSIZ;
- }
-
- /* Write the last few bytes. */
- asm volatile("rep\n"
- "stosb" /* %0, %2, %3 */ :
- "=D" (dstp), "=c" (d0) :
- "0" (dstp), "1" (len), "a" (x) :
- "memory");
-
- return dstpp;
-}
-libc_hidden_builtin_def (memset)
-
-#else
-#include <string/memset.c>
-#endif
diff --git a/sysdeps/i386/i686/memset_chk.S b/sysdeps/i386/memset_chk.S
similarity index 79%
rename from sysdeps/i386/i686/memset_chk.S
rename to sysdeps/i386/memset_chk.S
index da982fd..2312d32 100644
--- a/sysdeps/i386/i686/memset_chk.S
+++ b/sysdeps/i386/memset_chk.S
@@ -1,4 +1,4 @@
-/* Checking memset for i686.
+/* Checking memset for i386.
Copyright (C) 2004-2015 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -16,14 +16,13 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
-#include <sysdep.h>
-#include "asm-syntax.h"
-
#ifndef SHARED
- /* For libc.so this is defined in memset.S.
- For libc.a, this is a separate source to avoid
- memset bringing in __chk_fail and all routines
- it calls. */
+# include <sysdep.h>
+# include "asm-syntax.h"
+
+/* For libc.so this is defined in memset.S. For libc.a, this is a
+ separate source to avoid memset bringing in __chk_fail and all
+ routines it calls. */
.text
ENTRY (__memset_chk)
movl 12(%esp), %eax
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=b50c2db43357a7f0d6c474d21de76693f287d965
commit b50c2db43357a7f0d6c474d21de76693f287d965
Author: H.J. Lu <hjl.tools@gmail.com>
Date: Mon Aug 17 10:19:05 2015 -0700
Detect i586 and i686 features at run-time
We detect i586 and i686 features at run-time by checking CX8 and CMOV
CPUID features bits. We can use these information to select the best
implementation in ix86 multiarch. HAS_I586 and HAS_I686 are changed
run-time check. SUPPORT_I586 and SUPPORT_I686 are added for
compile-time check.
* sysdeps/x86/cpu-features.c (init_cpu_features): Set bit_I586
bit if CX8 is available. Set bit_I686 bit if CMOV is available.
* sysdeps/x86/cpu-features.h (bit_I586): New.
(bit_I686): Likewise.
(bit_CX8): Likewise.
(bit_CMOV): Likewise.
(index_CX8): Likewise.
(index_CMOV): Likewise.
(index_I586): Likewise.
(index_I686): Likewise.
(reg_CX8): Likewise.
(reg_CMOV): Likewise.
(HAS_I586): Renamed to ...
(SUPPORT_I586): This.
(HAS_I686): Renamed to ...
(SUPPORT_I686): This.
(HAS_I586): Defined as HAS_ARCH_FEATURE (I586) if i586 isn't
available at compile-time.
(HAS_I686): Defined as HAS_ARCH_FEATURE (I686) if i686 isn't
available at compile-time.
diff --git a/sysdeps/x86/cpu-features.c b/sysdeps/x86/cpu-features.c
index 40575de..b03451d 100644
--- a/sysdeps/x86/cpu-features.c
+++ b/sysdeps/x86/cpu-features.c
@@ -150,6 +150,14 @@ init_cpu_features (struct cpu_features *cpu_features)
else
kind = arch_kind_other;
+ /* Support i586 if CX8 is available. */
+ if (HAS_CPU_FEATURE (CX8))
+ cpu_features->feature[index_I586] |= bit_I586;
+
+ /* Support i686 if CMOV is available. */
+ if (HAS_CPU_FEATURE (CMOV))
+ cpu_features->feature[index_I686] |= bit_I686;
+
if (cpu_features->max_cpuid >= 7)
__cpuid_count (7, 0,
cpu_features->cpuid[COMMON_CPUID_INDEX_7].eax,
diff --git a/sysdeps/x86/cpu-features.h b/sysdeps/x86/cpu-features.h
index 6e70624..2c0a3fd 100644
--- a/sysdeps/x86/cpu-features.h
+++ b/sysdeps/x86/cpu-features.h
@@ -31,10 +31,14 @@
#define bit_AVX_Fast_Unaligned_Load (1 << 11)
#define bit_AVX512F_Usable (1 << 12)
#define bit_AVX512DQ_Usable (1 << 13)
+#define bit_I586 (1 << 14)
+#define bit_I686 (1 << 15)
/* CPUID Feature flags. */
/* COMMON_CPUID_INDEX_1. */
+#define bit_CX8 (1 << 8)
+#define bit_CMOV (1 << 15)
#define bit_SSE2 (1 << 26)
#define bit_SSSE3 (1 << 9)
#define bit_SSE4_1 (1 << 19)
@@ -69,6 +73,8 @@
# include <ifunc-defines.h>
# include <rtld-global-offsets.h>
+# define index_CX8 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_EDX_OFFSET
+# define index_CMOV COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_EDX_OFFSET
# define index_SSE2 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_EDX_OFFSET
# define index_SSSE3 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET
# define index_SSE4_1 COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET
@@ -89,6 +95,8 @@
# define index_AVX_Fast_Unaligned_Load FEATURE_INDEX_1*FEATURE_SIZE
# define index_AVX512F_Usable FEATURE_INDEX_1*FEATURE_SIZE
# define index_AVX512DQ_Usable FEATURE_INDEX_1*FEATURE_SIZE
+# define index_I586 FEATURE_INDEX_1*FEATURE_SIZE
+# define index_I686 FEATURE_INDEX_1*FEATURE_SIZE
# if defined (_LIBC) && !IS_IN (nonlib)
# ifdef __x86_64__
@@ -193,6 +201,8 @@ extern const struct cpu_features *__get_cpu_features (void)
# define HAS_ARCH_FEATURE(name) \
((__get_cpu_features ()->feature[index_##name] & (bit_##name)) != 0)
+# define index_CX8 COMMON_CPUID_INDEX_1
+# define index_CMOV COMMON_CPUID_INDEX_1
# define index_SSE2 COMMON_CPUID_INDEX_1
# define index_SSSE3 COMMON_CPUID_INDEX_1
# define index_SSE4_1 COMMON_CPUID_INDEX_1
@@ -207,6 +217,8 @@ extern const struct cpu_features *__get_cpu_features (void)
# define index_POPCOUNT COMMON_CPUID_INDEX_1
# define index_OSXSAVE COMMON_CPUID_INDEX_1
+# define reg_CX8 edx
+# define reg_CMOV edx
# define reg_SSE2 edx
# define reg_SSSE3 ecx
# define reg_SSE4_1 ecx
@@ -234,6 +246,8 @@ extern const struct cpu_features *__get_cpu_features (void)
# define index_AVX_Fast_Unaligned_Load FEATURE_INDEX_1
# define index_AVX512F_Usable FEATURE_INDEX_1
# define index_AVX512DQ_Usable FEATURE_INDEX_1
+# define index_I586 FEATURE_INDEX_1
+# define index_I686 FEATURE_INDEX_1
#endif /* !__ASSEMBLER__ */
@@ -242,7 +256,9 @@ extern const struct cpu_features *__get_cpu_features (void)
#elif defined __i586__ || defined __pentium__
# define HAS_CPUID 1
# define HAS_I586 1
-# define HAS_I686 0
+# define HAS_I686 HAS_ARCH_FEATURE (I686)
+# define SUPPORT_I586 1
+# define SUPPORT_I686 0
#elif (defined __i686__ || defined __pentiumpro__ \
|| defined __pentium4__ || defined __nocona__ \
|| defined __atom__ || defined __core2__ \
@@ -259,10 +275,14 @@ extern const struct cpu_features *__get_cpu_features (void)
# define HAS_CPUID 1
# define HAS_I586 1
# define HAS_I686 1
+# define SUPPORT_I586 1
+# define SUPPORT_I686 1
#else
# define HAS_CPUID 0
-# define HAS_I586 0
-# define HAS_I686 0
+# define HAS_I586 HAS_ARCH_FEATURE (I586)
+# define HAS_I686 HAS_ARCH_FEATURE (I686)
+# define SUPPORT_I586 0
+# define SUPPORT_I686 0
#endif
#endif /* cpu_features_h */
-----------------------------------------------------------------------
hooks/post-receive
--
GNU C Library master sources