Define bit_XXX and index_XXX.
[glibc.git] / sysdeps / x86_64 / multiarch / strlen.S
blob509f9c960597f0bb4bc70002429d8e6a6993e3a5
1 /* strlen(str) -- determine the length of the string STR.
2    Copyright (C) 2009 Free Software Foundation, Inc.
3    Contributed by Ulrich Drepper <drepper@redhat.com>.
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>
25 /* Define multiple versions only for the definition in libc and for
26    the DSO.  In static binaries we need strlen before the initialization
27    happened.  */
28 #if defined SHARED && !defined NOT_IN_libc
29         .text
30 ENTRY(strlen)
31         .type   strlen, @gnu_indirect_function
32         cmpl    $0, __cpu_features+KIND_OFFSET(%rip)
33         jne     1f
34         call    __init_cpu_features
35 1:      leaq    __strlen_sse2(%rip), %rax
36         testl   $bit_SSE4_2, __cpu_features+CPUID_OFFSET+index_SSE4_2(%rip)
37         jz      2f
38         leaq    __strlen_sse42(%rip), %rax
39 2:      ret
40 END(strlen)
43         .section .text.sse4.2,"ax",@progbits
44         .align  16
45         .type   __strlen_sse42, @function
46 __strlen_sse42:
47         cfi_startproc
48         CALL_MCOUNT
49         pxor    %xmm2, %xmm2
50         movq    %rdi, %rcx
51         movq    %rdi, %r8
52         andq    $~15, %rdi
53         movdqa  %xmm2, %xmm1
54         pcmpeqb (%rdi), %xmm2
55         orl     $0xffffffff, %esi
56         subq    %rdi, %rcx
57         shll    %cl, %esi
58         pmovmskb %xmm2, %edx
59         andl    %esi, %edx
60         jnz     1f
62 2:      pcmpistri $0x08, 16(%rdi), %xmm1
63         leaq    16(%rdi), %rdi
64         jnz     2b
66         leaq    (%rdi,%rcx), %rax
67         subq    %r8, %rax
68         ret
70 1:      subq    %r8, %rdi
71         bsfl    %edx, %eax
72         addq    %rdi, %rax
73         ret
74         cfi_endproc
75         .size   __strlen_sse42, .-__strlen_sse42
78 # undef ENTRY
79 # define ENTRY(name) \
80         .type __strlen_sse2, @function; \
81         .align 16; \
82         __strlen_sse2: cfi_startproc; \
83         CALL_MCOUNT
84 # undef END
85 # define END(name) \
86         cfi_endproc; .size __strlen_sse2, .-__strlen_sse2
87 # undef libc_hidden_builtin_def
88 /* It doesn't make sense to send libc-internal strlen 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_strlen; __GI_strlen = __strlen_sse2
93 #endif
95 #include "../strlen.S"