Add optimized x86-64 implementation of strnlen.
[glibc.git] / sysdeps / x86_64 / strnlen.S
blob939782d3f8cdb2d95779f1eff9193bff54791f83
1 /* strnlen(str,maxlen) -- determine the length of the string STR up to MAXLEN.
2    Copyright (C) 2010 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>
24         .text
25 ENTRY(__strnlen)
26         movq    %rsi, %rax
27         testq   %rsi, %rsi
28         jz      3f
29         pxor    %xmm2, %xmm2
30         movq    %rdi, %rcx
31         movq    %rdi, %r8
32         movq    $16, %r9
33         andq    $~15, %rdi
34         movdqa  %xmm2, %xmm1
35         pcmpeqb (%rdi), %xmm2
36         orl     $0xffffffff, %r10d
37         subq    %rdi, %rcx
38         shll    %cl, %r10d
39         subq    %rcx, %r9
40         pmovmskb %xmm2, %edx
41         andl    %r10d, %edx
42         jnz     1f
43         subq    %r9, %rsi
44         jbe     3f
46 2:      movdqa  16(%rdi), %xmm0
47         leaq    16(%rdi), %rdi
48         pcmpeqb %xmm1, %xmm0
49         pmovmskb %xmm0, %edx
50         testl   %edx, %edx
51         jnz     1f
52         subq    $16, %rsi
53         jnbe    2b
54 3:      ret
56 1:      subq    %r8, %rdi
57         bsfl    %edx, %edx
58         addq    %rdi, %rdx
59         cmpq    %rdx, %rax
60         cmovnbq %rdx, %rax
61         ret
62 END(__strnlen)
63 weak_alias (__strnlen, strnlen)
64 libc_hidden_def (strnlen)