diff -urN a/configure b/configure --- a/configure 2010-11-09 19:40:54.435000074 +0100 +++ b/configure 2010-11-09 19:45:58.987000075 +0100 @@ -20321,7 +20321,7 @@ { $as_echo "$as_me:$LINENO: checking if we should use assembler functions" >&5 $as_echo_n "checking if we should use assembler functions... " >&6; } # For now we only support assembler on i386 and sparc systems - if test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $AS strings/strings-x86.s -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;); then + if test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $AS strings/strings-x86.S -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;); then ASSEMBLER_x86_TRUE= ASSEMBLER_x86_FALSE='#' else diff -urN a/configure.in b/configure.in --- a/configure.in 2010-11-09 19:40:54.436000076 +0100 +++ b/configure.in 2010-11-09 19:45:44.978000081 +0100 @@ -673,7 +673,7 @@ AC_MSG_CHECKING(if we should use assembler functions) # For now we only support assembler on i386 and sparc systems -AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $AS strings/strings-x86.s -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;)) +AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $AS strings/strings-x86.S -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;)) AM_CONDITIONAL(ASSEMBLER_sparc32, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparc") AM_CONDITIONAL(ASSEMBLER_sparc64, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparcv9") AM_CONDITIONAL(ASSEMBLER, test "$ASSEMBLER_x86_TRUE" = "" -o "$ASSEMBLER_sparc32_TRUE" = "") diff -urN a/strings/Makefile.am b/strings/Makefile.am --- a/strings/Makefile.am 2010-11-09 19:41:43.054000076 +0100 +++ b/strings/Makefile.am 2010-11-09 19:47:11.763000074 +0100 @@ -20,7 +20,7 @@ # Exact one of ASSEMBLER_X if ASSEMBLER_x86 -ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s +ASRCS = strings-x86.S longlong2str-x86.s my_strtoll10-x86.s CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c my_strchr.c strmov.c else if ASSEMBLER_sparc32 @@ -44,7 +44,7 @@ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \ ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \ ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \ - xml.c decimal.c strto.c strings-x86.s \ + xml.c decimal.c strto.c strings-x86.S \ longlong2str.c longlong2str-x86.s longlong2str_asm.c \ my_strtoll10.c my_strtoll10-x86.s \ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \ diff -urN a/strings/Makefile.in b/strings/Makefile.in --- a/strings/Makefile.in 2010-11-09 19:41:43.058000076 +0100 +++ b/strings/Makefile.in 2010-11-09 19:46:43.318000076 +0100 @@ -87,7 +87,7 @@ libmystrings_a_DEPENDENCIES = am__libmystrings_a_SOURCES_DIST = bmove_upp-sparc.s strappend-sparc.s \ strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s \ - strnmov-sparc.s strstr-sparc.s strings-x86.s \ + strnmov-sparc.s strstr-sparc.s strings-x86.S \ longlong2str-x86.s my_strtoll10-x86.s strxmov.c bmove_upp.c \ strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c \ strstr.c strinstr.c strmake.c strnmov.c strmov.c \ @@ -585,7 +585,7 @@ @ASSEMBLER_sparc32_TRUE@@ASSEMBLER_x86_FALSE@ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s # Exact one of ASSEMBLER_X -@ASSEMBLER_x86_TRUE@ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s +@ASSEMBLER_x86_TRUE@ASRCS = strings-x86.S longlong2str-x86.s my_strtoll10-x86.s # These file MUST all be on the same line!! Otherwise automake # generats a very broken makefile @ASSEMBLER_sparc32_FALSE@@ASSEMBLER_x86_FALSE@CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c @@ -597,7 +597,7 @@ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \ ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \ ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \ - xml.c decimal.c strto.c strings-x86.s \ + xml.c decimal.c strto.c strings-x86.S \ longlong2str.c longlong2str-x86.s longlong2str_asm.c \ my_strtoll10.c my_strtoll10-x86.s \ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \ diff -urN a/strings/strings-x86.s b/strings/strings-x86.s --- a/strings/strings-x86.s 2010-11-09 19:41:43.049000076 +0100 +++ b/strings/strings-x86.s 1970-01-01 01:00:00.000000000 +0100 @@ -1,416 +0,0 @@ -# Copyright (C) 2000 MySQL 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; version 2 of the License. -# -# 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_align - .type bmove_align,@function -bmove_align: - movl %edi,%edx - push %esi - 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 - jz .ba_20 - .p2align 4,,7 -.ba_10: - movl -4(%esi,%ecx),%eax - movl %eax,-4(%edi,%ecx) - decl %ecx - jnz .ba_10 -.ba_20: pop %esi - movl %edx,%edi - ret - -.bmove_align_end: - .size bmove_align,.bmove_align_end-bmove_align - - # Move a string from higher to lower - # Arg from_end+1,to_end+1,length - -.globl bmove_upp - .type bmove_upp,@function -bmove_upp: - movl %edi,%edx # Remember %edi - push %esi - movl 8(%esp),%edi # dst - movl 16(%esp),%ecx # length - movl 12(%esp),%esi # source - test %ecx,%ecx - jz .bu_20 - subl %ecx,%esi # To start of strings - subl %ecx,%edi - - .p2align 4,,7 -.bu_10: movb -1(%esi,%ecx),%al - movb %al,-1(%edi,%ecx) - decl %ecx - jnz .bu_10 -.bu_20: pop %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 - mov 12(%esp),%edi # dst - movl $0,%edx - movl 20(%esp),%ecx # length - movl 16(%esp),%esi # src - cmpl %edx,%ecx - jz sm_90 -sm_00: movb (%esi,%edx),%al - cmpb $0,%al - jz sm_90 - movb %al,(%edi,%edx) - incl %edx - cmpl %edx,%ecx - jnz sm_00 -sm_90: movb $0,(%edi,%edx) -sm_99: lea (%edi,%edx),%eax # Return pointer to end null - pop %esi - pop %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 diff -urN a/strings/strings-x86.S b/strings/strings-x86.S --- a/strings/strings-x86.S 1970-01-01 01:00:00.000000000 +0100 +++ b/strings/strings-x86.S 2010-11-09 19:36:41.841000076 +0100 @@ -0,0 +1,440 @@ +# Copyright (C) 2000 MySQL 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; version 2 of the License. +# +# 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_align + .type bmove_align,@function +bmove_align: + movl %edi,%edx + push %esi + 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 + jz .ba_20 + .p2align 4,,7 +.ba_10: + movl -4(%esi,%ecx),%eax + movl %eax,-4(%edi,%ecx) + decl %ecx + jnz .ba_10 +.ba_20: pop %esi + movl %edx,%edi + ret + +.bmove_align_end: + .size bmove_align,.bmove_align_end-bmove_align + + # Move a string from higher to lower + # Arg from_end+1,to_end+1,length + +.globl bmove_upp + .type bmove_upp,@function +bmove_upp: + movl %edi,%edx # Remember %edi + push %esi + movl 8(%esp),%edi # dst + movl 16(%esp),%ecx # length + movl 12(%esp),%esi # source + test %ecx,%ecx + jz .bu_20 + subl %ecx,%esi # To start of strings + subl %ecx,%edi + + .p2align 4,,7 +.bu_10: movb -1(%esi,%ecx),%al + movb %al,-1(%edi,%ecx) + decl %ecx + jnz .bu_10 +.bu_20: pop %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 +#ifdef __PIC__ +# undef __i686 /* gcc define gets in our way */ + pushl %ebx + call __i686.get_pc_thunk.bx + addl $_GLOBAL_OFFSET_TABLE_, %ebx +#endif + pushl 12(%ebp) # search + pushl 8(%ebp) # str +#ifdef __PIC__ + call strstr@PLT /*We need to be sure that ebx point to the got*/ +#else + call strstr +#endif + 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: +#ifdef __PIC__ + popl %ebx +#endif + 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 + mov 12(%esp),%edi # dst + movl $0,%edx + movl 20(%esp),%ecx # length + movl 16(%esp),%esi # src + cmpl %edx,%ecx + jz sm_90 +sm_00: movb (%esi,%edx),%al + cmpb $0,%al + jz sm_90 + movb %al,(%edi,%edx) + incl %edx + cmpl %edx,%ecx + jnz sm_00 +sm_90: movb $0,(%edi,%edx) +sm_99: lea (%edi,%edx),%eax # Return pointer to end null + pop %esi + pop %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 + +#ifdef __PIC__ + .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits +.globl __i686.get_pc_thunk.bx + .hidden __i686.get_pc_thunk.bx + .type __i686.get_pc_thunk.bx,@function +__i686.get_pc_thunk.bx: + movl (%esp), %ebx + ret +#endif