SSSE3 optimized strcasecmp and strncasecmp for x86-32

This commit is contained in:
Ulrich Drepper 2011-11-13 09:50:13 -05:00
parent 7edb22eff5
commit 76e3966e9e
15 changed files with 1087 additions and 273 deletions

View File

@ -1,3 +1,25 @@
2011-11-13 Ulrich Drepper <drepper@gmail.com>
* sysdeps/i386/i686/multiarch/Makefile [subdir=string]: Add
locale-defines.sym to gen-as-const-headers.
(sysdep_routines): Add strcasecmp_l-c, strcasecmp-c,
strcasecmp_l-ssse3, strncase_l-c, strncase-c, and strncase_l-ssse3.
* sysdeps/i386/i686/multiarch/strcmp-ssse3.S: Change to allow reuse
to compile strcasecmp and strncasecmp.
* sysdeps/i386/i686/multiarch/strcmp.S: Allow to use for
strcasecmp_l and strncasecmp_l.
* sysdeps/i386/i686/multiarch/locale-defines.sym: New file.
* sysdeps/i386/i686/multiarch/strcasecmp-c.c: New file.
* sysdeps/i386/i686/multiarch/strcasecmp.S: New file.
* sysdeps/i386/i686/multiarch/strcasecmp_l-c.c: New file.
* sysdeps/i386/i686/multiarch/strcasecmp_l-ssse3.S: New file.
* sysdeps/i386/i686/multiarch/strcasecmp_l.S: New file.
* sysdeps/i386/i686/multiarch/strncase-c.c: New file.
* sysdeps/i386/i686/multiarch/strncase.S: New file.
* sysdeps/i386/i686/multiarch/strncase_l-c.c: New file.
* sysdeps/i386/i686/multiarch/strncase_l-ssse3.S: New file.
* sysdeps/i386/i686/multiarch/strncase_l.S: New file.
2011-11-12 Ulrich Drepper <drepper@gmail.com> 2011-11-12 Ulrich Drepper <drepper@gmail.com>
* sysdeps/unix/clock_gettime.c (clock_gettime): No need to assign * sysdeps/unix/clock_gettime.c (clock_gettime): No need to assign

View File

@ -4,6 +4,7 @@ gen-as-const-headers += ifunc-defines.sym
endif endif
ifeq ($(subdir),string) ifeq ($(subdir),string)
gen-as-const-headers += locale-defines.sym
sysdep_routines += bzero-sse2 memset-sse2 memcpy-ssse3 mempcpy-ssse3 \ sysdep_routines += bzero-sse2 memset-sse2 memcpy-ssse3 mempcpy-ssse3 \
memmove-ssse3 memcpy-ssse3-rep mempcpy-ssse3-rep \ memmove-ssse3 memcpy-ssse3-rep mempcpy-ssse3-rep \
memmove-ssse3-rep bcopy-ssse3 bcopy-ssse3-rep \ memmove-ssse3-rep bcopy-ssse3 bcopy-ssse3-rep \
@ -18,7 +19,9 @@ sysdep_routines += bzero-sse2 memset-sse2 memcpy-ssse3 mempcpy-ssse3 \
memchr-sse2 memchr-sse2-bsf \ memchr-sse2 memchr-sse2-bsf \
memrchr-sse2 memrchr-sse2-bsf memrchr-c \ memrchr-sse2 memrchr-sse2-bsf memrchr-c \
rawmemchr-sse2 rawmemchr-sse2-bsf \ rawmemchr-sse2 rawmemchr-sse2-bsf \
strnlen-sse2 strnlen-c strnlen-sse2 strnlen-c \
strcasecmp_l-c strcasecmp-c strcasecmp_l-ssse3 \
strncase_l-c strncase-c strncase_l-ssse3
ifeq (yes,$(config-cflags-sse4)) ifeq (yes,$(config-cflags-sse4))
sysdep_routines += strcspn-c strpbrk-c strspn-c strstr-c strcasestr-c sysdep_routines += strcspn-c strpbrk-c strspn-c strstr-c strcasestr-c
CFLAGS-varshift.c += -msse4 CFLAGS-varshift.c += -msse4

View File

@ -0,0 +1,11 @@
#include <locale/localeinfo.h>
#include <langinfo.h>
#include <stddef.h>
--
LOCALE_T___LOCALES offsetof (struct __locale_struct, __locales)
LC_CTYPE
_NL_CTYPE_NONASCII_CASE
LOCALE_DATA_VALUES offsetof (struct __locale_data, values)
SIZEOF_VALUES sizeof (((struct __locale_data *) 0)->values[0])

View File

