Messages in this thread Patch in this message | | | Date | Thu, 28 Oct 1999 15:57:15 -0400 | From | Brad Proctor <> | Subject | [PATCH] strlen |
| |
Here is an optimized strlen function for i586+ processors, it works by testing 4 bytes at a time and averages 1.8 clock cycles per byte (scas = 4n).
I made the patch apply to string-486.h, but it might belong in string.h too, since string.h is for i686 processors.
Brad Proctordiff -urN linux-2.3.24/include/asm-i386/string-486.h linux/include/asm-i486/string-486.h --- linux-2.3.24/include/asm-i386/string-486.h Wed Oct 27 20:34:41 1999 +++ linux/include/asm-i386/string-486.h Thu Oct 28 15:22:08 1999 @@ -326,21 +326,34 @@ extern inline size_t strlen(const char * s) { /* - * slightly slower on a 486, but with better chances of - * register allocation + * This function works by testing 4 bytes at a time + * and averages 1.8 clock cycles per byte. */ -register char dummy, *tmp= (char *)s; -__asm__ __volatile__( - "\n1:\t" - "movb\t(%0),%1\n\t" - "incl\t%0\n\t" - "testb\t%1,%1\n\t" - "jne\t1b" - :"=r" (tmp),"=q" (dummy) - :"0" (s) - : "memory" ); -return (tmp-s-1); +register int __res; +__asm__ __volatile__ ( + "addl %0,%2\n\t" + "movl (%0),%%ebx\n\t" + "addl $4,%0\n\t" + ".align 2\n\t" + "1:leal -0x1010101(%%ebx),%%ecx\n\t" + "xorl $-1,%%ebx\n\t" + "andl %%ebx,%%ecx\n\t" + "movl (%0),%%ebx\n\t" + "addl $4,%0\n\t" + "andl $0x80808080,%%ecx\n\t" + "jz 1b\n\t" + "testl $0x8080,%%ecx\n\t" + "jnz 1f\n\t" + "shrl $16,%%ecx\n\t" + "addl $2,%0\n\t" + "1:shlb $1,%%cl\n\t" + "sbbl %2,%0\n\t" + : "=r" (__res) + : "0" (s), "r" (7) + : "ebx", "ecx"); +return (__res); } + /* Added by Gertjan van Wingerde to make minix and sysv module work */ #define __HAVE_ARCH_STRNLEN
| |