Add x86 32-bit SSE4.2 string functions.
[glibc.git] / sysdeps / i386 / i686 / multiarch / strcspn.S
blobf5ca0923406ecf527257ebdd887c635deda580f2
1 /* Multiple versions of strcspn
2    Copyright (C) 2009 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 <config.h>
23 #ifdef HAVE_SSE4_SUPPORT
25 #include <sysdep.h>
26 #include <ifunc-defines.h>
28 #ifdef USE_AS_STRPBRK
29 #define STRCSPN_SSE42   __strpbrk_sse42
30 #define STRCSPN_IA32    __strpbrk_ia32
31 #define __GI_STRCSPN    __GI_strpbrk
32 #else
33 #ifndef STRCSPN
34 #define STRCSPN         strcspn
35 #define STRCSPN_SSE42   __strcspn_sse42
36 #define STRCSPN_IA32    __strcspn_ia32
37 #define __GI_STRCSPN    __GI_strcspn
38 #endif
39 #endif
41 /* Define multiple versions only for the definition in libc.  Don't
42    define multiple versions for strpbrk in static library since we
43    need strpbrk before the initialization happened.  */
44 #if (defined SHARED || !defined USE_AS_STRPBRK) && !defined NOT_IN_libc
45         .section        .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
46         .globl  __i686.get_pc_thunk.bx
47         .hidden __i686.get_pc_thunk.bx
48         .p2align 4
49         .type   __i686.get_pc_thunk.bx,@function
50 __i686.get_pc_thunk.bx:
51         movl    (%esp), %ebx
52         ret
54         .text
55 ENTRY(STRCSPN)
56         .type   STRCSPN, @gnu_indirect_function
57         pushl   %ebx
58         cfi_adjust_cfa_offset (4)
59         cfi_rel_offset (ebx, 0)
60         call    __i686.get_pc_thunk.bx
61         addl    $_GLOBAL_OFFSET_TABLE_, %ebx
62         cmpl    $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx)
63         jne     1f
64         call    __init_cpu_features
65 1:      leal    STRCSPN_IA32@GOTOFF(%ebx), %eax
66         testl   $(1<<20), CPUID_OFFSET+COMMON_CPUID_INDEX_1*CPUID_SIZE+CPUID_ECX_OFFSET+__cpu_features@GOTOFF(%ebx)
67         jz      2f
68         leal    STRCSPN_SSE42@GOTOFF(%ebx), %eax
69 2:      popl    %ebx
70         cfi_adjust_cfa_offset (-4);
71         cfi_restore (ebx)
72         ret
73 END(STRCSPN)
75 # undef ENTRY
76 # define ENTRY(name) \
77         .type STRCSPN_IA32, @function; \
78         .globl STRCSPN_IA32; \
79         .p2align 4; \
80         STRCSPN_IA32: cfi_startproc; \
81         CALL_MCOUNT
82 # undef END
83 # define END(name) \
84         cfi_endproc; .size STRCSPN_IA32, .-STRCSPN_IA32
85 # undef libc_hidden_builtin_def
86 /* It doesn't make sense to send libc-internal strcspn calls through a PLT.
87    The speedup we get from using SSE4.2 instruction is likely eaten away
88    by the indirect call in the PLT.  */
89 # define libc_hidden_builtin_def(name) \
90         .globl __GI_STRCSPN; __GI_STRCSPN = STRCSPN_IA32
91 #endif
93 #endif /* HAVE_SSE4_SUPPORT */
95 #ifdef USE_AS_STRPBRK
96 #include "../../strpbrk.S"
97 #else
98 #include "../../strcspn.S"
99 #endif