* sysdeps/unix/sysv/linux/m68k/vfork.S: New file.
[glibc.git] / sysdeps / i386 / i686 / strtok.S
blob18aa7c8c7b47a81966bcd90cb95bf495fc9623d4
1 /* strtok (str, delim) -- Return next DELIM separated token from STR.
2    For Intel 80686.
3    Copyright (C) 1998 Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
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.  */
22 #include <sysdep.h>
23 #include "asm-syntax.h"
25 /* This file can be used for three variants of the strtok function:
27    strtok:
28         INPUT PARAMETER:
29         str             (sp + 4)
30         delim           (sp + 8)
32    strtok_r:
33         INPUT PARAMETER:
34         str             (sp + 4)
35         delim           (sp + 8)
36         save_ptr        (sp + 12)
38    We do a common implementation here.  */
40 #ifndef USE_AS_STRTOK_R
41         .bss
42         .local save_ptr
43         ASM_TYPE_DIRECTIVE (save_ptr, @object)
44         .size save_ptr, 4
45 save_ptr:
46         .space 4
48 #define FUNCTION strtok
49 #endif
51         .text
53 #if !defined USE_AS_STRTOK_R && defined PIC
54 0:      movl (%esp), %ebx
55         ret
56 #endif
58 ENTRY (FUNCTION)
60 #if !defined USE_AS_STRTOK_R && defined PIC
61         pushl %ebx                      /* Save PIC register.  */
62         call 0b
63         addl $_GLOBAL_OFFSET_TABLE_, %ebx
64 #endif
66         /* First we create a table with flags for all possible characters.
67            For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
68            supported by the C string functions we have 256 characters.
69            Before inserting marks for the stop characters we clear the whole
70            table.  */
71         movl %edi, %edx
72         subl $256, %esp
73         movl $64, %ecx
74         movl %esp, %edi
75         xorl %eax, %eax
76         cld
77         rep
78         stosl
80         /* Note: %ecx = 0 !!! */
81         movl %edx, %edi
83 #if !defined USE_AS_STRTOK_R && defined PIC
84         movl 264(%esp), %edx            /* Get start of string.  */
85 #else
86         movl 260(%esp), %edx            /* Get start of string.  */
87 #endif
89 #ifdef USE_AS_STRTOK_R
90         /* The value is stored in the third argument.  */
91         movl 268(%esp), %eax
92         movl (%eax), %eax
93 #else
94         /* The value is in the local variable defined above.  But
95            we have to take care for PIC code.  */
96 # ifndef PIC
97         movl save_ptr, %eax
98 # else
99         movl save_ptr@GOTOFF(%ebx), %eax
100 # endif
101 #endif
103         /* If the pointer is NULL we have to use the stored value of
104            the last run.  */
105         cmpl $0, %edx
106         cmove %eax, %edx
108 #if !defined USE_AS_STRTOK_R && defined PIC
109         movl 268(%esp), %eax            /* Get start of delimiter set.  */
110 #else
111         movl 264(%esp), %eax            /* Get start of delimiter set.  */
112 #endif
114 /* For understanding the following code remember that %ecx == 0 now.
115    Although all the following instruction only modify %cl we always
116    have a correct zero-extended 32-bit value in %ecx.  */
118 L(2):   movb (%eax), %cl        /* get byte from stopset */
119         testb %cl, %cl          /* is NUL char? */
120         jz L(1)                 /* yes => start compare loop */
121         movb %cl, (%esp,%ecx)   /* set corresponding byte in stopset table */
123         movb 1(%eax), %cl       /* get byte from stopset */
124         testb $0xff, %cl        /* is NUL char? */
125         jz L(1)                 /* yes => start compare loop */
126         movb %cl, (%esp,%ecx)   /* set corresponding byte in stopset table */
128         movb 2(%eax), %cl       /* get byte from stopset */
129         testb $0xff, %cl        /* is NUL char? */
130         jz L(1)                 /* yes => start compare loop */
131         movb %cl, (%esp,%ecx)   /* set corresponding byte in stopset table */
133         movb 3(%eax), %cl       /* get byte from stopset */
134         addl $4, %eax           /* increment stopset pointer */
135         movb %cl, (%esp,%ecx)   /* set corresponding byte in stopset table */
136         testb $0xff, %cl        /* is NUL char? */
137         jnz L(2)                /* no => process next dword from stopset */
139 L(1):   leal -4(%edx), %eax     /* prepare loop */
141         /* We use a neat trick for the following loop.  Normally we would
142            have to test for two termination conditions
143            1. a character in the stopset was found
144            and
145            2. the end of the string was found
146            As a sign that the character is in the stopset we store its
147            value in the table.  The value of NUL is NUL so the loop
148            terminates for NUL in every case.  */
150 L(3):   addl $4, %eax           /* adjust pointer for full loop round */
152         movb (%eax), %cl        /* get byte from string */
153         testb %cl, (%esp,%ecx)  /* is it contained in stopset? */
154         jz L(4)                 /* no => start of token */
156         movb 1(%eax), %cl       /* get byte from string */
157         testb %cl, (%esp,%ecx)  /* is it contained in stopset? */
158         jz L(5)                 /* no => start of token */
160         movb 2(%eax), %cl       /* get byte from string */
161         testb %cl, (%esp,%ecx)  /* is it contained in stopset? */
162         jz L(6)                 /* no => start of token */
164         movb 3(%eax), %cl       /* get byte from string */
165         testb %cl, (%esp,%ecx)  /* is it contained in stopset? */
166         jnz L(3)                /* yes => start of loop */
168         incl %eax               /* adjust pointer */
169 L(6):   incl %eax
170 L(5):   incl %eax
172         /* Now we have to terminate the string.  */
174 L(4):   leal -4(%eax), %edx     /* We use %EDX for the next run.  */
176 L(7):   addl $4, %edx           /* adjust pointer for full loop round */
178         movb (%edx), %cl        /* get byte from string */
179         cmpb %cl, (%esp,%ecx)   /* is it contained in skipset? */
180         je L(8)                 /* yes => return */
182         movb 1(%edx), %cl       /* get byte from string */
183         cmpb %cl, (%esp,%ecx)   /* is it contained in skipset? */
184         je L(9)                 /* yes => return */
186         movb 2(%edx), %cl       /* get byte from string */
187         cmpb %cl, (%esp,%ecx)   /* is it contained in skipset? */
188         je L(10)                /* yes => return */
190         movb 3(%edx), %cl       /* get byte from string */
191         cmpb %cl, (%esp,%ecx)   /* is it contained in skipset? */
192         jne L(7)                /* no => start loop again */
194         incl %edx               /* adjust pointer */
195 L(10):  incl %edx
196 L(9):   incl %edx
198 L(8):   /* Remove the stopset table.  */
199         addl $256, %esp
201         cmpl %eax, %edx
202         je L(returnNULL)        /* There was no token anymore.  */
204         movb $0, (%edx)         /* Terminate string.  */
206         /* Are we at end of string?  */
207         cmpb $0, %cl
208         leal 1(%edx), %ecx
209         cmovne %ecx, %edx
211 L(return):
212         /* Store the pointer to the next character.  */
213 #ifdef USE_AS_STRTOK_R
214         movl 12(%esp), %ecx
215         movl %edx, (%ecx)
216 #else
217 # ifndef PIC
218         movl %edx, save_ptr
219 # else
220         movl %edx, save_ptr@GOTOFF(%ebx)
221         popl %ebx
222 # endif
223 #endif
224         ret
226 L(returnNULL):
227         xorl %eax, %eax
228         jmp L(return)
229 END (FUNCTION)