Browse Source

string/i386/strncpy: faster i386 version (same code size), testing code
string/i386/*: formatiing and commentary tidying up

Denis Vlasenko 16 years ago
parent
commit
bd7510cc6b

+ 1 - 1
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()

+ 3 - 3
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)

+ 1 - 1
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()

+ 37 - 18
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

+ 1 - 1
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()

+ 4 - 4
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__