diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2015-08-20 15:20:58 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2015-08-27 09:35:11 -0700 |
commit | d5496eb9a14df0fe463c211f5fe05cc73e8e770c (patch) | |
tree | 19053038a9799e981668201a3c2f1658fcb82ded /sysdeps/i386 | |
parent | f737f66b63911549f2dc82a5b940cb219b6e661e (diff) | |
download | glibc-d5496eb9a14df0fe463c211f5fe05cc73e8e770c.tar.gz glibc-d5496eb9a14df0fe463c211f5fe05cc73e8e770c.tar.xz glibc-d5496eb9a14df0fe463c211f5fe05cc73e8e770c.zip |
Add i386 strcat multiarch functions
Diffstat (limited to 'sysdeps/i386')
-rw-r--r-- | sysdeps/i386/i686/multiarch/Makefile | 2 | ||||
-rw-r--r-- | sysdeps/i386/i686/multiarch/strcat.S | 92 | ||||
-rw-r--r-- | sysdeps/i386/i686/multiarch/strncat.S | 5 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/Makefile | 4 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/ifunc-impl-list.c | 8 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcat-i386.S | 10 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcat-sse2.S (renamed from sysdeps/i386/i686/multiarch/strcat-sse2.S) | 0 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcat-ssse3.S (renamed from sysdeps/i386/i686/multiarch/strcat-ssse3.S) | 0 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strcat.c | 51 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strlen-sse2.S (renamed from sysdeps/i386/i686/multiarch/strlen-sse2.S) | 0 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strncat-i386.c (renamed from sysdeps/i386/i686/multiarch/strncat-c.c) | 4 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strncat-sse2.S (renamed from sysdeps/i386/i686/multiarch/strncat-sse2.S) | 0 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strncat-ssse3.S (renamed from sysdeps/i386/i686/multiarch/strncat-ssse3.S) | 0 | ||||
-rw-r--r-- | sysdeps/i386/multiarch/strncat.c | 54 |
14 files changed, 123 insertions, 107 deletions
diff --git a/sysdeps/i386/i686/multiarch/Makefile b/sysdeps/i386/i686/multiarch/Makefile index d38a051305..830c77d951 100644 --- a/sysdeps/i386/i686/multiarch/Makefile +++ b/sysdeps/i386/i686/multiarch/Makefile @@ -1,8 +1,6 @@ ifeq ($(subdir),string) sysdep_routines += varshift \ strlen-sse2 strlen-sse2-bsf \ - strcat-ssse3 \ - strcat-sse2 strncat-ssse3 strncat-sse2 strncat-c \ strchr-sse2 strrchr-sse2 strchr-sse2-bsf strrchr-sse2-bsf \ strnlen-sse2 strnlen-c ifeq (yes,$(config-cflags-sse4)) diff --git a/sysdeps/i386/i686/multiarch/strcat.S b/sysdeps/i386/i686/multiarch/strcat.S deleted file mode 100644 index e893815e24..0000000000 --- a/sysdeps/i386/i686/multiarch/strcat.S +++ /dev/null @@ -1,92 +0,0 @@ -/* Multiple versions of strcat - All versions must be listed in ifunc-impl-list.c. - Copyright (C) 2011-2015 Free Software Foundation, Inc. - Contributed by Intel Corporation. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <init-arch.h> - -#ifndef USE_AS_STRNCAT -# ifndef STRCAT -# define STRCAT strcat -# endif -#endif - -#ifdef USE_AS_STRNCAT -# define STRCAT_SSSE3 __strncat_ssse3 -# define STRCAT_SSE2 __strncat_sse2 -# define STRCAT_IA32 __strncat_ia32 -# define __GI_STRCAT __GI_strncat -#else -# define STRCAT_SSSE3 __strcat_ssse3 -# define STRCAT_SSE2 __strcat_sse2 -# define STRCAT_IA32 __strcat_ia32 -# define __GI_STRCAT __GI_strcat -#endif - - -/* Define multiple versions only for the definition in libc. Don't - define multiple versions for strncat in static library since we - need strncat before the initialization happened. */ -#if IS_IN (libc) - - .text -ENTRY(STRCAT) - .type STRCAT, @gnu_indirect_function - LOAD_GOT_AND_RTLD_GLOBAL_RO - LOAD_FUNC_GOT_EAX (STRCAT_IA32) - HAS_CPU_FEATURE (SSE2) - jz 2f - LOAD_FUNC_GOT_EAX (STRCAT_SSE2) - HAS_ARCH_FEATURE (Fast_Unaligned_Load) - jnz 2f - HAS_CPU_FEATURE (SSSE3) - jz 2f - LOAD_FUNC_GOT_EAX (STRCAT_SSSE3) -2: ret -END(STRCAT) - -# undef ENTRY -# define ENTRY(name) \ - .type STRCAT_IA32, @function; \ - .align 16; \ - .globl STRCAT_IA32; \ - .hidden STRCAT_IA32; \ - STRCAT_IA32: cfi_startproc; \ - CALL_MCOUNT -# undef END -# define END(name) \ - cfi_endproc; .size STRCAT_IA32, .-STRCAT_IA32 - -# ifdef SHARED -# undef libc_hidden_builtin_def -/* It doesn't make sense to send libc-internal strcat calls through a PLT. - The speedup we get from using SSSE3 instruction is likely eaten away - by the indirect call in the PLT. */ -# define libc_hidden_builtin_def(name) \ - .globl __GI_STRCAT; __GI_STRCAT = STRCAT_IA32 -# undef libc_hidden_def -# define libc_hidden_def(name) \ - .globl __GI___STRCAT; __GI___STRCAT = STRCAT_IA32 - -# endif -#endif - -#ifndef USE_AS_STRNCAT -# include "../../strcat.S" -#endif diff --git a/sysdeps/i386/i686/multiarch/strncat.S b/sysdeps/i386/i686/multiarch/strncat.S deleted file mode 100644 index 5c1bf41453..0000000000 --- a/sysdeps/i386/i686/multiarch/strncat.S +++ /dev/null @@ -1,5 +0,0 @@ -/* Multiple versions of strncat - All versions must be listed in ifunc-impl-list.c. */ -#define STRCAT strncat -#define USE_AS_STRNCAT -#include "strcat.S" diff --git a/sysdeps/i386/multiarch/Makefile b/sysdeps/i386/multiarch/Makefile index 78a99a7bbe..87d36a42ca 100644 --- a/sysdeps/i386/multiarch/Makefile +++ b/sysdeps/i386/multiarch/Makefile @@ -31,7 +31,9 @@ sysdep_routines += bcopy-i386 bcopy-i686 bcopy-sse2-unaligned \ strcasecmp_l-ssse3 \ strncase-i386 strncase_l-i386 strncase_l-sse4 \ strncase_l-ssse3 \ - strncmp-i386 strncmp-ssse3 strncmp-sse4 + strncmp-i386 strncmp-ssse3 strncmp-sse4 \ + strcat-i386 strcat-sse2 strcat-ssse3 \ + strncat-i386 strncat-sse2 strncat-ssse3 endif ifeq (mathyes,$(subdir)$(config-cflags-avx)) diff --git a/sysdeps/i386/multiarch/ifunc-impl-list.c b/sysdeps/i386/multiarch/ifunc-impl-list.c index bddc9e75da..05b9bcd622 100644 --- a/sysdeps/i386/multiarch/ifunc-impl-list.c +++ b/sysdeps/i386/multiarch/ifunc-impl-list.c @@ -206,15 +206,15 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, IFUNC_IMPL_ADD (array, i, strcasecmp_l, 1, __strcasecmp_l_i386)) -#if 0 /* Support sysdeps/i386/i686/multiarch/strcat.S. */ IFUNC_IMPL (i, name, strcat, IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSSE3), __strcat_ssse3) IFUNC_IMPL_ADD (array, i, strcat, HAS_CPU_FEATURE (SSE2), __strcat_sse2) - IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_ia32)) + IFUNC_IMPL_ADD (array, i, strcat, 1, __strcat_i386)) +#if 0 /* Support sysdeps/i386/i686/multiarch/strchr.S. */ IFUNC_IMPL (i, name, strchr, IFUNC_IMPL_ADD (array, i, strchr, HAS_CPU_FEATURE (SSE2), @@ -278,15 +278,13 @@ __libc_ifunc_impl_list (const char *name, struct libc_ifunc_impl *array, IFUNC_IMPL_ADD (array, i, strncasecmp_l, 1, __strncasecmp_l_i386)) -#if 0 /* Support sysdeps/i386/i686/multiarch/strncat.S. */ IFUNC_IMPL (i, name, strncat, IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSSE3), __strncat_ssse3) IFUNC_IMPL_ADD (array, i, strncat, HAS_CPU_FEATURE (SSE2), __strncat_sse2) - IFUNC_IMPL_ADD (array, i, strncat, 1, __strncat_ia32)) -#endif + IFUNC_IMPL_ADD (array, i, strncat, 1, __strncat_i386)) /* Support sysdeps/i386/i686/multiarch/strncpy.S. */ IFUNC_IMPL (i, name, strncpy, diff --git a/sysdeps/i386/multiarch/strcat-i386.S b/sysdeps/i386/multiarch/strcat-i386.S new file mode 100644 index 0000000000..c13503d3e4 --- /dev/null +++ b/sysdeps/i386/multiarch/strcat-i386.S @@ -0,0 +1,10 @@ +#define strcat __strcat_i386 +#undef libc_hidden_builtin_def +#define libc_hidden_builtin_def(name) +#include <sysdeps/i386/strcat.S> + +#ifdef SHARED + .globl __GI_strcat + .hidden __GI_strcat + __GI_strcat = __strcat_i386 +#endif diff --git a/sysdeps/i386/i686/multiarch/strcat-sse2.S b/sysdeps/i386/multiarch/strcat-sse2.S index 0f9e13c6d3..0f9e13c6d3 100644 --- a/sysdeps/i386/i686/multiarch/strcat-sse2.S +++ b/sysdeps/i386/multiarch/strcat-sse2.S diff --git a/sysdeps/i386/i686/multiarch/strcat-ssse3.S b/sysdeps/i386/multiarch/strcat-ssse3.S index a5b0bc6818..a5b0bc6818 100644 --- a/sysdeps/i386/i686/multiarch/strcat-ssse3.S +++ b/sysdeps/i386/multiarch/strcat-ssse3.S diff --git a/sysdeps/i386/multiarch/strcat.c b/sysdeps/i386/multiarch/strcat.c new file mode 100644 index 0000000000..5a2aa9cc42 --- /dev/null +++ b/sysdeps/i386/multiarch/strcat.c @@ -0,0 +1,51 @@ +/* Multiple versions of strcat. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +/* Redefine strcat so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strcat +# define strcat __redirect_strcat +# include <string.h> +# undef strcat + +# include <init-arch.h> + +extern __typeof (__redirect_strcat) __strcat_i386 attribute_hidden; +extern __typeof (__redirect_strcat) __strcat_sse2 attribute_hidden; +extern __typeof (__redirect_strcat) __strcat_ssse3 attribute_hidden; + +/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ +extern __typeof (__redirect_strcat) strcat; +extern void *strcat_ifunc (void) __asm__ ("strcat"); + +void * +strcat_ifunc (void) +{ + if (HAS_CPU_FEATURE (SSSE3)) + return __strcat_ssse3; + else if (HAS_CPU_FEATURE (SSE2)) + return __strcat_sse2; + + return __strcat_i386; +} +__asm__ (".type strcat, %gnu_indirect_function"); +#endif diff --git a/sysdeps/i386/i686/multiarch/strlen-sse2.S b/sysdeps/i386/multiarch/strlen-sse2.S index 3d30714b7a..3d30714b7a 100644 --- a/sysdeps/i386/i686/multiarch/strlen-sse2.S +++ b/sysdeps/i386/multiarch/strlen-sse2.S diff --git a/sysdeps/i386/i686/multiarch/strncat-c.c b/sysdeps/i386/multiarch/strncat-i386.c index 132a000545..0f22fbc035 100644 --- a/sysdeps/i386/i686/multiarch/strncat-c.c +++ b/sysdeps/i386/multiarch/strncat-i386.c @@ -1,8 +1,8 @@ -#define STRNCAT __strncat_ia32 +#define STRNCAT __strncat_i386 #ifdef SHARED #undef libc_hidden_def #define libc_hidden_def(name) \ - __hidden_ver1 (__strncat_ia32, __GI___strncat, __strncat_ia32); + __hidden_ver1 (__strncat_i386, __GI___strncat, __strncat_i386); #endif #include "string/strncat.c" diff --git a/sysdeps/i386/i686/multiarch/strncat-sse2.S b/sysdeps/i386/multiarch/strncat-sse2.S index f1045b72b8..f1045b72b8 100644 --- a/sysdeps/i386/i686/multiarch/strncat-sse2.S +++ b/sysdeps/i386/multiarch/strncat-sse2.S diff --git a/sysdeps/i386/i686/multiarch/strncat-ssse3.S b/sysdeps/i386/multiarch/strncat-ssse3.S index 625b90a978..625b90a978 100644 --- a/sysdeps/i386/i686/multiarch/strncat-ssse3.S +++ b/sysdeps/i386/multiarch/strncat-ssse3.S diff --git a/sysdeps/i386/multiarch/strncat.c b/sysdeps/i386/multiarch/strncat.c new file mode 100644 index 0000000000..7ab3e38df6 --- /dev/null +++ b/sysdeps/i386/multiarch/strncat.c @@ -0,0 +1,54 @@ +/* Multiple versions of strncat. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +/* Define multiple versions only for the definition in libc. Don't + define multiple versions for strncat in static library since we + need strncat before the initialization happened. */ +#if defined SHARED && IS_IN (libc) +# define _HAVE_STRING_ARCH_strncat +/* Redefine strncat so that the compiler won't complain about the type + mismatch with the IFUNC selector in strong_alias, below. */ +# undef strncat +# define strncat __redirect_strncat +# include <string.h> +# undef strncat + +# include <init-arch.h> + +extern __typeof (__redirect_strncat) __strncat_i386 attribute_hidden; +extern __typeof (__redirect_strncat) __strncat_sse2 attribute_hidden; +extern __typeof (__redirect_strncat) __strncat_ssse3 attribute_hidden; + +/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ +extern __typeof (__redirect_strncat) strncat; +extern void *strncat_ifunc (void) __asm__ ("strncat"); + +void * +strncat_ifunc (void) +{ + if (HAS_CPU_FEATURE (SSSE3)) + return __strncat_ssse3; + else if (HAS_CPU_FEATURE (SSE2)) + return __strncat_sse2; + + return __strncat_i386; +} +__asm__ (".type strncat, %gnu_indirect_function"); +#endif |