[PATCH] i386: Fix GCC running out of registers for bits/string.h
Denis Vlasenko
vda@ilport.com.ua
Thu Jun 9 09:20:00 GMT 2005
On Wednesday 08 June 2005 21:19, Jakub Jelinek wrote:
> On Wed, Jun 08, 2005 at 07:12:06PM +0100, Maciej W. Rozycki wrote:
> > --- 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-02 00:02:01.000000000 +0000
> > @@ -671,7 +671,7 @@ strcspn (__const char *__s, __const char
> > "2:\n\t"
> > "popl %%ebx"
> > : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2)
> > - : "d" (__reject), "0" (__s), "1" (0), "2" (0xffffffff),
> > + : "g" (__reject), "0" (__s), "1" (0), "2" (0xffffffff),
> > "m" ( *(struct { char __x[0xfffffff]; } *)__s)
> > : "cc");
> > return (__res - 1) - __s;
>
> E.g. this can't be right.
> strcspn (__const char *__s, __const char *__reject)
> {
> register unsigned long int __d0, __d1, __d2;
> register char *__res;
> __asm__ __volatile__
> ("pushl %%ebx\n\t"
> "cld\n\t"
> "movl %4,%%edi\n\t"
> "repne; scasb\n\t"
> "notl %%ecx\n\t"
> "decl %%ecx\n\t"
> "movl %%ecx,%%ebx\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"
> "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),
> "m" ( *(struct { char __x[0xfffffff]; } *)__s)
> : "cc");
> return (__res - 1) - __s;
> }
>
> 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.
Can be rewritten to use local temp var instead of hardcoded %ebx.
gcc will save/restore it then, if needed.
Also register keywords are anachronism. May be removed.
--
vda
More information about the Libc-alpha
mailing list