summaryrefslogtreecommitdiff
path: root/strings/strings-x86.s
diff options
context:
space:
mode:
Diffstat (limited to 'strings/strings-x86.s')
-rw-r--r--strings/strings-x86.s406
1 files changed, 406 insertions, 0 deletions
diff --git a/strings/strings-x86.s b/strings/strings-x86.s
new file mode 100644
index 00000000000..5d7cbde1b38
--- /dev/null
+++ b/strings/strings-x86.s
@@ -0,0 +1,406 @@
+/* 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