Optimized memchr, memrchr, rawmemchr for x86-32
[platform/upstream/glibc.git] / sysdeps / i386 / i686 / multiarch / rawmemchr.S
1 /* Multiple versions of rawmemchr
2    Copyright (C) 2011 Free Software Foundation, Inc.
3    Contributed by Intel Corporation.
4    This file is part of the GNU C Library.
5
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.
10
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.
15
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.  */
20
21 #include <sysdep.h>
22 #include <init-arch.h>
23
24 #ifndef  NOT_IN_libc
25         .section        .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
26         .globl  __i686.get_pc_thunk.bx
27         .hidden __i686.get_pc_thunk.bx
28         .p2align 4
29         .type   __i686.get_pc_thunk.bx,@function
30 __i686.get_pc_thunk.bx:
31         movl    (%esp), %ebx
32         ret
33
34 # define CFI_POP(REG) \
35         cfi_adjust_cfa_offset (-4); \
36         cfi_restore (REG)
37
38 # define CFI_PUSH(REG) \
39         cfi_adjust_cfa_offset (4); \
40         cfi_rel_offset (REG, 0)
41
42         .text
43 ENTRY(__rawmemchr)
44         .type   __rawmemchr, @gnu_indirect_function
45         pushl   %ebx
46         CFI_PUSH (%ebx)
47         call    __i686.get_pc_thunk.bx
48         addl    $_GLOBAL_OFFSET_TABLE_, %ebx
49         cmpl    $0, KIND_OFFSET+__cpu_features@GOTOFF(%ebx)
50         jne     1f
51         call    __init_cpu_features
52
53 1:      testl   $bit_SSE2, CPUID_OFFSET+index_SSE2+__cpu_features@GOTOFF(%ebx)
54         jz      2f
55         testl   $bit_Slow_BSF, FEATURE_OFFSET+index_Slow_BSF+__cpu_features@GOTOFF(%ebx)
56         jz      3f
57
58         leal    __rawmemchr_sse2@GOTOFF(%ebx), %eax
59         popl    %ebx
60         CFI_POP (%ebx)
61         ret
62
63         CFI_PUSH (%ebx)
64
65 2:      leal    __rawmemchr_ia32@GOTOFF(%ebx), %eax
66         popl    %ebx
67         CFI_POP (%ebx)
68         ret
69
70         CFI_PUSH (%ebx)
71
72 3:      leal    __rawmemchr_sse2_bsf@GOTOFF(%ebx), %eax
73         popl    %ebx
74         CFI_POP (%ebx)
75         ret
76 END(__rawmemchr)
77
78 weak_alias(__rawmemchr, rawmemchr)
79
80 # undef ENTRY
81 # define ENTRY(name) \
82         .type __rawmemchr_ia32, @function; \
83         .globl __rawmemchr_ia32; \
84         .p2align 4; \
85         __rawmemchr_ia32: cfi_startproc; \
86         CALL_MCOUNT
87 # undef END
88 # define END(name) \
89         cfi_endproc; .size __rawmemchr_ia32, .-__rawmemchr_ia32
90
91 # undef libc_hidden_def
92 /* IFUNC doesn't work with the hidden functions in shared library since
93    they will be called without setting up EBX needed for PLT which is
94    used by IFUNC.  */
95 # define libc_hidden_def(name) \
96         .globl __GI___rawmemchr; __GI___rawmemchr = __rawmemchr_ia32
97
98 #endif
99 #include "../../rawmemchr.S"