From bd7510cc6b7ea453c1bc1c12949174f6324a6bdc Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sat, 20 Dec 2008 01:34:52 +0000 Subject: string/i386/strncpy: faster i386 version (same code size), testing code string/i386/*: formatiing and commentary tidying up --- libc/string/i386/memchr.c | 2 +- libc/string/i386/memcpy.c | 6 ++--- libc/string/i386/memmove.c | 2 +- libc/string/i386/strncpy.c | 55 +++++++++++++++++++++++++++++++--------------- libc/string/i386/strnlen.c | 2 +- libc/string/i386/strrchr.c | 8 +++---- 6 files changed, 47 insertions(+), 28 deletions(-) (limited to 'libc/string') diff --git a/libc/string/i386/memchr.c b/libc/string/i386/memchr.c index 772251cee..c2fc44b4a 100644 --- a/libc/string/i386/memchr.c +++ b/libc/string/i386/memchr.c @@ -55,7 +55,7 @@ void *memchr(const void *s, int c, size_t count) #ifndef memchr libc_hidden_def(memchr) #else -/* Uncomment TESTING, gcc -D__USE_GNU -m32 -Os memchr.c -o memchr +/* Uncomment TESTING, gcc -D_GNU_SOURCE -m32 -Os memchr.c -o memchr * and run ./memchr */ int main() diff --git a/libc/string/i386/memcpy.c b/libc/string/i386/memcpy.c index af86cf255..697d0bdc2 100644 --- a/libc/string/i386/memcpy.c +++ b/libc/string/i386/memcpy.c @@ -38,11 +38,11 @@ void *memcpy(void * to, const void * from, size_t n) int d0, d1, d2; __asm__ __volatile__( " rep; movsl\n" - " movl %4,%%ecx\n" - " andl $3,%%ecx\n" + " movl %4, %%ecx\n" + " andl $3, %%ecx\n" /* jz is optional. avoids "rep; movsb" with ecx == 0, * but adds a branch, which is currently (2008) faster */ - " jz 1f\n" + " jz 1f\n" " rep; movsb\n" "1:\n" : "=&c" (d0), "=&D" (d1), "=&S" (d2) diff --git a/libc/string/i386/memmove.c b/libc/string/i386/memmove.c index cd746e804..72d8002a5 100644 --- a/libc/string/i386/memmove.c +++ b/libc/string/i386/memmove.c @@ -57,7 +57,7 @@ void *memmove(void *dest, const void *src, size_t n) #ifndef memmove libc_hidden_def(memmove) #else -/* Uncomment TESTING, gcc -D__USE_GNU -m32 -Os memmove.c -o memmove +/* Uncomment TESTING, gcc -D_GNU_SOURCE -m32 -Os memmove.c -o memmove * and run ./memmove */ int main() diff --git a/libc/string/i386/strncpy.c b/libc/string/i386/strncpy.c index 76aa6ae1b..ba0c41063 100644 --- a/libc/string/i386/strncpy.c +++ b/libc/string/i386/strncpy.c @@ -32,25 +32,44 @@ #include -/* Experimentally off - libc_hidden_proto(strncpy) */ +#undef strncpy +//#define strncpy TESTING char *strncpy(char * dest, const char * src, size_t count) { - int d0, d1, d2, d3; - __asm__ __volatile__( - "incl %2\n" - "1:\n" - "decl %2\n" - "jz 2f\n" - "lodsb\n\t" - "stosb\n\t" - "testb %%al,%%al\n\t" - "jne 1b\n\t" - "decl %2\n" - "rep\n\t" - "stosb\n" - "2:" - : "=&S" (d0), "=&D" (d1), "=&c" (d2), "=&a" (d3) - :"0" (src),"1" (dest),"2" (count) : "memory"); - return dest; + int esi, edi, ecx, eax; + __asm__ __volatile__( + "1: subl $1, %%ecx\n" /* not dec! it doesnt set CF */ + " jc 2f\n" + " lodsb\n" + " stosb\n" + " testb %%al, %%al\n" + " jnz 1b\n" + " rep; stosb\n" + "2:\n" + : "=&S" (esi), "=&D" (edi), "=&c" (ecx), "=&a" (eax) + : "0" (src), "1" (dest), "2" (count) + : "memory" + ); + return dest; } +#ifndef strncpy libc_hidden_def(strncpy) +#else +/* Uncomment TESTING, gcc -D_GNU_SOURCE -m32 -Os strncpy.c -o strncpy + * and run ./strncpy + */ +int main() +{ + static char str[99]; + + str[3] = '*'; str[4] = 0; strncpy(str, "abc", 3); + printf(strcmp(str, "abc*") == 0 ? "ok\n" : "BAD!\n"); + + str[4] = '*'; str[5] = '+'; strncpy(str, "abc", 5); + printf(strcmp(str, "abc") == 0 && str[4] == 0 && str[5] == '+' ? + "ok\n" : "BAD!\n"); + strncpy(str, "abc", 0); /* should do nothing */ + printf(strcmp(str, "abc") == 0 && str[4] == 0 && str[5] == '+' ? + "ok\n" : "BAD!\n"); +} +#endif diff --git a/libc/string/i386/strnlen.c b/libc/string/i386/strnlen.c index d9bce6485..3abde48e2 100644 --- a/libc/string/i386/strnlen.c +++ b/libc/string/i386/strnlen.c @@ -56,7 +56,7 @@ size_t strnlen(const char *s, size_t count) #ifndef strnlen libc_hidden_def(strnlen) #else -/* Uncomment TESTING, gcc -D__USE_GNU -m32 -Os strnlen.c -o strnlen +/* Uncomment TESTING, gcc -D_GNU_SOURCE -m32 -Os strnlen.c -o strnlen * and run ./strnlen */ int main() diff --git a/libc/string/i386/strrchr.c b/libc/string/i386/strrchr.c index 3209b1d76..9f2c74923 100644 --- a/libc/string/i386/strrchr.c +++ b/libc/string/i386/strrchr.c @@ -35,23 +35,23 @@ /* Experimentally off - libc_hidden_proto(strrchr) */ char *strrchr(const char *s, int c) { - char *retval; + char *eax; __asm__ __volatile__( " movb %%cl, %%ch\n" "1: movb (%1), %%cl\n" /* load char */ " cmpb %%cl, %%ch\n" /* char == c? */ " jne 2f\n" - " movl %1, %0\n" + " movl %1, %%eax\n" "2: incl %1\n" " testb %%cl, %%cl\n" /* char == NUL? */ " jnz 1b\n" /* "=c": use ecx, not ebx (-fpic uses it). */ - : "=a" (retval), "=r" (s), "=c" (c) + : "=a" (eax), "=r" (s), "=c" (c) : "0" (0), "1" (s), "2" (c) /* : no clobbers */ ); - return retval; + return eax; } libc_hidden_def(strrchr) #ifdef __UCLIBC_SUSV3_LEGACY__ -- cgit v1.2.3