]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/i386/strpbrk.S
Update copyright notices 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.
568035b7 4 Copyright (C) 1994-2013 Free Software Foundation, Inc.
5929563f
UD
5 Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>
6 Bug fixes by Alan Modra <Alan@SPRI.Levels.UniSA.Edu.Au>
7 This file is part of the GNU C Library.
8
9 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
10 modify it under the terms of the GNU Lesser General Public
11 License as published by the Free Software Foundation; either
12 version 2.1 of the License, or (at your option) any later version.
5929563f
UD
13
14 The GNU C Library is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 17 Lesser General Public License for more details.
5929563f 18
41bdb6e2 19 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
20 License along with the GNU C Library; if not, see
21 <http://www.gnu.org/licenses/>. */
8f5ca04b
RM
22
23#include <sysdep.h>
24#include "asm-syntax.h"
2fc08826 25#include "bp-sym.h"
3f02f778 26#include "bp-asm.h"
8f5ca04b 27
3f02f778
GM
28#define PARMS LINKAGE /* no space for saved regs */
29#define RTN PARMS
30#define STR RTN+RTN_SIZE
31#define STOP STR+PTR_SIZE
8f5ca04b
RM
32
33 .text
2fc08826 34ENTRY (BP_SYM (strpbrk))
3f02f778
GM
35 ENTER
36
37 movl STR(%esp), %edx
38 movl STOP(%esp), %eax
2fc08826 39 CHECK_BOUNDS_LOW (%edx, STR(%esp))
8f5ca04b
RM
40
41 /* First we create a table with flags for all possible characters.
42 For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
43 supported by the C string functions we have 256 characters.
44 Before inserting marks for the stop characters we clear the whole
45 table. The unrolled form is much faster than a loop. */
46 xorl %ecx, %ecx /* %ecx = 0 !!! */
47
48 pushl %ecx /* make a 256 bytes long block filled with 0 */
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 %ecx
1ad9da69 159 cfi_adjust_cfa_offset (4)
8f5ca04b 160 pushl %ecx
1ad9da69 161 cfi_adjust_cfa_offset (4)
8f5ca04b 162 pushl %ecx
1ad9da69 163 cfi_adjust_cfa_offset (4)
8f5ca04b 164 pushl $0 /* These immediate values make the label 2 */
1ad9da69 165 cfi_adjust_cfa_offset (4)
8f5ca04b 166 pushl $0 /* to be aligned on a 16 byte boundary to */
1ad9da69 167 cfi_adjust_cfa_offset (4)
8f5ca04b 168 pushl $0 /* get a better performance of the loop. */
1ad9da69 169 cfi_adjust_cfa_offset (4)
8f5ca04b 170 pushl $0
1ad9da69 171 cfi_adjust_cfa_offset (4)
8f5ca04b 172 pushl $0
1ad9da69 173 cfi_adjust_cfa_offset (4)
8f5ca04b 174 pushl $0
1ad9da69 175 cfi_adjust_cfa_offset (4)
8f5ca04b
RM
176
177/* For understanding the following code remember that %ecx == 0 now.
178 Although all the following instruction only modify %cl we always
179 have a correct zero-extended 32-bit value in %ecx. */
180
181/* Don't change the "testb $0xff,%%cl" to "testb %%cl,%%cl". We want
182 longer instructions so that the next loop aligns without adding nops. */
183
5929563f 184L(2): movb (%eax), %cl /* get byte from stopset */
8f5ca04b 185 testb %cl, %cl /* is NUL char? */
5929563f 186 jz L(1) /* yes => start compare loop */
8f5ca04b
RM
187 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
188
189 movb 1(%eax), %cl /* get byte from stopset */
190 testb $0xff, %cl /* is NUL char? */
5929563f 191 jz L(1) /* yes => start compare loop */
8f5ca04b
RM
192 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
193
194 movb 2(%eax), %cl /* get byte from stopset */
195 testb $0xff, %cl /* is NUL char? */
5929563f 196 jz L(1) /* yes => start compare loop */
8f5ca04b
RM
197 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
198
199 movb 3(%eax), %cl /* get byte from stopset */
200 addl $4, %eax /* increment stopset pointer */
201 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
202 testb $0xff, %cl /* is NUL char? */
5929563f 203 jnz L(2) /* no => process next dword from stopset */
8f5ca04b 204
5929563f 205L(1): leal -4(%edx), %eax /* prepare loop */
8f5ca04b
RM
206
207 /* We use a neat trick for the following loop. Normally we would
208 have to test for two termination conditions
209 1. a character in the stopset was found
210 and
211 2. the end of the string was found
212 But as a sign that the chracter is in the stopset we store its
213 value in the table. But the value of NUL is NUL so the loop
214 terminates for NUL in every case. */
215
5929563f 216L(3): addl $4, %eax /* adjust pointer for full loop round */
8f5ca04b
RM
217
218 movb (%eax), %cl /* get byte from string */
219 cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
5929563f 220 je L(4) /* yes => return */
8f5ca04b
RM
221
222 movb 1(%eax), %cl /* get byte from string */
223 cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
5929563f 224 je L(5) /* yes => return */
8f5ca04b
RM
225
226 movb 2(%eax), %cl /* get byte from string */
227 cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
5929563f 228 je L(6) /* yes => return */
8f5ca04b
RM
229
230 movb 3(%eax), %cl /* get byte from string */
231 cmpb %cl, (%esp,%ecx) /* is it contained in stopset? */
5929563f 232 jne L(3) /* yes => return */
8f5ca04b
RM
233
234 incl %eax /* adjust pointer */
5929563f
UD
235L(6): incl %eax
236L(5): incl %eax
8f5ca04b 237
5929563f 238L(4): addl $256, %esp /* remove stopset */
1ad9da69 239 cfi_adjust_cfa_offset (-256)
8f5ca04b 240
2fc08826 241 CHECK_BOUNDS_HIGH (%eax, STR(%esp), jb)
8f5ca04b 242 orb %cl, %cl /* was last character NUL? */
2fc08826
GM
243 jnz L(7) /* no => return pointer */
244 xorl %eax, %eax
245 RETURN_NULL_BOUNDED_POINTER
8f5ca04b 246
2fc08826 247 LEAVE
3f02f778 248 RET_PTR
2fc08826
GM
249
250L(7): RETURN_BOUNDED_POINTER (STR(%esp))
251
252 LEAVE
253 RET_PTR
254END (BP_SYM (strpbrk))
85dd1003 255libc_hidden_builtin_def (strpbrk)