1 /* strtok (str, delim) -- Return next DELIM separated token from STR.
3 Copyright (C) 1998,2000-2003,2005,2006 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Based on i686 version contributed by Ulrich Drepper
6 <drepper@cygnus.com>, 1998.
8 The GNU C Library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
13 The GNU C Library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the GNU C Library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 #include "asm-syntax.h"
28 /* This file can be used for the strtok and strtok_r functions:
41 We do a common implementation here. */
43 #ifdef USE_AS_STRTOK_R
44 # define SAVE_PTR (%r9)
48 ASM_TYPE_DIRECTIVE (save_ptr, @object)
54 # define SAVE_PTR save_ptr(%rip)
56 # define SAVE_PTR save_ptr
59 # define FUNCTION strtok
63 ENTRY (BP_SYM (FUNCTION))
64 /* First we create a table with flags for all possible characters.
65 For the ASCII (7bit/8bit) or ISO-8859-X character sets which are
66 supported by the C string functions we have 256 characters.
67 Before inserting marks for the stop characters we clear the whole
69 movq %rdi, %r8 /* Save value. */
70 subq $256, %rsp /* Make space for 256 bytes. */
71 cfi_adjust_cfa_offset(256)
72 movl $32, %ecx /* 32*8 bytes = 256 bytes. */
74 xorl %eax, %eax /* We store 0s. */
79 /* Note: %rcx = 0 !!! */
81 #ifdef USE_AS_STRTOK_R
82 /* The value is stored in the third argument. */
84 movq %rdx, %r9 /* Save value - see def. of SAVE_PTR. */
87 /* The value is in the local variable defined above. But
88 we have to take care for PIC code. */
91 movq %r8, %rdx /* Get start of string. */
93 /* If the pointer is NULL we have to use the stored value of
99 movq %rsi, %rax /* Get start of delimiter set. */
101 /* For understanding the following code remember that %rcx == 0 now.
102 Although all the following instruction only modify %cl we always
103 have a correct zero-extended 64-bit value in %rcx. */
105 L(2): movb (%rax), %cl /* get byte from stopset */
106 testb %cl, %cl /* is NUL char? */
107 jz L(1) /* yes => start compare loop */
108 movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */
110 movb 1(%rax), %cl /* get byte from stopset */
111 testb $0xff, %cl /* is NUL char? */
112 jz L(1) /* yes => start compare loop */
113 movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */
115 movb 2(%rax), %cl /* get byte from stopset */
116 testb $0xff, %cl /* is NUL char? */
117 jz L(1) /* yes => start compare loop */
118 movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */
120 movb 3(%rax), %cl /* get byte from stopset */
121 addq $4, %rax /* increment stopset pointer */
122 movb %cl, (%rsp,%rcx) /* set corresponding byte in stopset table */
123 testb $0xff, %cl /* is NUL char? */
124 jnz L(2) /* no => process next dword from stopset */
128 leaq -4(%rdx), %rax /* prepare loop */
130 /* We use a neat trick for the following loop. Normally we would
131 have to test for two termination conditions
132 1. a character in the stopset was found
134 2. the end of the string was found
135 As a sign that the character is in the stopset we store its
136 value in the table. The value of NUL is NUL so the loop
137 terminates for NUL in every case. */
139 L(3): addq $4, %rax /* adjust pointer for full loop round */
141 movb (%rax), %cl /* get byte from string */
142 testb %cl, (%rsp,%rcx) /* is it contained in stopset? */
143 jz L(4) /* no => start of token */
145 movb 1(%rax), %cl /* get byte from string */
146 testb %cl, (%rsp,%rcx) /* is it contained in stopset? */
147 jz L(5) /* no => start of token */
149 movb 2(%rax), %cl /* get byte from string */
150 testb %cl, (%rsp,%rcx) /* is it contained in stopset? */
151 jz L(6) /* no => start of token */
153 movb 3(%rax), %cl /* get byte from string */
154 testb %cl, (%rsp,%rcx) /* is it contained in stopset? */
155 jnz L(3) /* yes => start of loop */
157 incq %rax /* adjust pointer */
161 /* Now we have to terminate the string. */
163 L(4): leaq -4(%rax), %rdx /* We use %rDX for the next run. */
165 L(7): addq $4, %rdx /* adjust pointer for full loop round */
167 movb (%rdx), %cl /* get byte from string */
168 cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */
169 je L(8) /* yes => return */
171 movb 1(%rdx), %cl /* get byte from string */
172 cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */
173 je L(9) /* yes => return */
175 movb 2(%rdx), %cl /* get byte from string */
176 cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */
177 je L(10) /* yes => return */
179 movb 3(%rdx), %cl /* get byte from string */
180 cmpb %cl, (%rsp,%rcx) /* is it contained in skipset? */
181 jne L(7) /* no => start loop again */
183 incq %rdx /* adjust pointer */
187 L(8): cmpq %rax, %rdx
188 je L(returnNULL) /* There was no token anymore. */
190 movb $0, (%rdx) /* Terminate string. */
192 /* Are we at end of string? */
197 /* Store the pointer to the next character. */
201 /* Remove the stopset table. */
203 cfi_adjust_cfa_offset(-256)
208 /* Store the pointer to the next character. */
212 END (BP_SYM (FUNCTION))