@ -0,0 +1,12 @@
#include <string.h>
extern __typeof (strcasecmp) __strcasecmp_nonascii;
#define __strcasecmp __strcasecmp_nonascii
#include <string/strcasecmp.c>
strong_alias (__strcasecmp_nonascii, __strcasecmp_ia32)
/* The needs of strcasecmp in libc are minimal, no need to go through
the IFUNC. */
strong_alias (__strcasecmp_nonascii, __GI___strcasecmp)

View File

@ -0,0 +1,71 @@
/* Entry point for multi-version x86 strcasecmp.
Copyright (C) 2011 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, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <sysdep.h>
#include <init-arch.h>
#ifdef SHARED
.text
ENTRY(__strcasecmp)
.type __strcasecmp, @gnu_indirect_function
pushl %ebx
cfi_adjust_cfa_offset (4)
cfi_rel_offset (ebx, 0)
call __i686.get_pc_thunk.bx
addl $_GLOBAL_OFFSET_TABLE_, %ebx
cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx)
jne 1f
call __init_cpu_features
1: leal __strcasecmp_ia32@GOTOFF(%ebx), %eax
testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx)
jz 2f
leal __strcasecmp_ssse3@GOTOFF(%ebx), %eax
#if 0
// XXX Temporarily
testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features@GOTOFF(%ebx)
jz 2f
leal __strcasecmp_sse4_2@GOTOFF(%ebx), %eax
#endif
2: popl %ebx
cfi_adjust_cfa_offset (-4)
cfi_restore (ebx)
ret
END(__strcasecmp)
#else
.text
ENTRY(__strcasecmp)
.type __strcasecmp, @gnu_indirect_function
cmpl $0, KIND_OFFSET+__cpu_features
jne 1f
call __init_cpu_features
1: leal __strcasecmp_ia32, %eax
testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features
jz 2f
leal __strcasecmp_ssse3, %eax
#if 0
// XXX Temporarily
testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features
jz 2f
leal __strcasecmp_sse4_2, %eax
#endif
2: ret
END(__strcasecmp)
#endif
weak_alias (__strcasecmp, strcasecmp)

View File

@ -0,0 +1,11 @@
#include <string.h>
extern __typeof (strcasecmp_l) __strcasecmp_l_nonascii;
#define __strcasecmp_l __strcasecmp_l_nonascii
#define USE_IN_EXTENDED_LOCALE_MODEL 1
#include <string/strcasecmp.c>
/* The needs of strcasecmp in libc are minimal, no need to go through
the IFUNC. */
strong_alias (__strcasecmp_l_nonascii, __GI___strcasecmp_l)

View File

@ -0,0 +1,2 @@
#define USE_AS_STRCASECMP_L 1
#include "strcmp-ssse3.S"

View File

