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