powerpc: Update ulps
[glibc.git] / sysdeps / i386 / strpbrk.S
blob2622d813c280fa4d48e2befb6f503679dabc7f6e
1 /* strcspn (str, ss) -- Return the length of the initial segment of STR
2                         which contains no characters from SS.
3    For Intel 80x86, x>=3.
4    Copyright (C) 1994-2024 Free Software Foundation, Inc.
5    This file is part of the GNU C Library.
7    The GNU C Library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Lesser General Public
9    License as published by the Free Software Foundation; either
10    version 2.1 of the License, or (at your option) any later version.
12    The GNU C Library is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    Lesser General Public License for more details.
17    You should have received a copy of the GNU Lesser General Public
18    License along with the GNU C Library; if not, see
19    <https://www.gnu.org/licenses/>.  */
21 #include <sysdep.h>
22 #include "asm-syntax.h"
24 #define PARMS   4               /* no space for saved regs */
25 #define RTN     PARMS
26 #define STR     RTN
27 #define STOP    STR+4
29         .text
30 ENTRY (strpbrk)
32         movl STR(%esp), %edx
33         movl STOP(%esp), %eax
35         /* First we create a table with flags for all possible characters.
36            For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
37            supported by the C string functions we have 256 characters.
38            Before inserting marks for the stop characters we clear the whole
39            table.  The unrolled form is much faster than a loop.  */
40         xorl %ecx, %ecx         /* %ecx = 0 !!! */
42         pushl %ecx              /* make a 256 bytes long block filled with 0 */
43         cfi_adjust_cfa_offset (4)
44         pushl %ecx
45         cfi_adjust_cfa_offset (4)
46         pushl %ecx
47         cfi_adjust_cfa_offset (4)
48         pushl %ecx
49         cfi_adjust_cfa_offset (4)
50         pushl %ecx
51         cfi_adjust_cfa_offset (4)
52         pushl %ecx
53         cfi_adjust_cfa_offset (4)
54         pushl %ecx
55         cfi_adjust_cfa_offset (4)
56         pushl %ecx
57         cfi_adjust_cfa_offset (4)
58         pushl %ecx
59         cfi_adjust_cfa_offset (4)
60         pushl %ecx
61         cfi_adjust_cfa_offset (4)
62         pushl %ecx
63         cfi_adjust_cfa_offset (4)
64         pushl %ecx
65         cfi_adjust_cfa_offset (4)
66         pushl %ecx
67         cfi_adjust_cfa_offset (4)
68         pushl %ecx
69         cfi_adjust_cfa_offset (4)
70         pushl %ecx
71         cfi_adjust_cfa_offset (4)
72         pushl %ecx
73         cfi_adjust_cfa_offset (4)
74         pushl %ecx
75         cfi_adjust_cfa_offset (4)
76         pushl %ecx
77         cfi_adjust_cfa_offset (4)
78         pushl %ecx
79         cfi_adjust_cfa_offset (4)
80         pushl %ecx
81         cfi_adjust_cfa_offset (4)
82         pushl %ecx
83         cfi_adjust_cfa_offset (4)
84         pushl %ecx
85         cfi_adjust_cfa_offset (4)
86         pushl %ecx
87         cfi_adjust_cfa_offset (4)
88         pushl %ecx
89         cfi_adjust_cfa_offset (4)
90         pushl %ecx
91         cfi_adjust_cfa_offset (4)
92         pushl %ecx
93         cfi_adjust_cfa_offset (4)
94         pushl %ecx
95         cfi_adjust_cfa_offset (4)
96         pushl %ecx
97         cfi_adjust_cfa_offset (4)
98         pushl %ecx
99         cfi_adjust_cfa_offset (4)
100         pushl %ecx
101         cfi_adjust_cfa_offset (4)
102         pushl %ecx
103         cfi_adjust_cfa_offset (4)
104         pushl %ecx
105         cfi_adjust_cfa_offset (4)
106         pushl %ecx
107         cfi_adjust_cfa_offset (4)
108         pushl %ecx
109         cfi_adjust_cfa_offset (4)
110         pushl %ecx
111         cfi_adjust_cfa_offset (4)
112         pushl %ecx
113         cfi_adjust_cfa_offset (4)
114         pushl %ecx
115         cfi_adjust_cfa_offset (4)
116         pushl %ecx
117         cfi_adjust_cfa_offset (4)
118         pushl %ecx
119         cfi_adjust_cfa_offset (4)
120         pushl %ecx
121         cfi_adjust_cfa_offset (4)
122         pushl %ecx
123         cfi_adjust_cfa_offset (4)
124         pushl %ecx
125         cfi_adjust_cfa_offset (4)
126         pushl %ecx
127         cfi_adjust_cfa_offset (4)
128         pushl %ecx
129         cfi_adjust_cfa_offset (4)
130         pushl %ecx
131         cfi_adjust_cfa_offset (4)
132         pushl %ecx
133         cfi_adjust_cfa_offset (4)
134         pushl %ecx
135         cfi_adjust_cfa_offset (4)
136         pushl %ecx
137         cfi_adjust_cfa_offset (4)
138         pushl %ecx
139         cfi_adjust_cfa_offset (4)
140         pushl %ecx
141         cfi_adjust_cfa_offset (4)
142         pushl %ecx
143         cfi_adjust_cfa_offset (4)
144         pushl %ecx
145         cfi_adjust_cfa_offset (4)
146         pushl %ecx
147         cfi_adjust_cfa_offset (4)
148         pushl %ecx
149         cfi_adjust_cfa_offset (4)
150         pushl %ecx
151         cfi_adjust_cfa_offset (4)
152         pushl %ecx
153         cfi_adjust_cfa_offset (4)
154         pushl %ecx
155         cfi_adjust_cfa_offset (4)
156         pushl %ecx
157         cfi_adjust_cfa_offset (4)
158         pushl $0                /* These immediate values make the label 2 */
159         cfi_adjust_cfa_offset (4)
160         pushl $0                /* to be aligned on a 16 byte boundary to */
161         cfi_adjust_cfa_offset (4)
162         pushl $0                /* get a better performance of the loop.  */
163         cfi_adjust_cfa_offset (4)
164         pushl $0
165         cfi_adjust_cfa_offset (4)
166         pushl $0
167         cfi_adjust_cfa_offset (4)
168         pushl $0
169         cfi_adjust_cfa_offset (4)
171 /* For understanding the following code remember that %ecx == 0 now.
172    Although all the following instruction only modify %cl we always
173    have a correct zero-extended 32-bit value in %ecx.  */
175 /* Don't change the "testb $0xff,%%cl" to "testb %%cl,%%cl".  We want
176    longer instructions so that the next loop aligns without adding nops.  */
178 L(2):   movb (%eax), %cl        /* get byte from stopset */
179         testb %cl, %cl          /* is NUL char? */
180         jz L(1)                 /* yes => start compare loop */
181         movb %cl, (%esp,%ecx)   /* set corresponding byte in stopset table */
183         movb 1(%eax), %cl       /* get byte from stopset */
184         testb $0xff, %cl        /* is NUL char? */
185         jz L(1)                 /* yes => start compare loop */
186         movb %cl, (%esp,%ecx)   /* set corresponding byte in stopset table */
188         movb 2(%eax), %cl       /* get byte from stopset */
189         testb $0xff, %cl        /* is NUL char? */
190         jz L(1)                 /* yes => start compare loop */
191         movb %cl, (%esp,%ecx)   /* set corresponding byte in stopset table */
193         movb 3(%eax), %cl       /* get byte from stopset */
194         addl $4, %eax           /* increment stopset pointer */
195         movb %cl, (%esp,%ecx)   /* set corresponding byte in stopset table */
196         testb $0xff, %cl        /* is NUL char? */
197         jnz L(2)                /* no => process next dword from stopset */
199 L(1):   leal -4(%edx), %eax     /* prepare loop */
201         /* We use a neat trick for the following loop.  Normally we would
202            have to test for two termination conditions
203            1. a character in the stopset was found
204            and
205            2. the end of the string was found
206            But as a sign that the character is in the stopset we store its
207            value in the table.  But the value of NUL is NUL so the loop
208            terminates for NUL in every case.  */
210 L(3):   addl $4, %eax           /* adjust pointer for full loop round */
212         movb (%eax), %cl        /* get byte from string */
213         cmpb %cl, (%esp,%ecx)   /* is it contained in stopset? */
214         je L(4)                 /* yes => return */
216         movb 1(%eax), %cl       /* get byte from string */
217         cmpb %cl, (%esp,%ecx)   /* is it contained in stopset? */
218         je L(5)                 /* yes => return */
220         movb 2(%eax), %cl       /* get byte from string */
221         cmpb %cl, (%esp,%ecx)   /* is it contained in stopset? */
222         je L(6)                 /* yes => return */
224         movb 3(%eax), %cl       /* get byte from string */
225         cmpb %cl, (%esp,%ecx)   /* is it contained in stopset? */
226         jne L(3)                        /* yes => return */
228         incl %eax               /* adjust pointer */
229 L(6):   incl %eax
230 L(5):   incl %eax
232 L(4):   addl $256, %esp         /* remove stopset */
233         cfi_adjust_cfa_offset (-256)
235         orb %cl, %cl            /* was last character NUL? */
236         jnz L(7)                /* no => return pointer */
237         xorl %eax, %eax
239 L(7):   ret
240 END (strpbrk)
241 libc_hidden_builtin_def (strpbrk)