[PATCH] i386: Fix GCC running out of registers for bits/string.h
Maciej W. Rozycki
macro@linux-mips.org
Thu Jun 9 11:57:00 GMT 2005
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;
}
More information about the Libc-alpha
mailing list