@ -0,0 +1,5 @@
#define STRCMP __strcasecmp_l
#define USE_AS_STRCASECMP_L
#include "strcmp.S"
weak_alias (__strcasecmp_l, strcasecmp_l)

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* Multiple versions of strcmp /* Multiple versions of strcmp
Copyright (C) 2010 Free Software Foundation, Inc. Copyright (C) 2010, 2011 Free Software Foundation, Inc.
Contributed by Intel Corporation. Contributed by Intel Corporation.
This file is part of the GNU C Library. This file is part of the GNU C Library.
@ -21,18 +21,30 @@
#include <sysdep.h> #include <sysdep.h>
#include <init-arch.h> #include <init-arch.h>
#ifndef USE_AS_STRNCMP #ifdef USE_AS_STRNCMP
# define STRCMP strcmp
# define __GI_STRCMP __GI_strcmp
# define __STRCMP_IA32 __strcmp_ia32
# define __STRCMP_SSSE3 __strcmp_ssse3
# define __STRCMP_SSE4_2 __strcmp_sse4_2
#else
# define STRCMP strncmp # define STRCMP strncmp
# define __GI_STRCMP __GI_strncmp # define __GI_STRCMP __GI_strncmp
# define __STRCMP_IA32 __strncmp_ia32 # define __STRCMP_IA32 __strncmp_ia32
# define __STRCMP_SSSE3 __strncmp_ssse3 # define __STRCMP_SSSE3 __strncmp_ssse3
# define __STRCMP_SSE4_2 __strncmp_sse4_2 # define __STRCMP_SSE4_2 __strncmp_sse4_2
#elif defined USE_AS_STRCASECMP_L
# define STRCMP __strcasecmp_l
# define __GI_STRCMP __GI_strcasecmp_l
# define __STRCMP_IA32 __strcasecmp_l_ia32
# define __STRCMP_SSSE3 __strcasecmp_l_ssse3
# define __STRCMP_SSE4_2 __strcasecmp_l_sse4_2
#elif defined USE_AS_STRNCASECMP_L
# define STRCMP __strncasecmp_l
# define __GI_STRCMP __GI_strncasecmp_l
# define __STRCMP_IA32 __strncasecmp_l_ia32
# define __STRCMP_SSSE3 __strncasecmp_l_ssse3
# define __STRCMP_SSE4_2 __strncasecmp_l_sse4_2
#else
# define STRCMP strcmp
# define __GI_STRCMP __GI_strcmp
# define __STRCMP_IA32 __strcmp_ia32
# define __STRCMP_SSSE3 __strcmp_ssse3
# define __STRCMP_SSE4_2 __strcmp_sse4_2
#endif #endif
/* Define multiple versions only for the definition in libc. Don't /* Define multiple versions only for the definition in libc. Don't
@ -64,9 +76,12 @@ ENTRY(STRCMP)
testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx) testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx)
jz 2f jz 2f
leal __STRCMP_SSSE3@GOTOFF(%ebx), %eax leal __STRCMP_SSSE3@GOTOFF(%ebx), %eax
#if 0
// XXX Temporarily
testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features@GOTOFF(%ebx) testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features@GOTOFF(%ebx)
jz 2f jz 2f
leal __STRCMP_SSE4_2@GOTOFF(%ebx), %eax leal __STRCMP_SSE4_2@GOTOFF(%ebx), %eax
#endif
2: popl %ebx 2: popl %ebx
cfi_adjust_cfa_offset (-4) cfi_adjust_cfa_offset (-4)
cfi_restore (ebx) cfi_restore (ebx)
@ -83,9 +98,12 @@ ENTRY(STRCMP)
testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features
jz 2f jz 2f
leal __STRCMP_SSSE3, %eax leal __STRCMP_SSSE3, %eax
#if 0
// XXX Temporarily
testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features
jz 2f jz 2f
leal __STRCMP_SSE4_2, %eax leal __STRCMP_SSE4_2, %eax
#endif
2: ret 2: ret
END(STRCMP) END(STRCMP)
# endif # endif

View File

@ -0,0 +1,8 @@
#include <string.h>
extern __typeof (strncasecmp) __strncasecmp_nonascii;
#define __strncasecmp __strncasecmp_nonascii
#include <string/strncase.c>
strong_alias (__strncasecmp_nonascii, __strncasecmp_ia32)

View File

@ -0,0 +1,71 @@
/* Entry point for multi-version x86 strncasecmp.
Copyright (C) 2011 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, write to the Free
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA. */
#include <sysdep.h>
#include <init-arch.h>
#ifdef SHARED
.text
ENTRY(__strncasecmp)
.type __strncasecmp, @gnu_indirect_function
pushl %ebx
cfi_adjust_cfa_offset (4)
cfi_rel_offset (ebx, 0)
call __i686.get_pc_thunk.bx
addl $_GLOBAL_OFFSET_TABLE_, %ebx
cmpl $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx)
jne 1f
call __init_cpu_features
1: leal __strncasecmp_ia32@GOTOFF(%ebx), %eax
testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx)
jz 2f
leal __strncasecmp_ssse3@GOTOFF(%ebx), %eax
#if 0
// XXX Temporarily
testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features@GOTOFF(%ebx)
jz 2f
leal __strncasecmp_sse4_2@GOTOFF(%ebx), %eax
#endif
2: popl %ebx
cfi_adjust_cfa_offset (-4)
cfi_restore (ebx)
ret
END(__strncasecmp)
#else
.text
ENTRY(__strncasecmp)
.type __strncasecmp, @gnu_indirect_function
cmpl $0, KIND_OFFSET+__cpu_features
jne 1f
call __init_cpu_features
1: leal __strncasecmp_ia32, %eax
testl $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features
jz 2f
leal __strncasecmp_ssse3, %eax
#if 0
// XXX Temporarily
testl $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features
jz 2f
leal __strncasecmp_sse4_2, %eax
#endif
2: ret
END(__strncasecmp)
#endif
weak_alias (__strncasecmp, strncasecmp)

View File

@ -0,0 +1,11 @@
#include <string.h>
extern __typeof (strncasecmp_l) __strncasecmp_l_nonascii;
#define __strncasecmp_l __strncasecmp_l_nonascii
#define USE_IN_EXTENDED_LOCALE_MODEL 1
#include <string/strncase.c>
/* The needs of strcasecmp in libc are minimal, no need to go through
the IFUNC. */
strong_alias (__strncasecmp_l_nonascii, __GI___strncasecmp_l)

View File

@ -0,0 +1,2 @@
#define USE_AS_STRNCASECMP_L 1
#include "strcmp-ssse3.S"

View File

@ -0,0 +1,5 @@
#define STRCMP __strncasecmp_l
#define USE_AS_STRNCASECMP_L
#include "strcmp.S"
weak_alias (__strncasecmp_l, strncasecmp_l)