1 /* strtok (str, delim) -- Return next DELIM separated token from STR.
3 Copyright (C) 1996, 1997 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"
25 /* This file can be used for three variants of the strtok function:
38 We do a common implementation here. */
40 #ifndef USE_AS_STRTOK_R
43 ASM_TYPE_DIRECTIVE (save_ptr, @object)
48 #define FUNCTION strtok
55 movl 4(%esp), %edx /* Get start of string. */
56 movl 8(%esp), %eax /* Get start of delimiter set. */
58 #if !defined (USE_AS_STRTOK_R) && defined (PIC)
59 pushl %ebx /* Save PIC register. */
63 addl $_GLOBAL_OFFSET_TABLE_+[.-L(here)], %ebx
66 /* If the pointer is NULL we have to use the stored value of
71 #ifdef USE_AS_STRTOK_R
72 /* The value is stored in the third argument. */
76 /* The value is in the local variable defined above. But
77 we have to take care for PIC code. */
81 movl save_ptr@GOTOFF(%ebx), %edx
86 /* First we create a table with flags for all possible characters.
87 For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
88 supported by the C string functions we have 256 characters.
89 Before inserting marks for the stop characters we clear the whole
90 table. The unrolled form is much faster than a loop. */
91 xorl %ecx, %ecx /* %ecx = 0 !!! */
93 pushl %ecx /* make a 256 bytes long block filled with 0 */
151 pushl $0 /* These immediate values make the label 2 */
152 pushl $0 /* to be aligned on a 16 byte boundary to */
153 pushl $0 /* get a better performance of the loop. */
158 /* For understanding the following code remember that %ecx == 0 now.
159 Although all the following instruction only modify %cl we always
160 have a correct zero-extended 32-bit value in %ecx. */
162 L(2): movb (%eax), %cl /* get byte from stopset */
163 testb %cl, %cl /* is NUL char? */
164 jz L(1) /* yes => start compare loop */
165 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
167 movb 1(%eax), %cl /* get byte from stopset */
168 testb $0xff, %cl /* is NUL char? */
169 jz L(1) /* yes => start compare loop */
170 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
172 movb 2(%eax), %cl /* get byte from stopset */
173 testb $0xff, %cl /* is NUL char? */
174 jz L(1) /* yes => start compare loop */
175 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
177 movb 3(%eax), %cl /* get byte from stopset */
178 addl $4, %eax /* increment stopset pointer */
179 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
180 testb $0xff, %cl /* is NUL char? */
181 jnz L(2) /* no => process next dword from stopset */
183 L(1): leal -4(%edx), %eax /* prepare loop */
185 /* We use a neat trick for the following loop. Normally we would
186 have to test for two termination conditions
187 1. a character in the stopset was found
189 2. the end of the string was found
190 As a sign that the character is in the stopset we store its
191 value in the table. The value of NUL is NUL so the loop
192 terminates for NUL in every case. */
194 L(3): addl $4, %eax /* adjust pointer for full loop round */
196 movb (%eax), %cl /* get byte from string */
197 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
198 jz L(4) /* no => start of token */
200 movb 1(%eax), %cl /* get byte from string */
201 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
202 jz L(5) /* no => start of token */
204 movb 2(%eax), %cl /* get byte from string */
205 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
206 jz L(6) /* no => start of token */
208 movb 3(%eax), %cl /* get byte from string */
209 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
210 jnz L(3) /* yes => start of loop */
212 incl %eax /* adjust pointer */
216 /* Now we have to terminate the string. */
218 L(4): leal -4(%eax), %edx /* We use %EDX for the next run. */
220 L(7): addl $4, %edx /* adjust pointer for full loop round */
222 movb (%edx), %cl /* get byte from string */
223 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
224 je L(8) /* yes => return */
226 movb 1(%edx), %cl /* get byte from string */
227 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
228 je L(9) /* yes => return */
230 movb 2(%edx), %cl /* get byte from string */
231 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
232 je L(10) /* yes => return */
234 movb 3(%edx), %cl /* get byte from string */
235 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
236 jne L(7) /* no => start loop again */
238 incl %edx /* adjust pointer */
242 L(8): /* Remove the stopset table. */
246 je L(returnNULL) /* There was no token anymore. */
248 movb $0, (%edx) /* Terminate string. */
250 /* Are we at end of string? */
257 /* Store the pointer to the next character. */
258 #ifdef USE_AS_STRTOK_R
265 movl %edx, save_ptr@GOTOFF(%ebx)
274 /* Store current pointer for next round. */
275 #ifdef USE_AS_STRTOK_R
282 movl %edx, save_ptr@GOTOFF(%ebx)