This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] i386: Fix GCC running out of registers for bits/string.h


On Thu, 9 Jun 2005, Denis Vlasenko wrote:

> > Because of the pushl there, __reject's constraint must not allow
> > memory, as say 16(%esp) is valid "m" (as well as "g") operand,
> > but as GCC doesn't know about the pushl, it would use a wrong value.

 Good point -- it might also be based on %ebx, which would be equally bad.

> Can be rewritten to use local temp var instead of hardcoded %ebx.
> gcc will save/restore it then, if needed.

 It can and I have done it, see below.  But GCC is unhappy again.

> Also register keywords are anachronism. May be removed.

 That's secondary, but obviously it won't hurt.  Note that it's not 
universally true -- GCC still requires the keyword for explicit register 
variables for their bindings to be respected.

 Here's a new version of the fix, but with it I get:

md5-crypt.c: In function '__md5_crypt_r': 
../sysdeps/i386/bits/string.h:655: error: can't find a register in class 'GENERAL_REGS' while reloading 'asm'

for md5-crypt.os (that is for strcspn()).  Now that I would consider a bug 
in GCC -- replacing the "g" constraint with "m" for "__d3" makes the error 
go away, but it sort of defeats the purpose of that asm in the first 
place.

2005-06-09  Maciej W. Rozycki  <macro@linux-mips.org>

	* sysdeps/i386/bits/string.h (strcspn): Lower the register 
	pressure for the asm.
	(strspn): Likewise.
	(strpbrk): Likewise.
	(strstr): Likewise.

 Any suggestions?  If none, I guess I'll file a bug report against GCC.

  Maciej

