summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-12-20 01:34:52 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-12-20 01:34:52 +0000
commitbd7510cc6b7ea453c1bc1c12949174f6324a6bdc (patch)
tree60cc6c9ef264264b208b3b70a7a2f54fc986fde4
parenta0da3cfbbff226c7792be30e2bb277386e7cd086 (diff)
string/i386/strncpy: faster i386 version (same code size), testing code
string/i386/*: formatiing and commentary tidying up
-rw-r--r--libc/string/i386/memchr.c2
-rw-r--r--libc/string/i386/memcpy.c6
-rw-r--r--libc/string/i386/memmove.c2
-rw-r--r--libc/string/i386/strncpy.c55
-rw-r--r--libc/string/i386/strnlen.c2
-rw-r--r--libc/string/i386/strrchr.c8
6 files changed, 47 insertions, 28 deletions
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 <string.h>
-/* 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__