32bit memcmp/strcmp/strncmp optimized for SSSE3/SSS4.2
[glibc.git] / sysdeps / i386 / i686 / multiarch / strcmp.S
blob79a1fdfd43cc9461fd150652a7f6ed5e093db6eb
1 /* Multiple versions of strcmp
2    Copyright (C) 2010 Free Software Foundation, Inc.
3    Contributed by Intel Corporation.
4    This file is part of the GNU C Library.
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
21 #include <sysdep.h>
22 #include <init-arch.h>
24 #ifndef USE_AS_STRNCMP
25 # define STRCMP                 strcmp
26 # define __GI_STRCMP            __GI_strcmp
27 # define __STRCMP_IA32          __strcmp_ia32
28 # define __STRCMP_SSSE3         __strcmp_ssse3
29 # define __STRCMP_SSE4_2        __strcmp_sse4_2
30 #else
31 # define STRCMP                 strncmp
32 # define __GI_STRCMP            __GI_strncmp
33 # define __STRCMP_IA32          __strncmp_ia32
34 # define __STRCMP_SSSE3         __strncmp_ssse3
35 # define __STRCMP_SSE4_2        __strncmp_sse4_2
36 #endif
38 /* Define multiple versions only for the definition in libc.  Don't
39    define multiple versions for strncmp in static library since we
40    need strncmp before the initialization happened.  */
41 #if (defined SHARED || !defined USE_AS_STRNCMP) && !defined NOT_IN_libc
42 # ifdef SHARED
43         .section        .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
44         .globl  __i686.get_pc_thunk.bx
45         .hidden __i686.get_pc_thunk.bx
46         .p2align 4
47         .type   __i686.get_pc_thunk.bx,@function
48 __i686.get_pc_thunk.bx:
49         movl    (%esp), %ebx
50         ret
52         .text
53 ENTRY(STRCMP)
54         .type   STRCMP, @gnu_indirect_function
55         pushl   %ebx
56         cfi_adjust_cfa_offset (4)
57         cfi_rel_offset (ebx, 0)
58         call    __i686.get_pc_thunk.bx
59         addl    $_GLOBAL_OFFSET_TABLE_, %ebx
60         cmpl    $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx)
61         jne     1f
62         call    __init_cpu_features
63 1:      leal    __STRCMP_IA32@GOTOFF(%ebx), %eax
64         testl   $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features@GOTOFF(%ebx)
65         jz      2f
66         leal    __STRCMP_SSSE3@GOTOFF(%ebx), %eax
67         testl   $bit_SSE4_2, CPUID_OFFSET+index_SSE4_2+__cpu_features@GOTOFF(%ebx)
68         jz      2f
69         leal    __STRCMP_SSE4_2@GOTOFF(%ebx), %eax
70 2:      popl    %ebx
71         cfi_adjust_cfa_offset (-4)
72         cfi_restore (ebx)
73         ret
74 END(STRCMP)
75 # else
76         .text
77 ENTRY(STRCMP)
78         .type   STRCMP, @gnu_indirect_function
79         cmpl    $0, KIND_OFFSET+__cpu_features
80         jne     1f
81         call    __init_cpu_features
82 1:      leal    __STRCMP_IA32, %eax
83         testl   $bit_SSSE3, CPUID_OFFSET+index_SSSE3+__cpu_features
84         jz      2f
85         leal    __STRCMP_SSSE3, %eax
86         testl   $bit_SSE4_2, FEATURE_OFFSET+index_SSE4_2+__cpu_features
87         jz      2f
88         leal    __STRCMP_SSE4_2, %eax
89 2:      ret
90 END(STRCMP)
91 # endif
93 # undef ENTRY
94 # define ENTRY(name) \
95         .type __STRCMP_IA32, @function; \
96         .p2align 4; \
97         __STRCMP_IA32: cfi_startproc; \
98         CALL_MCOUNT
99 # undef END
100 # define END(name) \
101         cfi_endproc; .size __STRCMP_IA32, .-__STRCMP_IA32
103 # ifdef SHARED
104 #  undef libc_hidden_builtin_def
105 /* IFUNC doesn't work with the hidden functions in shared library since
106    they will be called without setting up EBX needed for PLT which is
107    used by IFUNC.  */
108 #  define libc_hidden_builtin_def(name) \
109         .globl __GI_STRCMP; __GI_STRCMP = __STRCMP_IA32
110 # endif
111 #endif
113 #ifndef USE_AS_STRNCMP
114 # include "../strcmp.S"
115 #endif