]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/i386/strtok.S
update from main archive 961005
[thirdparty/glibc.git] / sysdeps / i386 / strtok.S
CommitLineData
59dd8641
RM
1/* strtok (str, delim) -- Return next DELIM separated token from STR.
2For Intel 80x86, x>=3.
3Copyright (C) 1996 Free Software Foundation, Inc.
4This file is part of the GNU C Library.
5Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
6
7The GNU C Library is free software; you can redistribute it and/or
8modify it under the terms of the GNU Library General Public License as
9published by the Free Software Foundation; either version 2 of the
10License, or (at your option) any later version.
11
12The GNU C Library is distributed in the hope that it will be useful,
13but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15Library General Public License for more details.
16
17You should have received a copy of the GNU Library General Public
18License along with the GNU C Library; see the file COPYING.LIB. If
19not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20Boston, MA 02111-1307, USA. */
21
59dd8641
RM
22#include <sysdep.h>
23
24/* This file can be used for three variants of the strtok function:
25
26 strtok:
27 INPUT PARAMETER:
28 str (sp + 4)
29 delim (sp + 8)
30
31 strtok_r:
32 INPUT PARAMETER:
33 str (sp + 4)
34 delim (sp + 8)
35 save_ptr (sp + 12)
36
59dd8641
RM
37 We do a common implementation here. */
38
76060ec0 39#ifndef USE_AS_STRTOK_R
59dd8641
RM
40 .bss
41 .local save_ptr
42 ASM_TYPE_DIRECTIVE (save_ptr, @object)
43 .size save_ptr, 4
44save_ptr:
45 .space 4
46
47#define FUNCTION strtok
48#endif
49
59dd8641 50 .text
59dd8641
RM
51
52ENTRY (FUNCTION)
53
54 movl 4(%esp), %edx /* Get start of string. */
55 movl 8(%esp), %eax /* Get start of delimiter set. */
56
76060ec0 57#if !defined (USE_AS_STRTOK_R) && defined (PIC)
59dd8641
RM
58 pushl %ebx /* Save PIC register. */
59 call Lhere
60Lhere: popl %ebx
61 addl $_GLOBAL_OFFSET_TABLE_+[.-Lhere], %ebx
76060ec0 62#endif
59dd8641
RM
63
64 /* If the pointer is NULL we have to use the stored value of
65 the last run. */
66 cmpl $0, %edx
67 jne L0
68
76060ec0 69#ifdef USE_AS_STRTOK_R
59dd8641
RM
70 /* The value is stored in the third argument. */
71 movl 12(%esp), %edx
72 movl (%edx), %edx
76060ec0 73#else
59dd8641
RM
74 /* The value is in the local variable defined above. But
75 we have to take care for PIC code. */
76060ec0 76# ifndef PIC
59dd8641 77 movl save_ptr, %edx
76060ec0 78# else
59dd8641 79 movl save_ptr@GOTOFF(%ebx), %edx
59dd8641
RM
80# endif
81#endif
82
59dd8641 83L0:
59dd8641
RM
84 /* First we create a table with flags for all possible characters.
85 For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
86 supported by the C string functions we have 256 characters.
87 Before inserting marks for the stop characters we clear the whole
88 table. The unrolled form is much faster than a loop. */
89 xorl %ecx, %ecx /* %ecx = 0 !!! */
90
91 pushl %ecx /* make a 256 bytes long block filled with 0 */
92 pushl %ecx
93 pushl %ecx
94 pushl %ecx
95 pushl %ecx
96 pushl %ecx
97 pushl %ecx
98 pushl %ecx
99 pushl %ecx
100 pushl %ecx
101 pushl %ecx
102 pushl %ecx
103 pushl %ecx
104 pushl %ecx
105 pushl %ecx
106 pushl %ecx
107 pushl %ecx
108 pushl %ecx
109 pushl %ecx
110 pushl %ecx
111 pushl %ecx
112 pushl %ecx
113 pushl %ecx
114 pushl %ecx
115 pushl %ecx
116 pushl %ecx
117 pushl %ecx
118 pushl %ecx
119 pushl %ecx
120 pushl %ecx
121 pushl %ecx
122 pushl %ecx
123 pushl %ecx
124 pushl %ecx
125 pushl %ecx
126 pushl %ecx
127 pushl %ecx
128 pushl %ecx
129 pushl %ecx
130 pushl %ecx
131 pushl %ecx
132 pushl %ecx
133 pushl %ecx
134 pushl %ecx
135 pushl %ecx
136 pushl %ecx
137 pushl %ecx
138 pushl %ecx
139 pushl %ecx
140 pushl %ecx
141 pushl %ecx
142 pushl %ecx
143 pushl %ecx
144 pushl %ecx
145 pushl %ecx
146 pushl %ecx
147 pushl %ecx
148 pushl %ecx
149 pushl $0 /* These immediate values make the label 2 */
150 pushl $0 /* to be aligned on a 16 byte boundary to */
151 pushl $0 /* get a better performance of the loop. */
152 pushl $0
153 pushl $0
154 pushl $0
155
156/* For understanding the following code remember that %ecx == 0 now.
157 Although all the following instruction only modify %cl we always
158 have a correct zero-extended 32-bit value in %ecx. */
159
160L2: movb (%eax), %cl /* get byte from stopset */
161 testb %cl, %cl /* is NUL char? */
162 jz L1 /* yes => start compare loop */
163 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
164
165 movb 1(%eax), %cl /* get byte from stopset */
166 testb $0xff, %cl /* is NUL char? */
167 jz L1 /* yes => start compare loop */
168 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
169
170 movb 2(%eax), %cl /* get byte from stopset */
171 testb $0xff, %cl /* is NUL char? */
172 jz L1 /* yes => start compare loop */
173 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
174
175 movb 3(%eax), %cl /* get byte from stopset */
176 addl $4, %eax /* increment stopset pointer */
177 movb %cl, (%esp,%ecx) /* set corresponding byte in stopset table */
178 testb $0xff, %cl /* is NUL char? */
179 jnz L2 /* no => process next dword from stopset */
180
181L1: leal -4(%edx), %eax /* prepare loop */
182
183 /* We use a neat trick for the following loop. Normally we would
184 have to test for two termination conditions
185 1. a character in the stopset was found
186 and
187 2. the end of the string was found
76060ec0
RM
188 As a sign that the character is in the stopset we store its
189 value in the table. The value of NUL is NUL so the loop
59dd8641
RM
190 terminates for NUL in every case. */
191
192L3: addl $4, %eax /* adjust pointer for full loop round */
193
194 movb (%eax), %cl /* get byte from string */
195 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
196 jz L4 /* no => start of token */
197
198 movb 1(%eax), %cl /* get byte from string */
199 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
200 jz L5 /* no => start of token */
201
202 movb 2(%eax), %cl /* get byte from string */
203 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
204 jz L6 /* no => start of token */
205
206 movb 3(%eax), %cl /* get byte from string */
207 testb %cl, (%esp,%ecx) /* is it contained in stopset? */
208 jnz L3 /* yes => start of loop */
209
210 incl %eax /* adjust pointer */
211L6: incl %eax
212L5: incl %eax
213
214 /* Now we have to terminate the string. */
215
216L4: leal -4(%eax), %edx /* We use %EDX for the next run. */
217
218L7: addl $4, %edx /* adjust pointer for full loop round */
219
220 movb (%edx), %cl /* get byte from string */
221 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
222 je L8 /* yes => return */
223
224 movb 1(%edx), %cl /* get byte from string */
225 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
226 je L9 /* yes => return */
227
228 movb 2(%edx), %cl /* get byte from string */
229 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
230 je L10 /* yes => return */
231
232 movb 3(%edx), %cl /* get byte from string */
233 cmpb %cl, (%esp,%ecx) /* is it contained in skipset? */
234 jne L7 /* no => start loop again */
235
236 incl %edx /* adjust pointer */
237L10: incl %edx
238L9: incl %edx
239
240L8: /* Remove the stopset table. */
241 addl $256, %esp
242
243 cmpl %eax, %edx
244 je LreturnNULL /* There was no token anymore. */
245
246 movb $0, (%edx) /* Terminate string. */
247
248 /* Are we at end of string? */
249 cmpb $0, %cl
250 je L11
251
252 incl %edx
253L11:
254
255 /* Store the pointer to the next character. */
256#ifdef USE_AS_STRTOK_R
257 movl 12(%esp), %ecx
258 movl %edx, (%ecx)
59dd8641
RM
259#else
260# ifndef PIC
261 movl %edx, save_ptr
262# else
263 movl %edx, save_ptr@GOTOFF(%ebx)
264 popl %ebx
265# endif
266#endif
267 ret
268
269LreturnNULL:
270 xorl %eax, %eax
271
ffee1316 272 /* Store current pointer for next round. */
59dd8641
RM
273#ifdef USE_AS_STRTOK_R
274 movl 12(%esp), %ecx
ffee1316 275 movl %edx, (%ecx)
59dd8641
RM
276#else
277# ifndef PIC
ffee1316 278 movl %edx, save_ptr
59dd8641 279# else
ffee1316 280 movl %edx, save_ptr@GOTOFF(%ebx)
59dd8641
RM
281 popl %ebx
282# endif
283#endif
284 ret
cccda09f 285PSEUDO_END (FUNCTION)