[PATCH] i386: Fix GCC running out of registers for bits/string.h
Denis Vlasenko
vda@ilport.com.ua
Fri Jun 10 06:42:00 GMT 2005
> > Cannot reproduce it here in a isolated testcase.
>
> Make sure the calling function strcspn() is inlined into also uses
> alloca() (preferably with a variable argument, but I think GCC currently
> doesn't optimize it even for a constant) so that %ebp is used for the
> frame pointer and therefore unavailable.
>
> Building strcspn() standalone certainly is going to work.
>
> Maciej
Hmm. I tried already, works for me.
//gcc4 compiles this just fine with:
//gcc -O2 -fomit-frame-pointer
#include <alloca.h>
#define NL "\n"
inline int
strcspn (__const char *__s, __const char *__reject)
{
unsigned long int __eax, __ebx, __ecx, __edi;
char *__esi;
__asm__ __volatile__(NL
" cld" NL
" movl %5,%%edi" NL
" repne; scasb" NL
" notl %%ecx" NL
" leal -1(%%ecx),%%ebx" NL
"1:" NL
" lodsb" NL
" testb %%al,%%al" NL
" je 2f" NL
" movl %5,%%edi" NL
" movl %%ebx,%%ecx" NL
" repne; scasb" NL
" jne 1b" NL
"2:" NL
: "=&S" (__esi), "=&a" (__eax), "=&b" (__ebx), "=&c" (__ecx), "=&D" (__edi)
: "d" (__reject), "0" (__s), "1" (0), "2" (0xffffffff),
"m" ( *(struct { char __x[0xfffffff]; } *)__s)
: "cc");
return (__esi - 1) - __s;
}
int t(int n, char* s) {
char *p = alloca(n);
return strcspn("abcd",s);
}
Compiled result:
t:
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %esi
pushl %ebx
subl $12, %esp
movl 12(%ebp), %edx
movl 8(%ebp), %eax
addl $30, %eax
andl $-16, %eax
subl %eax, %esp
movl $.LC0, %esi
xorl %eax, %eax
movl $-1, %ebx
#APP
cld
movl %edx,%edi
repne; scasb
notl %ecx
leal -1(%ecx),%ebx
1:
lodsb
testb %al,%al
je 2f
movl %edx,%edi
movl %ebx,%ecx
repne; scasb
jne 1b
2:
#NO_APP
subl $.LC0, %esi
leal -1(%esi), %eax
leal -12(%ebp), %esp
popl %ebx
popl %esi
popl %edi
leave
ret
BTW, can I beg for writing asm() statements so that they do not
look like Obfuscated C Contest? Why this:
"1:\n\t"
"lodsb\n\t"
"testb %%al,%%al\n\t"
instead of this:
"1:\n"
" lodsb\n"
" testb %%al,%%al\n"
--
vda
More information about the Libc-alpha
mailing list