]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libc/string/x86_64/strcspn.S
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libc / string / x86_64 / strcspn.S
1 /* strcspn (str, ss) -- Return the length of the initial segment of STR
2                         which contains no characters from SS.
3    For AMD x86-64.
4    Copyright (C) 1994-1997, 2000, 2002, 2003, 2004, 2005
5    Free Software Foundation, Inc.
6    This file is part of the GNU C Library.
7    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>.
8    Bug fixes by Alan Modra <Alan@SPRI.Levels.UniSA.Edu.Au>.
9    Adopted for x86-64 by Andreas Jaeger <aj@suse.de>.
10
11    The GNU C Library is free software; you can redistribute it and/or
12    modify it under the terms of the GNU Lesser General Public
13    License as published by the Free Software Foundation; either
14    version 2.1 of the License, or (at your option) any later version.
15
16    The GNU C Library is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    Lesser General Public License for more details.
20
21    You should have received a copy of the GNU Lesser General Public
22    License along with the GNU C Library; if not, see
23    <http://www.gnu.org/licenses/>.  */
24
25 #include "_glibc_inc.h"
26
27 /* Seems to be unrolled too much */
28
29 /* BEWARE: `#ifdef strcspn' means that strcspn is redefined as `strpbrk' */
30 #define STRPBRK_P (defined strcspn)
31
32         .text
33 ENTRY (strcspn)
34
35         movq %rdi, %rdx         /* Save SRC.  */
36
37         /* First we create a table with flags for all possible characters.
38            For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
39            supported by the C string functions we have 256 characters.
40            Before inserting marks for the stop characters we clear the whole
41            table.  */
42         movq %rdi, %r8                  /* Save value.  */
43         subq $256, %rsp                 /* Make space for 256 bytes.  */
44         movl $32,  %ecx                 /* 32*8 bytes = 256 bytes.  */
45         movq %rsp, %rdi
46         xorl %eax, %eax                 /* We store 0s.  */
47         cld
48         rep
49         stosq
50
51         movq %rsi, %rax                 /* Setup skipset.  */
52
53 /* For understanding the following code remember that %rcx == 0 now.
54    Although all the following instruction only modify %cl we always
55    have a correct zero-extended 64-bit value in %rcx.  */
56
57         /* Next 3 insns are 6 bytes total, make sure we decode them in one go */
58         .p2align 3,,6
59
60 L(2):   movb (%rax), %cl        /* get byte from skipset */
61         testb %cl, %cl          /* is NUL char? */
62         jz L(1)                 /* yes => start compare loop */
63         movb %cl, (%rsp,%rcx)   /* set corresponding byte in skipset table */
64
65         movb 1(%rax), %cl       /* get byte from skipset */
66         testb %cl, %cl          /* is NUL char? */
67         jz L(1)                 /* yes => start compare loop */
68         movb %cl, (%rsp,%rcx)   /* set corresponding byte in skipset table */
69
70         movb 2(%rax), %cl       /* get byte from skipset */
71         testb %cl, %cl          /* is NUL char? */
72         jz L(1)                 /* yes => start compare loop */
73         movb %cl, (%rsp,%rcx)   /* set corresponding byte in skipset table */
74
75         movb 3(%rax), %cl       /* get byte from skipset */
76         addq $4, %rax           /* increment skipset pointer */
77         movb %cl, (%rsp,%rcx)   /* set corresponding byte in skipset table */
78         testb %cl, %cl          /* is NUL char? */
79         jnz L(2)                /* no => process next dword from skipset */
80
81 L(1):   leaq -4(%rdx), %rax     /* prepare loop */
82
83         /* We use a neat trick for the following loop.  Normally we would
84            have to test for two termination conditions
85            1. a character in the skipset was found
86            and
87            2. the end of the string was found
88            But as a sign that the character is in the skipset we store its
89            value in the table.  But the value of NUL is NUL so the loop
90            terminates for NUL in every case.  */
91
92         /* Next 3 insns are 9 bytes total. */
93         /* .p2align 4,,9 would make sure we decode them in one go, */
94         /* but it will also align entire function to 16 bytes, */
95         /* potentially creating largish padding at link time. */
96         /* We are aligning to 8 bytes instead: */
97         .p2align 3,,8
98
99 L(3):   addq $4, %rax           /* adjust pointer for full loop round */
100
101         movb (%rax), %cl        /* get byte from string */
102         cmpb %cl, (%rsp,%rcx)   /* is it contained in skipset? */
103         je L(4)                 /* yes => return */
104
105         movb 1(%rax), %cl       /* get byte from string */
106         cmpb %cl, (%rsp,%rcx)   /* is it contained in skipset? */
107         je L(5)                 /* yes => return */
108
109         movb 2(%rax), %cl       /* get byte from string */
110         cmpb %cl, (%rsp,%rcx)   /* is it contained in skipset? */
111         jz L(6)                 /* yes => return */
112
113         movb 3(%rax), %cl       /* get byte from string */
114         cmpb %cl, (%rsp,%rcx)   /* is it contained in skipset? */
115         jne L(3)                /* no => start loop again */
116
117         incq %rax               /* adjust pointer */
118 L(6):   incq %rax
119 L(5):   incq %rax
120
121 L(4):   addq $256, %rsp         /* remove skipset */
122 #if STRPBRK_P
123         xorl %edx,%edx
124         orb %cl, %cl            /* was last character NUL? */
125         cmovzq %rdx, %rax       /* Yes: return NULL */
126 #else   
127         subq %rdx, %rax         /* we have to return the number of valid
128                                    characters, so compute distance to first
129                                    non-valid character */
130 #endif
131         ret
132 END (strcspn)
133
134 #if !STRPBRK_P
135 libc_hidden_def(strcspn)
136 #endif