diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2015-08-19 14:10:40 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2015-08-27 09:35:10 -0700 |
commit | 42f926f9bd9e52fddd526268efccf5bd93d4f0dd (patch) | |
tree | c4a69b45e566b46e1f2148e758b30a3ec9c7afbe | |
parent | 75dd0a8f3db2813196db08928b1b6bb200230695 (diff) | |
download | glibc-42f926f9bd9e52fddd526268efccf5bd93d4f0dd.tar.gz glibc-42f926f9bd9e52fddd526268efccf5bd93d4f0dd.tar.xz glibc-42f926f9bd9e52fddd526268efccf5bd93d4f0dd.zip |
Add i386 memset family multiarch functions
37 files changed, 355 insertions, 232 deletions
diff --git a/sysdeps/i386/i586/multiarch/bzero-i386.S b/sysdeps/i386/i586/multiarch/bzero-i386.S new file mode 100644 index 0000000000..02c0874b2e --- /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 0000000000..b33a36cb1d --- /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 0000000000..c14c064406 --- /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 0000000000..3d2a287dd8 --- /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 0000000000..47b29ce55b --- /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 0000000000..57037dd45f --- /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 31bfd39bae..59072b94da 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 0000000000..9d841c9fd1 --- /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 0000000000..9d841c9fd1 --- /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 0000000000..1af300c4a3 --- /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 95c96a81ea..0000000000 --- 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 0000000000..c14c064406 --- /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 0000000000..9d841c9fd1 --- /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 0000000000..9d841c9fd1 --- /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 0000000000..e9a22b89e8 --- /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 8015d57894..0000000000 --- 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 0000000000..57037dd45f --- /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 7be45e710e..0000000000 --- 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 0000000000..fefbc63f63 --- /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 0000000000..44fabedd1d --- /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 0000000000..4a253d6931 --- /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 0000000000..2d5b61a7b7 --- /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 0000000000..aaa36cef01 --- /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 index 507b288bb3..507b288bb3 100644 --- a/sysdeps/i386/i686/multiarch/bzero-sse2-rep.S +++ b/sysdeps/i386/multiarch/bzero-sse2-rep.S diff --git a/sysdeps/i386/i686/multiarch/bzero-sse2.S b/sysdeps/i386/multiarch/bzero-sse2.S index 8d04512e4e..8d04512e4e 100644 --- a/sysdeps/i386/i686/multiarch/bzero-sse2.S +++ b/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 0000000000..75fe9b8544 --- /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 index 96e9cfaf61..96e9cfaf61 100644 --- a/sysdeps/i386/i686/multiarch/ifunc-defines.sym +++ b/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 index a6735a804b..7bde24e112 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 index aebff9a4f9..aebff9a4f9 100644 --- a/sysdeps/i386/i686/multiarch/locale-defines.sym +++ b/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 0000000000..860c756b0f --- /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 0000000000..4c94fe4a18 --- /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 0000000000..8d3462f735 --- /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 index 9c8f232c42..9c8f232c42 100644 --- a/sysdeps/i386/i686/multiarch/memset-sse2-rep.S +++ b/sysdeps/i386/multiarch/memset-sse2-rep.S diff --git a/sysdeps/i386/i686/multiarch/memset-sse2.S b/sysdeps/i386/multiarch/memset-sse2.S index d03e647a3f..d03e647a3f 100644 --- a/sysdeps/i386/i686/multiarch/memset-sse2.S +++ b/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 0000000000..49d7839f4f --- /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 0000000000..5e5c9b63e5 --- /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 index 593cfec273..593cfec273 100644 --- a/sysdeps/i386/i686/multiarch/test-multiarch.c +++ b/sysdeps/i386/multiarch/test-multiarch.c |