]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/i386/strpbrk.S
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / i386 / strpbrk.S
CommitLineData
8f5ca04b
RM
1/* strcspn (str, ss) -- Return the length of the initial segement of STR
2 which contains no characters from SS.
5929563f 3 For Intel 80x86, x>=3.
6d7e8eda 4 Copyright (C) 1994-2023 Free Software Foundation, Inc.
5929563f
UD
5 This file is part of the GNU C Library.
6
7 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
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.
5929563f
UD
11
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
41bdb6e2 15 Lesser General Public License for more details.
5929563f 16
41bdb6e2 17 You should have received a copy of the GNU Lesser General Public
59ba27a6 18 License along with the GNU C Library; if not, see
5a82c748 19 <https://www.gnu.org/licenses/>. */
8f5ca04b
RM
20
21#include <sysdep.h>
22#include "asm-syntax.h"
23
2366713d 24#define PARMS 4 /* no space for saved regs */
3f02f778 25#define RTN PARMS
2366713d
JM
26#define STR RTN
27#define STOP STR+4
8f5ca04b
RM
28
29 .text
2366713d 30ENTRY (strpbrk)
3f02f778
GM
31
32 movl STR(%esp), %edx
33 movl STOP(%esp), %eax
8f5ca04b
RM
34
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 !!! */
41
42 pushl %ecx /* make a 256 bytes long block filled with 0 */
1ad9da69 43 cfi_adjust_cfa_offset (4)
8f5ca04b 44 pushl %ecx
1ad9da69 45 cfi_adjust_cfa_offset (4)
8f5ca04b 46 pushl %ecx
1ad9da69 47 cfi_adjust_cfa_offset (4)
8f5ca04b 48 pushl %ecx
1ad9da69 49 cfi_adjust_cfa_offset (4)
8f5ca04b 50 pushl %ecx
1ad9da69 51 cfi_adjust_cfa_offset (4)
8f5ca04b 52 pushl %ecx
1ad9da69 53 cfi_adjust_cfa_offset (4)
8f5ca04b 54 pushl %ecx
1ad9da69 55 cfi_adjust_cfa_offset (4)
8f5ca04b 56 pushl %ecx
1ad9da69 57 cfi_adjust_cfa_offset (4)
8f5ca04b 58 pushl %ecx
1ad9da69 59 cfi_adjust_cfa_offset (4)
8f5ca04b 60 pushl %ecx
1ad9da69 61 cfi_adjust_cfa_offset (4)
8f5ca04b 62 pushl %ecx
1ad9da69 63 cfi_adjust_cfa_offset (4)
8f5ca04b 64 pushl %ecx
1ad9da69 65 cfi_adjust_cfa_offset (4)
8f5ca04b 66 pushl %ecx
1ad9da69 67 cfi_adjust_cfa_offset (4)
8f5ca04b 68 pushl %ecx
1ad9da69 69 cfi_adjust_cfa_offset (4)
8f5ca04b 70 pushl %ecx
1ad9da69 71 cfi_adjust_cfa_offset (4)
8f5ca04b 72 pushl %ecx
1ad9da69 73 cfi_adjust_cfa_offset (4)
8f5ca04b 74 pushl %ecx
1ad9da69 75 cfi_adjust_cfa_offset (4)
8f5ca04b 76 pushl %ecx
1ad9da69 77 cfi_adjust_cfa_offset (4)
8f5ca04b 78 pushl %ecx
1ad9da69 79 cfi_adjust_cfa_offset (4)
8f5ca04b 80 pushl %ecx
1ad9da69 81 cfi_adjust_cfa_offset (4)
8f5ca04b 82 pushl %ecx
1ad9da69 83 cfi_adjust_cfa_offset (4)
8f5ca04b 84 pushl %ecx
1ad9da69 85 cfi_adjust_cfa_offset (4)
8f5ca04b 86 pushl %ecx
1ad9da69 87 cfi_adjust_cfa_offset (4)
8f5ca04b 88 pushl %ecx
1ad9da69 89 cfi_adjust_cfa_offset (4)
8f5ca04b 90 pushl %ecx
1ad9da69 91 cfi_adjust_cfa_offset (4)
8f5ca04b 92 pushl %ecx
1ad9da69 93 cfi_adjust_cfa_offset (4)
8f5ca04b 94 pushl %ecx
1ad9da69 95 cfi_adjust_cfa_offset (4)
8f5ca04b 96 pushl %ecx
1ad9da69 97 cfi_adjust_cfa_offset (4)
8f5ca04b 98 pushl %ecx
1ad9da69 99 cfi_adjust_cfa_offset (4)
8f5ca04b 100 pushl %ecx
1ad9da69 101 cfi_adjust_cfa_offset (4)
8f5ca04b 102 pushl %ecx
1ad9da69 103 cfi_adjust_cfa_offset (4)
8f5ca04b 104 pushl %ecx
1ad9da69 105 cfi_adjust_cfa_offset (4)
8f5ca04b 106 pushl %ecx
1ad9da69 107 cfi_adjust_cfa_offset (4)
8f5ca04b 108 pushl %ecx
1ad9da69 109 cfi_adjust_cfa_offset (4)
8f5ca04b 110 pushl %ecx
1ad9da69 111 cfi_adjust_cfa_offset (4)
8f5ca04b 112 pushl %ecx
1ad9da69 113 cfi_adjust_cfa_offset (4)
8f5ca04b 114 pushl %ecx
1ad9da69 115 cfi_adjust_cfa_offset (4)
8f5ca04b 116 pushl %ecx
1ad9da69 117 cfi_adjust_cfa_offset (4)
8f5ca04b 118 pushl %ecx
1ad9da69 119 cfi_adjust_cfa_offset (4)
8f5ca04b 120 pushl %ecx
1ad9da69 121 cfi_adjust_cfa_offset (4)
8f5ca04b 122 pushl %ecx
1ad9da69 123 cfi_adjust_cfa_offset (4)
8f5ca04b 124 pushl %ecx
1ad9da69 125 cfi_adjust_cfa_offset (4)
8f5ca04b 126 pushl %ecx
1ad9da69 127 cfi_adjust_cfa_offset (4)
8f5ca04b 128 pushl %ecx
1ad9da69 129 cfi_adjust_cfa_offset (4)
8f5ca04b 130 pushl %ecx
1ad9da69 131 cfi_adjust_cfa_offset (4)
8f5ca04b 132 pushl %ecx
1ad9da69 133 cfi_adjust_cfa_offset (4)
8f5ca04b 134 pushl %ecx
1ad9da69 135 cfi_adjust_cfa_offset (4)
8f5ca04b 136 pushl %ecx
1ad9da69 137 cfi_adjust_cfa_offset (4)
8f5ca04b 138 pushl %ecx
1ad9da69 139 cfi_adjust_cfa_offset (4)
8f5ca04b 140 pushl %ecx
1ad9da69 141 cfi_adjust_cfa_offset (4)
8f5ca04b 142 pushl %ecx
1ad9da69 143 cfi_adjust_cfa_offset (4)
8f5ca04b 144 pushl %ecx
1ad9da69 145 cfi_adjust_cfa_offset (4)
8f5ca04b 146 pushl %ecx
1ad9da69 147 cfi_adjust_cfa_offset (4)
8f5ca04b 148 pushl %ecx
1ad9da69 149 cfi_adjust_cfa_offset (4)
8f5ca04b 150 pushl %ecx
1ad9da69 151 cfi_adjust_cfa_offset (4)
8f5ca04b 152 pushl %ecx
1ad9da69 153 cfi_adjust_cfa_offset (4)
8f5ca04b 154 pushl %ecx
1ad9da69 155 cfi_adjust_cfa_offset (4)
8f5ca04b 156 pushl %ecx
1ad9da69 157 cfi_adjust_cfa_offset (4)
8f5ca04b 158 pushl $0 /* These immediate values make the label 2 */
1ad9da69 159 cfi_adjust_cfa_offset (4)
8f5ca04b 160 pushl $0 /* to be aligned on a 16 byte boundary to */
1ad9da69 161 cfi_adjust_cfa_offset (4)
8f5ca04b 162 pushl $0 /* get a better performance of the loop. */
1ad9da69 163 cfi_adjust_cfa_offset (4)
8f5ca04b 164 pushl $0
1ad9da69 165 cfi_adjust_cfa_offset (4)
8f5ca04b 166 pushl $0
1ad9da69 167 cfi_adjust_cfa_offset (4)
8f5ca04b 168 pushl $0
1ad9da69 169 cfi_adjust_cfa_offset (4)
8f5ca04b
RM
170
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. */
174
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. */
177
5929563f 178L(2): movb (%eax), %cl /* get byte from stopset */
8f5ca04b 179 testb %cl, %cl /* is NUL char? */
5929563f 180 jz L(1) /* yes => start compare loop */
8f5ca04b
RM
181 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
182
183 movb 1(%eax), %cl /* get byte from stopset */
184 testb $0xff, %cl /* is NUL char? */
5929563f 185 jz L(1) /* yes => start compare loop */
8f5ca04b
RM
186 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
187
188 movb 2(%eax), %cl /* get byte from stopset */
189 testb $0xff, %cl /* is NUL char? */
5929563f 190 jz L(1) /* yes => start compare loop */
8f5ca04b
RM
191 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
192
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? */
5929563f 197 jnz L(2) /* no => process next dword from stopset */
8f5ca04b 198
5929563f 199L(1): leal -4(%edx), %eax /* prepare loop */
8f5ca04b
RM
200
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
382466e0 206 But as a sign that the character is in the stopset we store its
8f5ca04b
RM
207 value in the table. But the value of NUL is NUL so the loop
208 terminates for NUL in every case. */
209
5929563f 210L(3): addl $4, %eax /* adjust pointer for full loop round */
8f5ca04b
RM
211
212 movb (%eax), %cl /* get byte from string */
213 cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
5929563f 214 je L(4) /* yes => return */
8f5ca04b
RM
215
216 movb 1(%eax), %cl /* get byte from string */
217 cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
5929563f 218 je L(5) /* yes => return */
8f5ca04b
RM
219
220 movb 2(%eax), %cl /* get byte from string */
221 cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
5929563f 222 je L(6) /* yes => return */
8f5ca04b
RM
223
224 movb 3(%eax), %cl /* get byte from string */
225 cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
5929563f 226 jne L(3) /* yes => return */
8f5ca04b
RM
227
228 incl %eax /* adjust pointer */
5929563f
UD
229L(6): incl %eax
230L(5): incl %eax
8f5ca04b 231
5929563f 232L(4): addl $256, %esp /* remove stopset */
1ad9da69 233 cfi_adjust_cfa_offset (-256)
8f5ca04b
RM
234
235 orb %cl, %cl /* was last character NUL? */
2fc08826
GM
236 jnz L(7) /* no => return pointer */
237 xorl %eax, %eax
8f5ca04b 238
2366713d
JM
239L(7): ret
240END (strpbrk)
85dd1003 241libc_hidden_builtin_def (strpbrk)