Line 0
Link Here
|
|
|
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 |
#ifdef __PIC__ |
295 |
# undef __i686 /* gcc define gets in our way */ |
296 |
pushl %ebx |
297 |
call __i686.get_pc_thunk.bx |
298 |
addl $_GLOBAL_OFFSET_TABLE_, %ebx |
299 |
#endif |
300 |
pushl 12(%ebp) # search |
301 |
pushl 8(%ebp) # str |
302 |
#ifdef __PIC__ |
303 |
call strstr@PLT /*We need to be sure that ebx point to the got*/ |
304 |
#else |
305 |
call strstr |
306 |
#endif |
307 |
add $8,%esp |
308 |
or %eax,%eax |
309 |
jz si_99 # Not found, return NULL |
310 |
sub 8(%ebp),%eax # Pos from start |
311 |
inc %eax # And first pos = 1 |
312 |
si_99: |
313 |
#ifdef __PIC__ |
314 |
popl %ebx |
315 |
#endif |
316 |
popl %ebp |
317 |
ret |
318 |
.strinstr_end: |
319 |
.size strinstr,.strinstr_end-strinstr |
320 |
|
321 |
# Make a string of len length from another string |
322 |
# Arg: dst,src,length |
323 |
# ret: end of dst |
324 |
|
325 |
.globl strmake |
326 |
.type strmake,@function |
327 |
|
328 |
strmake: |
329 |
pushl %edi |
330 |
pushl %esi |
331 |
mov 12(%esp),%edi # dst |
332 |
movl $0,%edx |
333 |
movl 20(%esp),%ecx # length |
334 |
movl 16(%esp),%esi # src |
335 |
cmpl %edx,%ecx |
336 |
jz sm_90 |
337 |
sm_00: movb (%esi,%edx),%al |
338 |
cmpb $0,%al |
339 |
jz sm_90 |
340 |
movb %al,(%edi,%edx) |
341 |
incl %edx |
342 |
cmpl %edx,%ecx |
343 |
jnz sm_00 |
344 |
sm_90: movb $0,(%edi,%edx) |
345 |
sm_99: lea (%edi,%edx),%eax # Return pointer to end null |
346 |
pop %esi |
347 |
pop %edi |
348 |
ret |
349 |
.strmake_end: |
350 |
.size strmake,.strmake_end-strmake |
351 |
|
352 |
# Move a string with max len chars |
353 |
# arg: dst,src,len |
354 |
# ret: pos to first null or dst+len |
355 |
|
356 |
.globl strnmov |
357 |
.type strnmov,@function |
358 |
strnmov: |
359 |
pushl %edi |
360 |
pushl %esi |
361 |
movl 12(%esp),%edi # dst |
362 |
movl 16(%esp),%esi # src |
363 |
movl 20(%esp),%ecx # Length of memory-area |
364 |
jecxz snm_99 # Nothing to do |
365 |
clrb %al # For test of end-null |
366 |
|
367 |
snm_10: cmpb (%esi),%al # Next char to move |
368 |
movsb # move arg |
369 |
jz snm_20 # last char, fill with null |
370 |
loop snm_10 # Continue moving |
371 |
incl %edi # Point two after last |
372 |
snm_20: decl %edi # Point at first null (or last+1) |
373 |
snm_99: movl %edi,%eax # Pointer at last char |
374 |
popl %esi |
375 |
popl %edi |
376 |
ret |
377 |
.strnmov_end: |
378 |
.size strnmov,.strnmov_end-strnmov |
379 |
|
380 |
|
381 |
.globl strmov |
382 |
.type strmov,@function |
383 |
strmov: |
384 |
movl %esi,%ecx # Save old %esi and %edi |
385 |
movl %edi,%edx |
386 |
movl 8(%esp),%esi # get source pointer (s2) |
387 |
movl 4(%esp),%edi # %edi -> s1 |
388 |
smo_10: movb (%esi),%al |
389 |
movsb # move arg |
390 |
andb %al,%al |
391 |
jnz smo_10 # Not last |
392 |
movl %edi,%eax |
393 |
dec %eax |
394 |
movl %ecx,%esi # Restore |
395 |
movl %edx,%edi |
396 |
ret |
397 |
.strmov_end: |
398 |
.size strmov,.strmov_end-strmov |
399 |
|
400 |
.globl strxmov |
401 |
.type strxmov,@function |
402 |
strxmov: |
403 |
movl %ebx,%edx # Save %ebx, %esi and %edi |
404 |
mov %esi,%ecx |
405 |
push %edi |
406 |
leal 8(%esp),%ebx # Get destination |
407 |
movl (%ebx),%edi |
408 |
xorb %al,%al |
409 |
jmp next_str # Handle source ebx+4 |
410 |
|
411 |
start_str: |
412 |
movsb |
413 |
cmpb -1(%edi),%al |
414 |
jne start_str |
415 |
decl %edi # Don't copy last null |
416 |
|
417 |
next_str: |
418 |
addl $4,%ebx |
419 |
movl (%ebx),%esi |
420 |
orl %esi,%esi |
421 |
jne start_str |
422 |
movb %al,0(%edi) # Force last to ASCII 0 |
423 |
|
424 |
movl %edi,%eax # Return ptr to ASCII 0 |
425 |
pop %edi # Restore registers |
426 |
movl %ecx,%esi |
427 |
movl %edx,%ebx |
428 |
ret |
429 |
.strxmov_end: |
430 |
.size strxmov,.strxmov_end-strxmov |
431 |
|
432 |
#ifdef __PIC__ |
433 |
.section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits |
434 |
.globl __i686.get_pc_thunk.bx |
435 |
.hidden __i686.get_pc_thunk.bx |
436 |
.type __i686.get_pc_thunk.bx,@function |
437 |
__i686.get_pc_thunk.bx: |
438 |
movl (%esp), %ebx |
439 |
ret |
440 |
#endif |
441 |
.section .note.GNU-stack,"",@progbits |
442 |
|