glibc-2.3.5-i386-string.patch
diff -up --recursive --new-file glibc-2.3.5.macro/sysdeps/i386/bits/string.h glibc-2.3.5/sysdeps/i386/bits/string.h
--- glibc-2.3.5.macro/sysdeps/i386/bits/string.h	2004-06-15 20:11:53.000000000 +0000
+++ glibc-2.3.5/sysdeps/i386/bits/string.h	2005-06-08 22:29:51.000000000 +0000
@@ -650,28 +650,26 @@ __strchrnul_c (__const char *__s, int __
 __STRING_INLINE size_t
 strcspn (__const char *__s, __const char *__reject)
 {
-  register unsigned long int __d0, __d1, __d2;
+  register unsigned long int __d0, __d1, __d2, __d3;
   register char *__res;
   __asm__ __volatile__
-    ("pushl	%%ebx\n\t"
-     "cld\n\t"
-     "movl	%4,%%edi\n\t"
+    ("cld\n\t"
+     "movl	%5,%%edi\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
      "decl	%%ecx\n\t"
-     "movl	%%ecx,%%ebx\n"
+     "movl	%%ecx,%4\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
-     "movl	%%ebx,%%ecx\n\t"
+     "movl	%5,%%edi\n\t"
+     "movl	%4,%%ecx\n\t"
      "repne; scasb\n\t"
      "jne	1b\n"
-     "2:\n\t"
-     "popl	%%ebx"
-     : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
-     : "d" (__reject), "0" (__s), "1" (0), "2" (0xffffffff),
+     "2:"
+     : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&g" (__d3)
+     : "g" (__reject), "0" (__s), "1" (0), "2" (0xffffffff),
        "m" ( *(struct { char __x[0xfffffff]; } *)__s)
      : "cc");
   return (__res - 1) - __s;
@@ -716,28 +714,26 @@ strcspn (__const char *__s, __const char
 __STRING_INLINE size_t
 strspn (__const char *__s, __const char *__accept)
 {
-  register unsigned long int __d0, __d1, __d2;
+  register unsigned long int __d0, __d1, __d2, __d3;
   register char *__res;
   __asm__ __volatile__
-    ("pushl	%%ebx\n\t"
-     "cld\n\t"
-     "movl	%4,%%edi\n\t"
+    ("cld\n\t"
+     "movl	%5,%%edi\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
      "decl	%%ecx\n\t"
-     "movl	%%ecx,%%ebx\n"
+     "movl	%%ecx,%4\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
-     "movl	%%ebx,%%ecx\n\t"
+     "movl	%5,%%edi\n\t"
+     "movl	%4,%%ecx\n\t"
      "repne; scasb\n\t"
      "je	1b\n"
-     "2:\n\t"
-     "popl	%%ebx"
-     : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
-     : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
+     "2:"
+     : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&g" (__d3)
+     : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
        "m" ( *(struct { char __x[0xfffffff]; } *)__s)
      : "cc");
   return (__res - 1) - __s;
@@ -781,32 +777,30 @@ strspn (__const char *__s, __const char 
 __STRING_INLINE char *
 strpbrk (__const char *__s, __const char *__accept)
 {
-  unsigned long int __d0, __d1, __d2;
+  unsigned long int __d0, __d1, __d2, __d3;
   register char *__res;
   __asm__ __volatile__
-    ("pushl	%%ebx\n\t"
-     "cld\n\t"
-     "movl	%4,%%edi\n\t"
+    ("cld\n\t"
+     "movl	%5,%%edi\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
      "decl	%%ecx\n\t"
-     "movl	%%ecx,%%ebx\n"
+     "movl	%%ecx,%4\n"
      "1:\n\t"
      "lodsb\n\t"
      "testb	%%al,%%al\n\t"
      "je	2f\n\t"
-     "movl	%4,%%edi\n\t"
-     "movl	%%ebx,%%ecx\n\t"
+     "movl	%5,%%edi\n\t"
+     "movl	%4,%%ecx\n\t"
      "repne; scasb\n\t"
      "jne	1b\n\t"
      "decl	%0\n\t"
      "jmp	3f\n"
      "2:\n\t"
      "xorl	%0,%0\n"
-     "3:\n\t"
-     "popl	%%ebx"
-     : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
-     : "r" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
+     "3:"
+     : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=&g" (__d3)
+     : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
        "m" ( *(struct { char __x[0xfffffff]; } *)__s)
      : "cc");
   return __res;
@@ -854,20 +848,19 @@ strpbrk (__const char *__s, __const char
 __STRING_INLINE char *
 strstr (__const char *__haystack, __const char *__needle)
 {
-  register unsigned long int __d0, __d1, __d2;
+  register unsigned long int __d0, __d1, __d2, __d3;
   register char *__res;
   __asm__ __volatile__
-    ("pushl	%%ebx\n\t"
-     "cld\n\t" \
-     "movl	%4,%%edi\n\t"
+    ("cld\n\t" \
+     "movl	%5,%%edi\n\t"
      "repne; scasb\n\t"
      "notl	%%ecx\n\t"
      "decl	%%ecx\n\t"	/* NOTE! This also sets Z if searchstring='' */
-     "movl	%%ecx,%%ebx\n"
+     "movl	%%ecx,%4\n"
      "1:\n\t"
-     "movl	%4,%%edi\n\t"
+     "movl	%5,%%edi\n\t"
      "movl	%%esi,%%eax\n\t"
-     "movl	%%ebx,%%ecx\n\t"
+     "movl	%4,%%ecx\n\t"
      "repe; cmpsb\n\t"
      "je	2f\n\t"		/* also works for empty string, see above */
      "xchgl	%%eax,%%esi\n\t"
@@ -875,10 +868,9 @@ strstr (__const char *__haystack, __cons
      "cmpb	$0,-1(%%eax)\n\t"
      "jne	1b\n\t"
      "xorl	%%eax,%%eax\n\t"
-     "2:\n\t"
-     "popl	%%ebx"
-     : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2)
-     : "r" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
+     "2:"
+     : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=&g" (__d3)
+     : "g" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
      : "memory", "cc");
   return __res;
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]