diff --git a/ChangeLog b/ChangeLog index bf791fcc43..70faa63f6e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2017-06-15 H.J. Lu + + * sysdeps/x86_64/multiarch/Makefile (sysdep_routines): Add + strcspn-sse2, strpbrk-sse2 and strspn-sse2. + * sysdeps/x86_64/strcspn.S (STRPBRK_P): Removed. + Check USE_AS_STRPBRK instead of STRPBRK_P. + * sysdeps/x86_64/strpbrk.S (USE_AS_STRPBRK): New. + * sysdeps/x86_64/multiarch/ifunc-sse4_2.h: New file. + * sysdeps/x86_64/multiarch/strcspn-sse2.S: Likewise. + * sysdeps/x86_64/multiarch/strcspn.c: Likewise. + * sysdeps/x86_64/multiarch/strpbrk-sse2.S: Likewise. + * sysdeps/x86_64/multiarch/strpbrk.c: Likewise. + * sysdeps/x86_64/multiarch/strspn-sse2.S: Likewise. + * sysdeps/x86_64/multiarch/strspn.c: Likewise. + * sysdeps/x86_64/multiarch/strcspn.S: Removed. + * sysdeps/x86_64/multiarch/strpbrk.S: Likewise. + * sysdeps/x86_64/multiarch/strspn.S: Likewise. + * sysdeps/x86_64/multiarch/strpbrk-c.c: Remove "#ifdef SHARED" + and "#endif". + 2017-06-15 H.J. Lu * sysdeps/x86_64/multiarch/wcscpy.S: Removed. diff --git a/sysdeps/x86_64/multiarch/Makefile b/sysdeps/x86_64/multiarch/Makefile index 43443b303c..2c54c5cc23 100644 --- a/sysdeps/x86_64/multiarch/Makefile +++ b/sysdeps/x86_64/multiarch/Makefile @@ -26,6 +26,7 @@ sysdep_routines += strncat-c stpncpy-c strncpy-c strcmp-ssse3 \ strcat-sse2 \ strcat-sse2-unaligned strncat-sse2-unaligned \ strchr-sse2-no-bsf memcmp-ssse3 strstr-sse2-unaligned \ + strcspn-sse2 strpbrk-sse2 strspn-sse2 \ strcspn-c strpbrk-c strspn-c varshift \ memset-avx512-no-vzeroupper \ memmove-sse2-unaligned-erms \ diff --git a/sysdeps/x86_64/multiarch/ifunc-sse4_2.h b/sysdeps/x86_64/multiarch/ifunc-sse4_2.h new file mode 100644 index 0000000000..a43265e8e0 --- /dev/null +++ b/sysdeps/x86_64/multiarch/ifunc-sse4_2.h @@ -0,0 +1,34 @@ +/* Common definition for ifunc selections optimized with SSE2 and SSE4.2. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2017 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 + . */ + +#include + +extern __typeof (REDIRECT_NAME) OPTIMIZE (sse2) attribute_hidden; +extern __typeof (REDIRECT_NAME) OPTIMIZE (sse42) attribute_hidden; + +static inline void * +IFUNC_SELECTOR (void) +{ + const struct cpu_features* cpu_features = __get_cpu_features (); + + if (CPU_FEATURES_CPU_P (cpu_features, SSE4_2)) + return OPTIMIZE (sse42); + + return OPTIMIZE (sse2); +} diff --git a/sysdeps/x86_64/multiarch/strcspn-sse2.S b/sysdeps/x86_64/multiarch/strcspn-sse2.S new file mode 100644 index 0000000000..72eb38b2e5 --- /dev/null +++ b/sysdeps/x86_64/multiarch/strcspn-sse2.S @@ -0,0 +1,28 @@ +/* strcspn optimized with SSE2. + Copyright (C) 2017 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 + . */ + +#if IS_IN (libc) + +# include +# define strcspn __strcspn_sse2 + +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(strcspn) +#endif + +#include diff --git a/sysdeps/x86_64/multiarch/strcspn.S b/sysdeps/x86_64/multiarch/strcspn.S deleted file mode 100644 index d102c7e80b..0000000000 --- a/sysdeps/x86_64/multiarch/strcspn.S +++ /dev/null @@ -1,69 +0,0 @@ -/* Multiple versions of strcspn - All versions must be listed in ifunc-impl-list.c. - Copyright (C) 2009-2017 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 - . */ - -#include -#include -#include - -#ifdef USE_AS_STRPBRK -#define STRCSPN_SSE42 __strpbrk_sse42 -#define STRCSPN_SSE2 __strpbrk_sse2 -#define __GI_STRCSPN __GI_strpbrk -#else -#ifndef STRCSPN -#define STRCSPN strcspn -#define STRCSPN_SSE42 __strcspn_sse42 -#define STRCSPN_SSE2 __strcspn_sse2 -#define __GI_STRCSPN __GI_strcspn -#endif -#endif - -/* Define multiple versions only for the definition in libc. Don't - define multiple versions for strpbrk in static library since we - need strpbrk before the initialization happened. */ -#if (defined SHARED || !defined USE_AS_STRPBRK) && IS_IN (libc) - .text -ENTRY(STRCSPN) - .type STRCSPN, @gnu_indirect_function - LOAD_RTLD_GLOBAL_RO_RDX - leaq STRCSPN_SSE2(%rip), %rax - HAS_CPU_FEATURE (SSE4_2) - jz 2f - leaq STRCSPN_SSE42(%rip), %rax -2: ret -END(STRCSPN) - -# undef ENTRY -# define ENTRY(name) \ - .type STRCSPN_SSE2, @function; \ - .globl STRCSPN_SSE2; \ - .align 16; \ - STRCSPN_SSE2: cfi_startproc; \ - CALL_MCOUNT -# undef END -# define END(name) \ - cfi_endproc; .size STRCSPN_SSE2, .-STRCSPN_SSE2 -#endif - -#ifdef USE_AS_STRPBRK -#include "../strpbrk.S" -#else -#include "../strcspn.S" -#endif diff --git a/sysdeps/x86_64/multiarch/strspn.S b/sysdeps/x86_64/multiarch/strcspn.c similarity index 57% rename from sysdeps/x86_64/multiarch/strspn.S rename to sysdeps/x86_64/multiarch/strcspn.c index adf7d9e533..011f69aa9c 100644 --- a/sysdeps/x86_64/multiarch/strspn.S +++ b/sysdeps/x86_64/multiarch/strcspn.c @@ -1,7 +1,6 @@ -/* Multiple versions of strspn +/* Multiple versions of strcspn. All versions must be listed in ifunc-impl-list.c. - Copyright (C) 2009-2017 Free Software Foundation, Inc. - Contributed by Intel Corporation. + Copyright (C) 2017 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -18,33 +17,20 @@ License along with the GNU C Library; if not, see . */ -#include -#include -#include - /* Define multiple versions only for the definition in libc. */ #if IS_IN (libc) - .text -ENTRY(strspn) - .type strspn, @gnu_indirect_function - LOAD_RTLD_GLOBAL_RO_RDX - leaq __strspn_sse2(%rip), %rax - HAS_CPU_FEATURE (SSE4_2) - jz 2f - leaq __strspn_sse42(%rip), %rax -2: ret -END(strspn) +# define _HAVE_STRING_ARCH_strcspn 1 +# define strcspn __redirect_strcspn +# include +# undef strcspn -# undef ENTRY -# define ENTRY(name) \ - .type __strspn_sse2, @function; \ - .globl __strspn_sse2; \ - .align 16; \ - __strspn_sse2: cfi_startproc; \ - CALL_MCOUNT -# undef END -# define END(name) \ - cfi_endproc; .size __strspn_sse2, .-__strspn_sse2 +# define SYMBOL_NAME strcspn +# include "ifunc-sse4_2.h" + +libc_ifunc_redirected (__redirect_strcspn, strcspn, IFUNC_SELECTOR ()); + +# ifdef SHARED +__hidden_ver1 (strcspn, __GI_strcspn, __redirect_strcspn) + __attribute__ ((visibility ("hidden"))); +# endif #endif - -#include "../strspn.S" diff --git a/sysdeps/x86_64/multiarch/strpbrk-c.c b/sysdeps/x86_64/multiarch/strpbrk-c.c index bbf5c49d89..c58dcb5605 100644 --- a/sysdeps/x86_64/multiarch/strpbrk-c.c +++ b/sysdeps/x86_64/multiarch/strpbrk-c.c @@ -1,8 +1,4 @@ -/* Don't define multiple versions for strpbrk in static library since we - need strpbrk before the initialization happened. */ -#ifdef SHARED -# define USE_AS_STRPBRK -# define STRCSPN_SSE2 __strpbrk_sse2 -# define STRCSPN_SSE42 __strpbrk_sse42 -# include "strcspn-c.c" -#endif +#define USE_AS_STRPBRK +#define STRCSPN_SSE2 __strpbrk_sse2 +#define STRCSPN_SSE42 __strpbrk_sse42 +#include "strcspn-c.c" diff --git a/sysdeps/x86_64/multiarch/strpbrk-sse2.S b/sysdeps/x86_64/multiarch/strpbrk-sse2.S new file mode 100644 index 0000000000..d2efe7d84e --- /dev/null +++ b/sysdeps/x86_64/multiarch/strpbrk-sse2.S @@ -0,0 +1,29 @@ +/* strpbrk optimized with SSE2. + Copyright (C) 2017 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 + . */ + +#if IS_IN (libc) + +# include +# define strcspn __strpbrk_sse2 + +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(strpbrk) +#endif + +#define USE_AS_STRPBRK +#include diff --git a/sysdeps/x86_64/multiarch/strpbrk.S b/sysdeps/x86_64/multiarch/strpbrk.S deleted file mode 100644 index 7201d6376f..0000000000 --- a/sysdeps/x86_64/multiarch/strpbrk.S +++ /dev/null @@ -1,5 +0,0 @@ -/* Multiple versions of strpbrk - All versions must be listed in ifunc-impl-list.c. */ -#define STRCSPN strpbrk -#define USE_AS_STRPBRK -#include "strcspn.S" diff --git a/sysdeps/x86_64/multiarch/strpbrk.c b/sysdeps/x86_64/multiarch/strpbrk.c new file mode 100644 index 0000000000..65453df498 --- /dev/null +++ b/sysdeps/x86_64/multiarch/strpbrk.c @@ -0,0 +1,36 @@ +/* Multiple versions of strpbrk. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2017 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 + . */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define _HAVE_STRING_ARCH_strpbrk 1 +# define strpbrk __redirect_strpbrk +# include +# undef strpbrk + +# define SYMBOL_NAME strpbrk +# include "ifunc-sse4_2.h" + +libc_ifunc_redirected (__redirect_strpbrk, strpbrk, IFUNC_SELECTOR ()); + +# ifdef SHARED +__hidden_ver1 (strpbrk, __GI_strpbrk, __redirect_strpbrk) + __attribute__ ((visibility ("hidden"))); +# endif +#endif diff --git a/sysdeps/x86_64/multiarch/strspn-sse2.S b/sysdeps/x86_64/multiarch/strspn-sse2.S new file mode 100644 index 0000000000..9bc5bff2bf --- /dev/null +++ b/sysdeps/x86_64/multiarch/strspn-sse2.S @@ -0,0 +1,28 @@ +/* strspn optimized with SSE2. + Copyright (C) 2017 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 + . */ + +#if IS_IN (libc) + +# include +# define strspn __strspn_sse2 + +# undef libc_hidden_builtin_def +# define libc_hidden_builtin_def(strspn) +#endif + +#include diff --git a/sysdeps/x86_64/multiarch/strspn.c b/sysdeps/x86_64/multiarch/strspn.c new file mode 100644 index 0000000000..942e07ae56 --- /dev/null +++ b/sysdeps/x86_64/multiarch/strspn.c @@ -0,0 +1,36 @@ +/* Multiple versions of strspn. + All versions must be listed in ifunc-impl-list.c. + Copyright (C) 2017 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 + . */ + +/* Define multiple versions only for the definition in libc. */ +#if IS_IN (libc) +# define _HAVE_STRING_ARCH_strspn 1 +# define strspn __redirect_strspn +# include +# undef strspn + +# define SYMBOL_NAME strspn +# include "ifunc-sse4_2.h" + +libc_ifunc_redirected (__redirect_strspn, strspn, IFUNC_SELECTOR ()); + +# ifdef SHARED +__hidden_ver1 (strspn, __GI_strspn, __redirect_strspn) + __attribute__ ((visibility ("hidden"))); +# endif +#endif diff --git a/sysdeps/x86_64/strcspn.S b/sysdeps/x86_64/strcspn.S index a1d1f7dfba..e450a1e856 100644 --- a/sysdeps/x86_64/strcspn.S +++ b/sysdeps/x86_64/strcspn.S @@ -24,9 +24,6 @@ #include #include "asm-syntax.h" -/* BEWARE: `#ifdef strcspn' means that strcspn is redefined as `strpbrk' */ -#define STRPBRK_P (defined strcspn) - .text ENTRY (strcspn) @@ -111,7 +108,7 @@ L(5): incq %rax L(4): addq $256, %rsp /* remove skipset */ cfi_adjust_cfa_offset(-256) -#if STRPBRK_P +#ifdef USE_AS_STRPBRK xorl %edx,%edx orb %cl, %cl /* was last character NUL? */ cmovzq %rdx, %rax /* Yes: return NULL */ diff --git a/sysdeps/x86_64/strpbrk.S b/sysdeps/x86_64/strpbrk.S index 9b97ada84e..21888a5b92 100644 --- a/sysdeps/x86_64/strpbrk.S +++ b/sysdeps/x86_64/strpbrk.S @@ -1,2 +1,3 @@ #define strcspn strpbrk +#define USE_AS_STRPBRK #include