1
by brian
clean slate |
1 |
# Copyright (C) 2000 MySQL AB
|
2 |
# This program is free software; you can redistribute it and/or modify
|
|
3 |
# it under the terms of the GNU General Public License as published by
|
|
4 |
# the Free Software Foundation; version 2 of the License.
|
|
5 |
#
|
|
6 |
# This program is distributed in the hope that it will be useful,
|
|
7 |
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
8 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
9 |
# GNU General Public License for more details.
|
|
10 |
#
|
|
11 |
# You should have received a copy of the GNU General Public License
|
|
12 |
# along with this program; if not, write to the Free Software
|
|
13 |
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
14 |
||
15 |
# Optimized string functions Intel 80x86 (gcc/gas syntax)
|
|
16 |
||
17 |
.file "strings.s" |
|
18 |
.version "1.00" |
|
19 |
||
20 |
.text
|
|
21 |
||
22 |
# Move a alligned, not overlapped, by (long) divided memory area
|
|
23 |
# Args: to,from,length
|
|
24 |
||
25 |
.globl bmove_align |
|
26 |
.type bmove_align,@function |
|
27 |
bmove_align:
|
|
28 |
movl %edi,%edx |
|
29 |
push %esi |
|
30 |
movl 4(%esp),%edi # to |
|
31 |
movl 8(%esp),%esi # from |
|
32 |
movl 12(%esp),%ecx # length |
|
33 |
addw $3,%cx # fix if not divisible with long |
|
34 |
shrw $2,%cx |
|
35 |
jz .ba_20 |
|
36 |
.p2align 4,,7 |
|
37 |
.ba_10:
|
|
38 |
movl -4(%esi,%ecx),%eax |
|
39 |
movl %eax,-4(%edi,%ecx) |
|
40 |
decl %ecx |
|
41 |
jnz .ba_10 |
|
42 |
.ba_20: pop %esi |
|
43 |
movl %edx,%edi |
|
44 |
ret
|
|
45 |
||
46 |
.bmove_align_end:
|
|
47 |
.size bmove_align,.bmove_align_end-bmove_align |
|
48 |
||
49 |
# Move a string from higher to lower
|
|
50 |
# Arg from_end+1,to_end+1,length
|
|
51 |
||
52 |
.globl bmove_upp |
|
53 |
.type bmove_upp,@function |
|
54 |
bmove_upp:
|
|
55 |
movl %edi,%edx # Remember %edi |
|
56 |
push %esi |
|
57 |
movl 8(%esp),%edi # dst |
|
58 |
movl 16(%esp),%ecx # length |
|
59 |
movl 12(%esp),%esi # source |
|
60 |
test %ecx,%ecx |
|
61 |
jz .bu_20 |
|
62 |
subl %ecx,%esi # To start of strings |
|
63 |
subl %ecx,%edi |
|
64 |
||
65 |
.p2align 4,,7 |
|
66 |
.bu_10: movb -1(%esi,%ecx),%al |
|
67 |
movb %al,-1(%edi,%ecx) |
|
68 |
decl %ecx |
|
69 |
jnz .bu_10 |
|
70 |
.bu_20: pop %esi |
|
71 |
movl %edx,%edi |
|
72 |
ret
|
|
73 |
||
74 |
.bmove_upp_end:
|
|
75 |
.size bmove_upp,.bmove_upp_end-bmove_upp |
|
76 |
||
77 |
# Append fillchars to string
|
|
78 |
# Args: dest,len,fill
|
|
79 |
||
80 |
.globl strappend |
|
81 |
.type strappend,@function |
|
82 |
strappend:
|
|
83 |
pushl %edi |
|
84 |
movl 8(%esp),%edi # Memory pointer |
|
85 |
movl 12(%esp),%ecx # Length |
|
86 |
clrl %eax # Find end of string |
|
87 |
repne |
|
88 |
scasb
|
|
89 |
jnz sa_99 # String to long, shorten it |
|
90 |
movzb 16(%esp),%eax # Fillchar |
|
91 |
decl %edi # Point at end null |
|
92 |
incl %ecx # rep made one dec for null-char |
|
93 |
||
94 |
movb %al,%ah # (2) Set up a 32 bit pattern. |
|
95 |
movw %ax,%dx # (2) |
|
96 |
shll $16,%eax # (3) |
|
97 |
movw %dx,%ax # (2) %eax has the 32 bit pattern. |
|
98 |
||
99 |
movl %ecx,%edx # (2) Save the count of bytes. |
|
100 |
shrl $2,%ecx # (2) Number of dwords. |
|
101 |
rep
|
|
102 |
stosl # (5 + 5n) |
|
103 |
movb $3,%cl # (2) |
|
104 |
and %edx,%ecx # (2) Fill in the odd bytes |
|
105 |
rep
|
|
106 |
stosb # Move last bytes if any |
|
107 |
||
108 |
sa_99: movb $0,(%edi) # End of string |
|
109 |
popl %edi |
|
110 |
ret
|
|
111 |
.strappend_end:
|
|
112 |
.size strappend,.strappend_end-strappend |
|
113 |
||
114 |
# Find if string contains any char in another string
|
|
115 |
# Arg: str,set
|
|
116 |
# Ret: Pointer to first found char in str
|
|
117 |
||
118 |
.globl strcont |
|
119 |
.type strcont,@function |
|
120 |
strcont:
|
|
121 |
movl %edi,%edx |
|
122 |
pushl %esi |
|
123 |
movl 8(%esp),%esi # str |
|
124 |
movl 12(%esp),%ecx # set |
|
125 |
clrb %ah # For endtest |
|
126 |
jmp sc_60 |
|
127 |
||
128 |
sc_10: scasb |
|
129 |
jz sc_fo # Found char |
|
130 |
sc_20: cmp (%edi),%ah # Test if null |
|
131 |
jnz sc_10 # Not end of set yet |
|
132 |
incl %esi # Next char in str |
|
133 |
sc_60: movl %ecx,%edi # %edi = Set |
|
134 |
movb (%esi),%al # Test if this char exist |
|
135 |
andb %al,%al |
|
136 |
jnz sc_20 # Not end of string |
|
137 |
clrl %esi # Return Null |
|
138 |
sc_fo: movl %esi,%eax # Char found here |
|
139 |
movl %edx,%edi # Restore |
|
140 |
popl %esi |
|
141 |
ret
|
|
142 |
.strcont_end:
|
|
143 |
.size strcont,.strcont_end-strcont |
|
144 |
||
145 |
# Find end of string
|
|
146 |
# Arg: str
|
|
147 |
# ret: Pointer to end null
|
|
148 |
||
149 |
.globl strend |
|
150 |
.type strend,@function |
|
151 |
strend:
|
|
152 |
movl %edi,%edx # Save |
|
153 |
movl 4(%esp),%edi # str |
|
154 |
clrl %eax # Find end of string |
|
155 |
movl %eax,%ecx |
|
156 |
decl %ecx # ECX = -1 |
|
157 |
repne |
|
158 |
scasb
|
|
159 |
movl %edi,%eax |
|
160 |
decl %eax # End of string |
|
161 |
movl %edx,%edi # Restore |
|
162 |
ret
|
|
163 |
.strend_end:
|
|
164 |
.size strend,.strend_end-strend |
|
165 |
||
166 |
# Make a string with len fill-chars and endnull
|
|
167 |
# Args: dest,len,fill
|
|
168 |
# Ret: dest+len
|
|
169 |
||
170 |
.globl strfill |
|
171 |
.type strfill,@function |
|
172 |
strfill:
|
|
173 |
pushl %edi |
|
174 |
movl 8(%esp),%edi # Memory pointer |
|
175 |
movl 12(%esp),%ecx # Length |
|
176 |
movzb 16(%esp),%eax # Fill |
|
177 |
||
178 |
movb %al,%ah # (2) Set up a 32 bit pattern |
|
179 |
movw %ax,%dx # (2) |
|
180 |
shll $16,%eax # (3) |
|
181 |
movw %dx,%ax # (2) %eax has the 32 bit pattern. |
|
182 |
||
183 |
movl %ecx,%edx # (2) Save the count of bytes. |
|
184 |
shrl $2,%ecx # (2) Number of dwords. |
|
185 |
rep
|
|
186 |
stosl # (5 + 5n) |
|
187 |
movb $3,%cl # (2) |
|
188 |
and %edx,%ecx # (2) Fill in the odd bytes |
|
189 |
rep
|
|
190 |
stosb # Move last bytes if any |
|
191 |
||
192 |
movb %cl,(%edi) # End NULL |
|
193 |
movl %edi,%eax # End i %eax |
|
194 |
popl %edi |
|
195 |
ret
|
|
196 |
.strfill_end:
|
|
197 |
.size strfill,.strfill_end-strfill |
|
198 |
||
199 |
||
200 |
# Find a char in or end of a string
|
|
201 |
# Arg: str,char
|
|
202 |
# Ret: pointer to found char or NullS
|
|
203 |
||
204 |
.globl strcend |
|
205 |
.type strcend,@function |
|
206 |
strcend:
|
|
207 |
movl %edi,%edx |
|
208 |
movl 4(%esp),%edi # str |
|
209 |
movb 8(%esp),%ah # search |
|
210 |
clrb %al # for scasb to find end |
|
211 |
||
212 |
se_10: cmpb (%edi),%ah |
|
213 |
jz se_20 # Found char |
|
214 |
scasb
|
|
215 |
jnz se_10 # Not end |
|
216 |
dec %edi # Not found, point at end of string |
|
217 |
se_20: movl %edi,%eax |
|
218 |
movl %edx,%edi # Restore |
|
219 |
ret
|
|
220 |
.strcend_end:
|
|
221 |
.size strcend,.strcend_end-strcend |
|
222 |
||
223 |
# Test if string has a given suffix
|
|
224 |
||
225 |
.globl is_prefix |
|
226 |
.type is_prefix,@function |
|
227 |
is_prefix:
|
|
228 |
movl %edi,%edx # Save %edi |
|
229 |
pushl %esi # and %esi |
|
230 |
movl 12(%esp),%esi # get suffix |
|
231 |
movl 8(%esp),%edi # s1 |
|
232 |
movl $1,%eax # Ok and zero-test |
|
233 |
ip_10: cmpb (%esi),%ah |
|
234 |
jz suf_ok # End of string/ found suffix |
|
235 |
cmpsb # Compare strings |
|
236 |
jz ip_10 # Same, possible prefix |
|
237 |
xor %eax,%eax # Not suffix |
|
238 |
suf_ok: popl %esi |
|
239 |
movl %edx,%edi |
|
240 |
ret
|
|
241 |
.is_prefix_end:
|
|
242 |
.size is_prefix,.is_prefix_end-is_prefix |
|
243 |
||
244 |
# Find a substring in string
|
|
245 |
# Arg: str,search
|
|
246 |
||
247 |
.globl strstr |
|
248 |
.type strstr,@function |
|
249 |
||
250 |
strstr:
|
|
251 |
pushl %edi |
|
252 |
pushl %esi |
|
253 |
movl 12(%esp),%esi # str |
|
254 |
movl 16(%esp),%edi # search |
|
255 |
movl %edi,%ecx |
|
256 |
incl %ecx # %ecx = search+1 |
|
257 |
movb (%edi),%ah # %ah = First char in search |
|
258 |
jmp sf_10 |
|
259 |
||
260 |
sf_00: movl %edx,%esi # si = Current str-pos |
|
261 |
sf_10: movb (%esi),%al # Test if this char exist |
|
262 |
andb %al,%al |
|
263 |
jz sf_90 # End of string, didn't find search |
|
264 |
incl %esi |
|
265 |
cmpb %al,%ah |
|
266 |
jnz sf_10 # Didn't find first char, continue |
|
267 |
movl %esi,%edx # Save str-pos in %edx |
|
268 |
movl %ecx,%edi |
|
269 |
sf_20: cmpb $0,(%edi) |
|
270 |
jz sf_fo # Found substring |
|
271 |
cmpsb
|
|
272 |
jz sf_20 # Char ok |
|
273 |
jmp sf_00 # Next str-pos |
|
274 |
||
275 |
sf_90: movl $1,%edx # Return Null |
|
276 |
sf_fo: movl %edx,%eax # Char found here |
|
277 |
decl %eax # Pointed one after |
|
278 |
popl %esi |
|
279 |
popl %edi |
|
280 |
ret
|
|
281 |
.strstr_end:
|
|
282 |
.size strstr,.strstr_end-strstr |
|
283 |
||
284 |
||
285 |
# Find a substring in string, return index
|
|
286 |
# Arg: str,search
|
|
287 |
||
288 |
.globl strinstr |
|
289 |
.type strinstr,@function |
|
290 |
||
291 |
strinstr:
|
|
292 |
pushl %ebp |
|
293 |
movl %esp,%ebp |
|
294 |
pushl 12(%ebp) # search |
|
295 |
pushl 8(%ebp) # str |
|
296 |
call strstr |
|
297 |
add $8,%esp |
|
298 |
or %eax,%eax |
|
299 |
jz si_99 # Not found, return NULL |
|
300 |
sub 8(%ebp),%eax # Pos from start |
|
301 |
inc %eax # And first pos = 1 |
|
302 |
si_99: popl %ebp |
|
303 |
ret
|
|
304 |
.strinstr_end:
|
|
305 |
.size strinstr,.strinstr_end-strinstr |
|
306 |
||
307 |
# Make a string of len length from another string
|
|
308 |
# Arg: dst,src,length
|
|
309 |
# ret: end of dst
|
|
310 |
||
311 |
.globl strmake |
|
312 |
.type strmake,@function |
|
313 |
||
314 |
strmake:
|
|
315 |
pushl %edi |
|
316 |
pushl %esi |
|
317 |
mov 12(%esp),%edi # dst |
|
318 |
movl $0,%edx |
|
319 |
movl 20(%esp),%ecx # length |
|
320 |
movl 16(%esp),%esi # src |
|
321 |
cmpl %edx,%ecx |
|
322 |
jz sm_90 |
|
323 |
sm_00: movb (%esi,%edx),%al |
|
324 |
cmpb $0,%al |
|
325 |
jz sm_90 |
|
326 |
movb %al,(%edi,%edx) |
|
327 |
incl %edx |
|
328 |
cmpl %edx,%ecx |
|
329 |
jnz sm_00 |
|
330 |
sm_90: movb $0,(%edi,%edx) |
|
331 |
sm_99: lea (%edi,%edx),%eax # Return pointer to end null |
|
332 |
pop %esi |
|
333 |
pop %edi |
|
334 |
ret
|
|
335 |
.strmake_end:
|
|
336 |
.size strmake,.strmake_end-strmake |
|
337 |
||
338 |
# Move a string with max len chars
|
|
339 |
# arg: dst,src,len
|
|
340 |
# ret: pos to first null or dst+len
|
|
341 |
||
342 |
.globl strnmov |
|
343 |
.type strnmov,@function |
|
344 |
strnmov:
|
|
345 |
pushl %edi |
|
346 |
pushl %esi |
|
347 |
movl 12(%esp),%edi # dst |
|
348 |
movl 16(%esp),%esi # src |
|
349 |
movl 20(%esp),%ecx # Length of memory-area |
|
350 |
jecxz snm_99 # Nothing to do |
|
351 |
clrb %al # For test of end-null |
|
352 |
||
353 |
snm_10: cmpb (%esi),%al # Next char to move |
|
354 |
movsb # move arg |
|
355 |
jz snm_20 # last char, fill with null |
|
356 |
loop snm_10 # Continue moving |
|
357 |
incl %edi # Point two after last |
|
358 |
snm_20: decl %edi # Point at first null (or last+1) |
|
359 |
snm_99: movl %edi,%eax # Pointer at last char |
|
360 |
popl %esi |
|
361 |
popl %edi |
|
362 |
ret
|
|
363 |
.strnmov_end:
|
|
364 |
.size strnmov,.strnmov_end-strnmov |
|
365 |
||
366 |
||
367 |
.globl strmov |
|
368 |
.type strmov,@function |
|
369 |
strmov:
|
|
370 |
movl %esi,%ecx # Save old %esi and %edi |
|
371 |
movl %edi,%edx |
|
372 |
movl 8(%esp),%esi # get source pointer (s2) |
|
373 |
movl 4(%esp),%edi # %edi -> s1 |
|
374 |
smo_10: movb (%esi),%al |
|
375 |
movsb # move arg |
|
376 |
andb %al,%al |
|
377 |
jnz smo_10 # Not last |
|
378 |
movl %edi,%eax |
|
379 |
dec %eax |
|
380 |
movl %ecx,%esi # Restore |
|
381 |
movl %edx,%edi |
|
382 |
ret
|
|
383 |
.strmov_end:
|
|
384 |
.size strmov,.strmov_end-strmov |
|
385 |
||
386 |
.globl strxmov |
|
387 |
.type strxmov,@function |
|
388 |
strxmov:
|
|
389 |
movl %ebx,%edx # Save %ebx, %esi and %edi |
|
390 |
mov %esi,%ecx |
|
391 |
push %edi |
|
392 |
leal 8(%esp),%ebx # Get destination |
|
393 |
movl (%ebx),%edi |
|
394 |
xorb %al,%al |
|
395 |
jmp next_str # Handle source ebx+4 |
|
396 |
||
397 |
start_str:
|
|
398 |
movsb
|
|
399 |
cmpb -1(%edi),%al |
|
400 |
jne start_str |
|
401 |
decl %edi # Don't copy last null |
|
402 |
||
403 |
next_str:
|
|
404 |
addl $4,%ebx |
|
405 |
movl (%ebx),%esi |
|
406 |
orl %esi,%esi |
|
407 |
jne start_str |
|
408 |
movb %al,0(%edi) # Force last to ASCII 0 |
|
409 |
||
410 |
movl %edi,%eax # Return ptr to ASCII 0 |
|
411 |
pop %edi # Restore registers |
|
412 |
movl %ecx,%esi |
|
413 |
movl %edx,%ebx |
|
414 |
ret
|
|
415 |
.strxmov_end:
|
|
416 |
.size strxmov,.strxmov_end-strxmov |