[PATCH] i386: Fix GCC running out of registers for bits/string.h
Maciej W. Rozycki
macro@linux-mips.org
Wed Aug 10 17:39:00 GMT 2005
On Thu, 9 Jun 2005, Denis Vlasenko wrote:
> > 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.
>
> Definitely gcc fault.
Thanks to Richard's analysis it is now clear it is not a GCC fault at
all. I have changed the patch to avoid the problem. This version is back
to using %ebx explicitly, but it saves it to a fixed stack slot, therefore
avoiding problems with memory references from within the asm when %esp is
used as the frame pointer. This has the additional gain the temporary
storage that is used repeatedly within the loop is still assured to be in
a register (memory access is all but "free" on the original i386 -- cache
is external and may be write-through or not present at all).
As the "register" keyword conflicts with the "m" constraint, I had to
remove it; for consistency I removed it throughout.
2005-08-10 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.
* sysdeps/i386/bits/string.h: Remove the "register" keyword
throughout.
With the patch applied I have built glibc 2.3.5 successfully. I have
run the test suite with no regressions, too. As the file hasn't changed
for over a year, I see no reason for the changes not to be valid for the
HEAD.
Please apply,
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-08-10 11:49:54.000000000 +0000
@@ -53,7 +53,7 @@ __STRING_INLINE void *__memcpy_c (void *
__STRING_INLINE void *
__memcpy_c (void *__dest, __const void *__src, size_t __n)
{
- register unsigned long int __d0, __d1, __d2;
+ unsigned long int __d0, __d1, __d2;
union {
unsigned int __ui;
unsigned short int __usi;
@@ -151,7 +151,7 @@ __memcpy_c (void *__dest, __const void *
__STRING_INLINE void *
memmove (void *__dest, __const void *__src, size_t __n)
{
- register unsigned long int __d0, __d1, __d2;
+ unsigned long int __d0, __d1, __d2;
if (__dest < __src)
__asm__ __volatile__
("cld\n\t"
@@ -190,7 +190,7 @@ __STRING_INLINE void *__memset_cc (void
__STRING_INLINE void *
__memset_cc (void *__s, unsigned long int __pattern, size_t __n)
{
- register unsigned long int __d0, __d1;
+ unsigned long int __d0, __d1;
union {
unsigned int __ui;
unsigned short int __usi;
@@ -248,7 +248,7 @@ __STRING_INLINE void *__memset_cg (void
__STRING_INLINE void *
__memset_cg (void *__s, unsigned long __c, size_t __n)
{
- register unsigned long int __d0, __d1;
+ unsigned long int __d0, __d1;
__asm__ __volatile__
("cld\n\t"
"rep; stosl\n\t"
@@ -271,7 +271,7 @@ __STRING_INLINE void *__memset_gg (void
__STRING_INLINE void *
__memset_gg (void *__s, char __c, size_t __n)
{
- register unsigned long int __d0, __d1;
+ unsigned long int __d0, __d1;
__asm__ __volatile__
("cld\n\t"
"rep; stosb"
@@ -290,8 +290,8 @@ __memset_gg (void *__s, char __c, size_t
__STRING_INLINE void *
memchr (__const void *__s, int __c, size_t __n)
{
- register unsigned long int __d0;
- register void *__res;
+ unsigned long int __d0;
+ void *__res;
if (__n == 0)
return NULL;
__asm__ __volatile__
@@ -313,8 +313,8 @@ memchr (__const void *__s, int __c, size
__STRING_INLINE void *
__memrchr (__const void *__s, int __c, size_t __n)
{
- register unsigned long int __d0;
- register void *__res;
+ unsigned long int __d0;
+ void *__res;
if (__n == 0)
return NULL;
__asm__ __volatile__
@@ -341,8 +341,8 @@ __memrchr (__const void *__s, int __c, s
__STRING_INLINE size_t
strlen (__const char *__str)
{
- register unsigned long int __d0;
- register size_t __res;
+ unsigned long int __d0;
+ size_t __res;
__asm__ __volatile__
("cld\n\t"
"repne; scasb\n\t"
@@ -361,7 +361,7 @@ strlen (__const char *__str)
__STRING_INLINE char *
strcpy (char *__dest, __const char *__src)
{
- register unsigned long int __d0, __d1;
+ unsigned long int __d0, __d1;
__asm__ __volatile__
("cld\n"
"1:\n\t"
@@ -382,7 +382,7 @@ strcpy (char *__dest, __const char *__sr
__STRING_INLINE char *
strncpy (char *__dest, __const char *__src, size_t __n)
{
- register unsigned long int __d0, __d1, __d2;
+ unsigned long int __d0, __d1, __d2;
__asm__ __volatile__
("cld\n"
"1:\n\t"
@@ -407,7 +407,7 @@ strncpy (char *__dest, __const char *__s
__STRING_INLINE char *
strcat (char *__dest, __const char *__src)
{
- register unsigned long int __d0, __d1, __d2, __d3;
+ unsigned long int __d0, __d1, __d2, __d3;
__asm__ __volatile__
("cld\n\t"
"repne; scasb\n\t"
@@ -430,7 +430,7 @@ strcat (char *__dest, __const char *__sr
__STRING_INLINE char *
strncat (char *__dest, __const char *__src, size_t __n)
{
- register unsigned long int __d0, __d1, __d2, __d3;
+ unsigned long int __d0, __d1, __d2, __d3;
__asm__ __volatile__
("cld\n\t"
"repne; scasb\n\t"
@@ -461,8 +461,8 @@ strncat (char *__dest, __const char *__s
__STRING_INLINE int
strcmp (__const char *__s1, __const char *__s2)
{
- register unsigned long int __d0, __d1;
- register int __res;
+ unsigned long int __d0, __d1;
+ int __res;
__asm__ __volatile__
("cld\n"
"1:\n\t"
@@ -492,8 +492,8 @@ strcmp (__const char *__s1, __const char
__STRING_INLINE int
strncmp (__const char *__s1, __const char *__s2, size_t __n)
{
- register unsigned long int __d0, __d1, __d2;
- register int __res;
+ unsigned long int __d0, __d1, __d2;
+ int __res;
__asm__ __volatile__
("cld\n"
"1:\n\t"
@@ -533,8 +533,8 @@ __STRING_INLINE char *__strchr_g (__cons
__STRING_INLINE char *
__strchr_g (__const char *__s, int __c)
{
- register unsigned long int __d0;
- register char *__res;
+ unsigned long int __d0;
+ char *__res;
__asm__ __volatile__
("cld\n\t"
"movb %%al,%%ah\n"
@@ -559,8 +559,8 @@ __STRING_INLINE char *__strchr_c (__cons
__STRING_INLINE char *
__strchr_c (__const char *__s, int __c)
{
- register unsigned long int __d0;
- register char *__res;
+ unsigned long int __d0;
+ char *__res;
__asm__ __volatile__
("cld\n\t"
"1:\n\t"
@@ -594,8 +594,8 @@ __STRING_INLINE char *__strchrnul_g (__c
__STRING_INLINE char *
__strchrnul_g (__const char *__s, int __c)
{
- register unsigned long int __d0;
- register char *__res;
+ unsigned long int __d0;
+ char *__res;
__asm__ __volatile__
("cld\n\t"
"movb %%al,%%ah\n"
@@ -619,8 +619,8 @@ __STRING_INLINE char *__strchrnul_c (__c
__STRING_INLINE char *
__strchrnul_c (__const char *__s, int __c)
{
- register unsigned long int __d0;
- register char *__res;
+ unsigned long int __d0;
+ char *__res;
__asm__ __volatile__
("cld\n\t"
"1:\n\t"
@@ -650,12 +650,12 @@ __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 char *__res;
+ unsigned long int __d0, __d1, __d2, __d3;
+ char *__res;
__asm__ __volatile__
- ("pushl %%ebx\n\t"
+ ("movl %%ebx,%4\n\t"
"cld\n\t"
- "movl %4,%%edi\n\t"
+ "movl %5,%%edi\n\t"
"repne; scasb\n\t"
"notl %%ecx\n\t"
"decl %%ecx\n\t"
@@ -664,14 +664,14 @@ strcspn (__const char *__s, __const char
"lodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %5,%%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),
+ "movl %4,%%ebx"
+ : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=m" (__d3)
+ : "g" (__reject), "0" (__s), "1" (0), "2" (0xffffffff),
"m" ( *(struct { char __x[0xfffffff]; } *)__s)
: "cc");
return (__res - 1) - __s;
@@ -680,8 +680,8 @@ strcspn (__const char *__s, __const char
__STRING_INLINE size_t
strcspn (__const char *__s, __const char *__reject)
{
- register unsigned long int __d0, __d1, __d2, __d3;
- register char *__res;
+ unsigned long int __d0, __d1, __d2, __d3;
+ char *__res;
__asm__ __volatile__
("cld\n\t"
"movl %5,%%edi\n\t"
@@ -716,12 +716,12 @@ 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 char *__res;
+ unsigned long int __d0, __d1, __d2, __d3;
+ char *__res;
__asm__ __volatile__
- ("pushl %%ebx\n\t"
+ ("movl %%ebx,%4\n\t"
"cld\n\t"
- "movl %4,%%edi\n\t"
+ "movl %5,%%edi\n\t"
"repne; scasb\n\t"
"notl %%ecx\n\t"
"decl %%ecx\n\t"
@@ -730,14 +730,14 @@ strspn (__const char *__s, __const char
"lodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %5,%%edi\n\t"
"movl %%ebx,%%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),
+ "movl %4,%%ebx"
+ : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=m" (__d3)
+ : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
"m" ( *(struct { char __x[0xfffffff]; } *)__s)
: "cc");
return (__res - 1) - __s;
@@ -746,8 +746,8 @@ strspn (__const char *__s, __const char
__STRING_INLINE size_t
strspn (__const char *__s, __const char *__accept)
{
- register unsigned long int __d0, __d1, __d2, __d3;
- register char *__res;
+ unsigned long int __d0, __d1, __d2, __d3;
+ char *__res;
__asm__ __volatile__
("cld\n\t"
"movl %5,%%edi\n\t"
@@ -781,12 +781,12 @@ strspn (__const char *__s, __const char
__STRING_INLINE char *
strpbrk (__const char *__s, __const char *__accept)
{
- unsigned long int __d0, __d1, __d2;
- register char *__res;
+ unsigned long int __d0, __d1, __d2, __d3;
+ char *__res;
__asm__ __volatile__
- ("pushl %%ebx\n\t"
+ ("movl %%ebx,%4\n\t"
"cld\n\t"
- "movl %4,%%edi\n\t"
+ "movl %5,%%edi\n\t"
"repne; scasb\n\t"
"notl %%ecx\n\t"
"decl %%ecx\n\t"
@@ -795,7 +795,7 @@ strpbrk (__const char *__s, __const char
"lodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %5,%%edi\n\t"
"movl %%ebx,%%ecx\n\t"
"repne; scasb\n\t"
"jne 1b\n\t"
@@ -804,9 +804,9 @@ strpbrk (__const char *__s, __const char
"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),
+ "movl %4,%%ebx"
+ : "=&S" (__res), "=&a" (__d0), "=&c" (__d1), "=&D" (__d2), "=m" (__d3)
+ : "g" (__accept), "0" (__s), "1" (0), "2" (0xffffffff),
"m" ( *(struct { char __x[0xfffffff]; } *)__s)
: "cc");
return __res;
@@ -815,8 +815,8 @@ strpbrk (__const char *__s, __const char
__STRING_INLINE char *
strpbrk (__const char *__s, __const char *__accept)
{
- register unsigned long int __d0, __d1, __d2, __d3;
- register char *__res;
+ unsigned long int __d0, __d1, __d2, __d3;
+ char *__res;
__asm__ __volatile__
("cld\n\t"
"movl %5,%%edi\n\t"
@@ -854,18 +854,18 @@ strpbrk (__const char *__s, __const char
__STRING_INLINE char *
strstr (__const char *__haystack, __const char *__needle)
{
- register unsigned long int __d0, __d1, __d2;
- register char *__res;
+ unsigned long int __d0, __d1, __d2, __d3;
+ char *__res;
__asm__ __volatile__
- ("pushl %%ebx\n\t"
+ ("movl %%ebx,%4\n\t"
"cld\n\t" \
- "movl %4,%%edi\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"
"1:\n\t"
- "movl %4,%%edi\n\t"
+ "movl %5,%%edi\n\t"
"movl %%esi,%%eax\n\t"
"movl %%ebx,%%ecx\n\t"
"repe; cmpsb\n\t"
@@ -876,9 +876,9 @@ strstr (__const char *__haystack, __cons
"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)
+ "movl %4,%%ebx"
+ : "=&a" (__res), "=&c" (__d0), "=&S" (__d1), "=&D" (__d2), "=m" (__d3)
+ : "g" (__needle), "0" (0), "1" (0xffffffff), "2" (__haystack)
: "memory", "cc");
return __res;
}
@@ -886,8 +886,8 @@ strstr (__const char *__haystack, __cons
__STRING_INLINE char *
strstr (__const char *__haystack, __const char *__needle)
{
- register unsigned long int __d0, __d1, __d2, __d3;
- register char *__res;
+ unsigned long int __d0, __d1, __d2, __d3;
+ char *__res;
__asm__ __volatile__
("cld\n\t" \
"movl %5,%%edi\n\t"
More information about the Libc-alpha
mailing list