Define bit_XXX and index_XXX.
[glibc.git] / sysdeps / x86_64 / multiarch / rawmemchr.S
blob2a8a6909efd55e7343deccfcce75a3cc0554e900
1 /* Copyright (C) 2009 Free Software Foundation, Inc.
2    Contributed by Ulrich Drepper <drepper@redhat.com>.
3    This file is part of the GNU C Library.
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
20 #include <sysdep.h>
21 #include <init-arch.h>
24 /* Define multiple versions only for the definition in lib.  */
25 #ifndef NOT_IN_libc
26         .text
27 ENTRY(rawmemchr)
28         .type   rawmemchr, @gnu_indirect_function
29         cmpl    $0, __cpu_features+KIND_OFFSET(%rip)
30         jne     1f
31         call    __init_cpu_features
32 1:      leaq    __rawmemchr_sse2(%rip), %rax
33         testl   $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip)
34         jz      2f
35         leaq    __rawmemchr_sse42(%rip), %rax
36 2:      ret
37 END(rawmemchr)
38 strong_alias (rawmemchr, __rawmemchr)
41         .section .text.sse4.2,"ax",@progbits
42         .align  16
43         .type   __rawmemchr_sse42, @function
44 __rawmemchr_sse42:
45         cfi_startproc
46         CALL_MCOUNT
47         movd    %esi, %xmm1
48         movq    %rdi, %rcx
49         punpcklbw %xmm1, %xmm1
50         andq    $~15, %rdi
51         punpcklbw %xmm1, %xmm1
52         orl     $0xffffffff, %esi
53         movdqa  (%rdi), %xmm0
54         pshufd  $0, %xmm1, %xmm1
55         subq    %rdi, %rcx
56         pcmpeqb %xmm1, %xmm0
57         shl     %cl, %esi
58         pmovmskb %xmm0, %ecx
59         movl    $16, %eax
60         movl    $16, %edx
61         andl    %esi, %ecx
62         jnz     1f
64 2:      pcmpestri $0x08, 16(%rdi), %xmm1
65         leaq    16(%rdi), %rdi
66         jnc     2b
68         leaq    (%rdi,%rcx), %rax
69         ret
71 1:      bsfl    %ecx, %eax
72         addq    %rdi, %rax
73         ret
74         cfi_endproc
75         .size   __rawmemchr_sse42, .-__rawmemchr_sse42
78 # undef ENTRY
79 # define ENTRY(name) \
80         .type __rawmemchr_sse2, @function; \
81         .align 16; \
82         __rawmemchr_sse2: cfi_startproc; \
83         CALL_MCOUNT
84 # undef END
85 # define END(name) \
86         cfi_endproc; .size __rawmemchr_sse2, .-__rawmemchr_sse2
87 # undef libc_hidden_builtin_def
88 /* It doesn't make sense to send libc-internal rawmemchr calls through a PLT.
89    The speedup we get from using SSE4.2 instruction is likely eaten away
90    by the indirect call in the PLT.  */
91 # define libc_hidden_builtin_def(name) \
92         .globl __GI___rawmemchr; __GI___rawmemchr = __rawmemchr_sse2
93 #endif
95 #include "../rawmemchr.S"