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


> > 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


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