mariadb/strings/strings-x86.s

407 lines
9.7 KiB
ArmAsm
Raw Normal View History

2000-07-31 21:29:14 +02:00
/* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* Optimized string functions Intel 80x86 (gcc/gas syntax) */
.file "strings.s"
.version "1.00"
.text
/* Move a alligned, not overlapped, by (long) divided memory area */
/* Args: to,from,length */
.globl bmove_allign
.type bmove_allign,@function
bmove_allign:
movl %edi,%edx
movl %esi,%eax
movl 4(%esp),%edi /* to */
movl 8(%esp),%esi /* from */
movl 12(%esp),%ecx /* length */
addw $3,%cx /* fix if not divisible with long */
shrw $2,%cx
rep
movsl
movl %eax,%esi
movl %edx,%edi
ret
.end:
.size bmove_allign,.end-bmove_allign
/* Move a string from higher to lower */
/* Arg from+1,to+1,length */
.globl bmove_upp
.type bmove_upp,@function
bmove_upp:
std /* Work downward */
movl %edi,%edx
movl %esi,%eax
movl 4(%esp),%edi /* p1 */
movl 8(%esp),%esi /* p2 */
movl 12(%esp),%ecx /* length */
decl %edi /* Don't move last arg */
decl %esi
rep
movsb /* One byte a time because overlap */
cld /* C library wants cld */
movl %eax,%esi
movl %edx,%edi
ret
.bmove_upp_end:
.size bmove_upp,.bmove_upp_end-bmove_upp
/* Append fillchars to string */
/* Args: dest,len,fill */
.globl strappend
.type strappend,@function
strappend:
pushl %edi
movl 8(%esp),%edi /* Memory pointer */
movl 12(%esp),%ecx /* Length */
clrl %eax /* Find end of string */
repne
scasb
jnz sa_99 /* String to long, shorten it */
movzb 16(%esp),%eax /* Fillchar */
decl %edi /* Point at end null */
incl %ecx /* rep made one dec for null-char */
movb %al,%ah /* (2) Set up a 32 bit pattern. */
movw %ax,%dx /* (2) */
shll $16,%eax /* (3) */
movw %dx,%ax /* (2) %eax has the 32 bit pattern. */
movl %ecx,%edx /* (2) Save the count of bytes. */
shrl $2,%ecx /* (2) Number of dwords. */
rep
stosl /* (5 + 5n) */
movb $3,%cl /* (2) */
and %edx,%ecx /* (2) Fill in the odd bytes*/
rep
stosb /* Move last bytes if any */
sa_99: movb $0,(%edi) /* End of string */
popl %edi
ret
.strappend_end:
.size strappend,.strappend_end-strappend
/* Find if string contains any char in another string */
/* Arg: str,set */
/* Ret: Pointer to first found char in str */
.globl strcont
.type strcont,@function
strcont:
movl %edi,%edx
pushl %esi
movl 8(%esp),%esi /* str */
movl 12(%esp),%ecx /* set */
clrb %ah /* For endtest */
jmp sc_60
sc_10: scasb
jz sc_fo /* Found char */
sc_20: cmp (%edi),%ah /* Test if null */
jnz sc_10 /* Not end of set yet */
incl %esi /* Next char in str */
sc_60: movl %ecx,%edi /* %edi = Set */
movb (%esi),%al /* Test if this char exist */
andb %al,%al
jnz sc_20 /* Not end of string */
clrl %esi /* Return Null */
sc_fo: movl %esi,%eax /* Char found here */
movl %edx,%edi /* Restore */
popl %esi
ret
.strcont_end:
.size strcont,.strcont_end-strcont
/* Find end of string */
/* Arg: str */
/* ret: Pointer to end null */
.globl strend
.type strend,@function
strend:
movl %edi,%edx /* Save */
movl 4(%esp),%edi /* str */
clrl %eax /* Find end of string */
movl %eax,%ecx
decl %ecx /* ECX = -1 */
repne
scasb
movl %edi,%eax
decl %eax /* End of string */
movl %edx,%edi /* Restore */
ret
.strend_end:
.size strend,.strend_end-strend
/* Make a string with len fill-chars and endnull */
/* Args: dest,len,fill */
/* Ret: dest+len */
.globl strfill
.type strfill,@function
strfill:
pushl %edi
movl 8(%esp),%edi /* Memory pointer */
movl 12(%esp),%ecx /* Length */
movzb 16(%esp),%eax /* Fill */
movb %al,%ah /* (2) Set up a 32 bit pattern */
movw %ax,%dx /* (2) */
shll $16,%eax /* (3) */
movw %dx,%ax /* (2) %eax has the 32 bit pattern. */
movl %ecx,%edx /* (2) Save the count of bytes. */
shrl $2,%ecx /* (2) Number of dwords. */
rep
stosl /* (5 + 5n) */
movb $3,%cl /* (2) */
and %edx,%ecx /* (2) Fill in the odd bytes */
rep
stosb /* Move last bytes if any */
movb %cl,(%edi) /* End NULL */
movl %edi,%eax /* End i %eax */
popl %edi
ret
.strfill_end:
.size strfill,.strfill_end-strfill
/* Find a char in or end of a string */
/* Arg: str,char */
/* Ret: pointer to found char or NullS */
.globl strcend
.type strcend,@function
strcend:
movl %edi,%edx
movl 4(%esp),%edi /* str */
movb 8(%esp),%ah /* search */
clrb %al /* for scasb to find end */
se_10: cmpb (%edi),%ah
jz se_20 /* Found char */
scasb
jnz se_10 /* Not end */
dec %edi /* Not found, point at end of string */
se_20: movl %edi,%eax
movl %edx,%edi /* Restore */
ret
.strcend_end:
.size strcend,.strcend_end-strcend
/* Test if string has a given suffix */
.globl is_prefix
.type is_prefix,@function
is_prefix:
movl %edi,%edx /* Save %edi */
pushl %esi /* and %esi */
movl 12(%esp),%esi /* get suffix */
movl 8(%esp),%edi /* s1 */
movl $1,%eax /* Ok and zero-test */
ip_10: cmpb (%esi),%ah
jz suf_ok /* End of string/ found suffix */
cmpsb /* Compare strings */
jz ip_10 /* Same, possible prefix */
xor %eax,%eax /* Not suffix */
suf_ok: popl %esi
movl %edx,%edi
ret
.is_prefix_end:
.size is_prefix,.is_prefix_end-is_prefix
/* Find a substring in string */
/* Arg: str,search */
.globl strstr
.type strstr,@function
strstr:
pushl %edi
pushl %esi
movl 12(%esp),%esi /* str */
movl 16(%esp),%edi /* search */
movl %edi,%ecx
incl %ecx /* %ecx = search+1 */
movb (%edi),%ah /* %ah = First char in search */
jmp sf_10
sf_00: movl %edx,%esi /* si = Current str-pos */
sf_10: movb (%esi),%al /* Test if this char exist */
andb %al,%al
jz sf_90 /* End of string, didn't find search */
incl %esi
cmpb %al,%ah
jnz sf_10 /* Didn't find first char, continue */
movl %esi,%edx /* Save str-pos in %edx */
movl %ecx,%edi
sf_20: cmpb $0,(%edi)
jz sf_fo /* Found substring */
cmpsb
jz sf_20 /* Char ok */
jmp sf_00 /* Next str-pos */
sf_90: movl $1,%edx /* Return Null */
sf_fo: movl %edx,%eax /* Char found here */
decl %eax /* Pointed one after */
popl %esi
popl %edi
ret
.strstr_end:
.size strstr,.strstr_end-strstr
/* Find a substring in string, return index */
/* Arg: str,search */
.globl strinstr
.type strinstr,@function
strinstr:
pushl %ebp
movl %esp,%ebp
pushl 12(%ebp) /* search */
pushl 8(%ebp) /* str */
call strstr
add $8,%esp
or %eax,%eax
jz si_99 /* Not found, return NULL */
sub 8(%ebp),%eax /* Pos from start */
inc %eax /* And first pos = 1 */
si_99: popl %ebp
ret
.strinstr_end:
.size strinstr,.strinstr_end-strinstr
/* Make a string of len length from another string */
/* Arg: dst,src,length */
/* ret: end of dst */
.globl strmake
.type strmake,@function
strmake:
pushl %edi
pushl %esi
movl 12(%esp),%edi /* dst */
movl 16(%esp),%esi /* src */
movl 20(%esp),%ecx /* Length of memory-area */
clrb %al /* For test of end-null */
jecxz sm_90 /* Nothing to move, put zero at end. */
sm_10: cmpb (%esi),%al /* Next char to move */
movsb /* move arg */
jz sm_99 /* last char, we are ready */
loop sm_10 /* Continue moving */
sm_90: movb %al,(%edi) /* Set end pos */
incl %edi /* Fix that di points at end null */
sm_99: decl %edi /* di points now at end null */
movl %edi,%eax /* Ret value.p $ */
popl %esi
popl %edi
ret
.strmake_end:
.size strmake,.strmake_end-strmake
/* Move a string with max len chars */
/* arg: dst,src,len */
/* ret: pos to first null or dst+len */
.globl strnmov
.type strnmov,@function
strnmov:
pushl %edi
pushl %esi
movl 12(%esp),%edi /* dst */
movl 16(%esp),%esi /* src */
movl 20(%esp),%ecx /* Length of memory-area */
jecxz snm_99 /* Nothing to do */
clrb %al /* For test of end-null */
snm_10: cmpb (%esi),%al /* Next char to move */
movsb /* move arg */
jz snm_20 /* last char, fill with null */
loop snm_10 /* Continue moving */
incl %edi /* Point two after last */
snm_20: decl %edi /* Point at first null (or last+1) */
snm_99: movl %edi,%eax /* Pointer at last char */
popl %esi
popl %edi
ret
.strnmov_end:
.size strnmov,.strnmov_end-strnmov
.globl strmov
.type strmov,@function
strmov:
movl %esi,%ecx /* Save old %esi and %edi */
movl %edi,%edx
movl 8(%esp),%esi /* get source pointer (s2) */
movl 4(%esp),%edi /* %edi -> s1 */
smo_10: movb (%esi),%al
movsb /* move arg */
andb %al,%al
jnz smo_10 /* Not last */
movl %edi,%eax
dec %eax
movl %ecx,%esi /* Restore */
movl %edx,%edi
ret
.strmov_end:
.size strmov,.strmov_end-strmov
.globl strxmov
.type strxmov,@function
strxmov:
movl %ebx,%edx /* Save %ebx, %esi and %edi */
mov %esi,%ecx
push %edi
leal 8(%esp),%ebx /* Get destination */
movl (%ebx),%edi
xorb %al,%al
jmp next_str /* Handle source ebx+4 */
start_str:
movsb
cmpb -1(%edi),%al
jne start_str
decl %edi /* Don't copy last null */
next_str:
addl $4,%ebx
movl (%ebx),%esi
orl %esi,%esi
jne start_str
movb %al,0(%edi) /* Force last to ASCII 0 */
movl %edi,%eax /* Return ptr to ASCII 0 */
pop %edi /* Restore registers */
movl %ecx,%esi
movl %edx,%ebx
ret
.strxmov_end:
.size strxmov,strxmov_end-strxmov