1 /* strtok (str, delim) -- Return next DELIM separated token from STR.
3 Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 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 Library General Public License for more details.
17 You should have received a copy of the GNU Library General Public
18 License along with the GNU C Library; see the file COPYING.LIB. If not,
19 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
23 #include "asm-syntax.h"
26 /* This file can be used for three variants of the strtok function:
39 We do a common implementation here. */
41 #ifndef USE_AS_STRTOK_R
44 ASM_TYPE_DIRECTIVE (save_ptr, @object)
49 #define FUNCTION strtok
52 #define PARMS LINKAGE /* no space for saved regs */
54 #define STR RTN+RTN_SIZE
55 #define DELIM STR+PTR_SIZE
56 #define SAVE DELIM+PTR_SIZE
64 movl DELIM(%esp), %eax
66 #if !defined (USE_AS_STRTOK_R) && defined (PIC)
67 pushl %ebx /* Save PIC register. */
71 addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ebx
74 /* If the pointer is NULL we have to use the stored value of
79 #ifdef USE_AS_STRTOK_R
80 /* The value is stored in the third argument. */
84 /* The value is in the local variable defined above. But
85 we have to take care for PIC code. */
89 movl save_ptr@GOTOFF(%ebx), %edx
94 /* First we create a table with flags for all possible characters.
95 For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
96 supported by the C string functions we have 256 characters.
97 Before inserting marks for the stop characters we clear the whole
98 table. The unrolled form is much faster than a loop. */
99 xorl %ecx, %ecx /* %ecx = 0 !!! */
101 pushl %ecx /* make a 256 bytes long block filled with 0 */
159 pushl $0 /* These immediate values make the label 2 */
160 pushl $0 /* to be aligned on a 16 byte boundary to */
161 pushl $0 /* get a better performance of the loop. */
166 /* For understanding the following code remember that %ecx == 0 now.
167 Although all the following instruction only modify %cl we always
168 have a correct zero-extended 32-bit value in %ecx. */
170 L(2): movb (%eax), %cl /* get byte from stopset */
171 testb %cl, %cl /* is NUL char? */
172 jz L(1) /* yes => start compare loop */
173 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
175 movb 1(%eax), %cl /* get byte from stopset */
176 testb $0xff, %cl /* is NUL char? */
177 jz L(1) /* yes => start compare loop */
178 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
180 movb 2(%eax), %cl /* get byte from stopset */
181 testb $0xff, %cl /* is NUL char? */
182 jz L(1) /* yes => start compare loop */
183 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
185 movb 3(%eax), %cl /* get byte from stopset */
186 addl $4, %eax /* increment stopset pointer */
187 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
188 testb $0xff, %cl /* is NUL char? */
189 jnz L(2) /* no => process next dword from stopset */
191 L(1): leal -4(%edx), %eax /* prepare loop */
193 /* We use a neat trick for the following loop. Normally we would
194 have to test for two termination conditions
195 1. a character in the stopset was found
197 2. the end of the string was found
198 As a sign that the character is in the stopset we store its
199 value in the table. The value of NUL is NUL so the loop
200 terminates for NUL in every case. */
202 L(3): addl $4, %eax /* adjust pointer for full loop round */
204 movb (%eax), %cl /* get byte from string */
205 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
206 jz L(4) /* no => start of token */
208 movb 1(%eax), %cl /* get byte from string */
209 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
210 jz L(5) /* no => start of token */
212 movb 2(%eax), %cl /* get byte from string */
213 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
214 jz L(6) /* no => start of token */
216 movb 3(%eax), %cl /* get byte from string */
217 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
218 jnz L(3) /* yes => start of loop */
220 incl %eax /* adjust pointer */
224 /* Now we have to terminate the string. */
226 L(4): leal -4(%eax), %edx /* We use %EDX for the next run. */
228 L(7): addl $4, %edx /* adjust pointer for full loop round */
230 movb (%edx), %cl /* get byte from string */
231 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
232 je L(8) /* yes => return */
234 movb 1(%edx), %cl /* get byte from string */
235 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
236 je L(9) /* yes => return */
238 movb 2(%edx), %cl /* get byte from string */
239 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
240 je L(10) /* yes => return */
242 movb 3(%edx), %cl /* get byte from string */
243 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
244 jne L(7) /* no => start loop again */
246 incl %edx /* adjust pointer */
250 L(8): /* Remove the stopset table. */
254 je L(returnNULL) /* There was no token anymore. */
256 movb $0, (%edx) /* Terminate string. */
258 /* Are we at end of string? */
266 /* Store the pointer to the next character. */
267 #ifdef USE_AS_STRTOK_R
268 movl SAVE(%esp), %ecx
274 movl %edx, save_ptr@GOTOFF(%ebx)