Messages in this thread Patches in this message | | | Date | Sun, 18 Jan 1998 19:06:28 +0100 (MET) | From | Gabriel Paubert <> | Subject | Re: gcc-2.8.0 miscompiles kernel (Was: gcc-2.8 out...) |
| |
Sorry for the previous message, it was slightly wrong. I did not realize that big-mama dod not havethe latest (and obviously greatest) version of my patch(es). Two patches attached, the first one cures only de4x5, the second one should cure most problems linked with inlined string functions and pgcc/egcs/gcc-2.8+...
Gabriel. --- linux-2.0.30/drivers/net/de4x5.c.virgin Sun Oct 5 18:39:18 1997 +++ linux-2.0.30/drivers/net/de4x5.c Sun Oct 5 18:54:38 1997 @@ -3026,10 +3026,11 @@ /* ** Look for a particular board name in the EISA configuration space */ +static c_char * const signatures[] = DE4X5_SIGNATURE; + static int EISA_signature(char *name, s32 eisa_id) { - c_char *signatures[] = DE4X5_SIGNATURE; char ManCode[DE4X5_STRLEN]; union { s32 ID; @@ -3064,8 +3065,7 @@ static int PCI_signature(char *name, struct bus_type *lp) { - c_char *de4x5_signatures[] = DE4X5_SIGNATURE; - int i, status = 0, siglen = sizeof(de4x5_signatures)/sizeof(c_char *); + int i, status = 0, siglen = sizeof(signatures)/sizeof(c_char *); if (lp->chipset == DC21040) { strcpy(name, "DE434/5"); @@ -3079,7 +3079,7 @@ } name[8] = '\0'; for (i=0; i<siglen; i++) { - if (strstr(name,de4x5_signatures[i])!=NULL) break; + if (strstr(name,signatures[i])!=NULL) break; } if (i == siglen) { if (dec_only) {--- linux-2.0.30/include/asm-i386/string.h.virgin Wed Oct 1 10:55:48 1997 +++ linux-2.0.30/include/asm-i386/string.h Thu Oct 2 21:52:47 1997 @@ -26,6 +26,23 @@ * Copyright (C) 1991, 1992 Linus Torvalds */ +/* + * Found a serious problem with constraints revealed by compiling with pgcc. + * + * First attempt to fix it by G.Paubert, paubert@iram.es, 1997 + * + * Consider for now this code as experimentation on gcc inline assembly. + * Use at your own risk. + * + * I have also the feeling that many "memory" are superfluous: + * when passing a char *, resp. a const char *, the compiler should assume + * that the value or array pointed to is modified, resp referenced. + * The fact that the function is declared extern inline should not change + * these semantics. + * + */ + + #define __HAVE_ARCH_STRCPY extern inline char * strcpy(char * dest,const char *src) { @@ -36,7 +53,7 @@ "testb %%al,%%al\n\t" "jne 1b" : /* no output */ - :"S" (src),"D" (dest):"si","di","ax","memory"); + :"S" (src),"D" (dest):"si","di","ax"/*,"memory"*/); return dest; } @@ -55,7 +72,7 @@ "stosb\n" "2:" : /* no output */ - :"S" (src),"D" (dest),"c" (count):"si","di","ax","cx","memory"); + :"S" (src),"D" (dest),"c" (count):"si","di","ax","cx"/*,"memory"*/); return dest; } @@ -95,7 +112,7 @@ "stosb" : /* no output */ :"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count) - :"si","di","ax","cx","memory"); + :"si","di","ax","cx"/*,"memory"*/); return dest; } @@ -181,25 +198,29 @@ extern inline size_t strspn(const char * cs, const char * ct) { register char * __res; +const char * __ct; +int __len; __asm__ __volatile__( "cld\n\t" - "movl %4,%%edi\n\t" + "movl %6,%%edi\n\t" "repne\n\t" "scasb\n\t" "notl %%ecx\n\t" - "decl %%ecx\n\t" - "movl %%ecx,%%edx\n" + "leal -1(%%ecx),%1\n\t" "1:\tlodsb\n\t" "testb %%al,%%al\n\t" "je 2f\n\t" - "movl %4,%%edi\n\t" - "movl %%edx,%%ecx\n\t" + "movl %6,%%edi\n\t" + "movl %1,%%ecx\n\t" "repne\n\t" "scasb\n\t" "je 1b\n" "2:\tdecl %0" - :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) - :"ax","cx","dx","di"); + /* This constraint set leaves few choices to gcc, but usually works. + Change "=&r" (__len) to "=&rm" (__len) if the compiler complains. */ + :"=S" (__res), "=&r" (__len), "=&D" (__ct) + :"a" (0),"c" (0xffffffff),"0" (cs), "g" (ct) + :"ax","cx"); return __res-cs; } @@ -207,83 +228,95 @@ extern inline size_t strcspn(const char * cs, const char * ct) { register char * __res; +const char * __ct; +int __len; __asm__ __volatile__( "cld\n\t" - "movl %4,%%edi\n\t" + "movl %6,%%edi\n\t" "repne\n\t" "scasb\n\t" "notl %%ecx\n\t" - "decl %%ecx\n\t" - "movl %%ecx,%%edx\n" + "leal -1(%%ecx),%1\n\t" "1:\tlodsb\n\t" "testb %%al,%%al\n\t" "je 2f\n\t" - "movl %4,%%edi\n\t" - "movl %%edx,%%ecx\n\t" + "movl %6,%%edi\n\t" + "movl %1,%%ecx\n\t" "repne\n\t" "scasb\n\t" "jne 1b\n" "2:\tdecl %0" - :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) - :"ax","cx","dx","di"); + /* This constraint set leaves few choices to gcc, but usually works. + Change "=&r" (__len) to "=&rm" (__len) if the compiler complains. */ + :"=S" (__res), "=&r" (__len), "=&D" (__ct) + :"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) + :"ax","cx"); return __res-cs; } #define __HAVE_ARCH_STRPBRK extern inline char * strpbrk(const char * cs,const char * ct) { -register char * __res; +char * __res; +const char * __ct; +int __len; __asm__ __volatile__( "cld\n\t" - "movl %4,%%edi\n\t" + "movl %6,%%edi\n\t" "repne\n\t" "scasb\n\t" "notl %%ecx\n\t" - "decl %%ecx\n\t" - "movl %%ecx,%%edx\n" + "leal -1(%%ecx),%1\n\t" "1:\tlodsb\n\t" "testb %%al,%%al\n\t" - "je 2f\n\t" - "movl %4,%%edi\n\t" - "movl %%edx,%%ecx\n\t" + "je 2f\n\t" /* Here %eax is zero if branch taken ! */ + "movl %6,%%edi\n\t" + "movl %1,%%ecx\n\t" "repne\n\t" "scasb\n\t" "jne 1b\n\t" - "decl %0\n\t" - "jmp 3f\n" - "2:\txorl %0,%0\n" - "3:" - :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct) - :"ax","cx","dx","di"); + "leal -1(%%esi),%%eax\n\t" + "2:" + /* This constraint set leaves few choices to gcc, but usually works. + Change "=&r" (__len) to "=&rm" (__len) if the compiler complains. */ + :"=a" (__res), "=&r" (__len), "=&D" (__ct) + :"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct) + :"cx","si"); return __res; } #define __HAVE_ARCH_STRSTR extern inline char * strstr(const char * cs,const char * ct) { -register char * __res; +char * __res; +const char *__ct; +int __len; __asm__ __volatile__( - "cld\n\t" \ - "movl %4,%%edi\n\t" + "cld\n\t" + "movl %6,%%edi\n\t" "repne\n\t" "scasb\n\t" "notl %%ecx\n\t" "decl %%ecx\n\t" /* NOTE! This also sets Z if searchstring='' */ - "movl %%ecx,%%edx\n" - "1:\tmovl %4,%%edi\n\t" + "movl %%ecx,%1\n" + "1:\tmovl %6,%%edi\n\t" "movl %%esi,%%eax\n\t" - "movl %%edx,%%ecx\n\t" "repe\n\t" "cmpsb\n\t" "je 2f\n\t" /* also works for empty string, see above */ "xchgl %%eax,%%esi\n\t" + "movl %1,%%ecx\n\t" "incl %%esi\n\t" "cmpb $0,-1(%%eax)\n\t" "jne 1b\n\t" "xorl %%eax,%%eax\n\t" "2:" - :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct) - :"cx","dx","di","si"); + /* This constraint set leaves few choices to gcc, but usually works, + and pgcc complains with impossible constraints if __len is declared + as "=&r" when compiling de4x5.c ! */ + :"=a" (__res), "=&rm" (__len), "=&D" (__ct) + :"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct) + :"cx","si"); return __res; } @@ -304,7 +337,9 @@ #define __HAVE_ARCH_STRTOK extern inline char * strtok(char * s,const char * ct) { -register char * __res; +char * __res; +const char * __ct; +int __len, __cnt, __val; __asm__ __volatile__( "testl %1,%1\n\t" "jne 1f\n\t" @@ -315,18 +350,18 @@ "movl $-1,%%ecx\n\t" "xorl %%eax,%%eax\n\t" "cld\n\t" - "movl %4,%%edi\n\t" + "movl %8,%%edi\n\t" "repne\n\t" "scasb\n\t" "notl %%ecx\n\t" "decl %%ecx\n\t" "je 7f\n\t" /* empty delimiter-string */ - "movl %%ecx,%%edx\n" + "movl %%ecx,%2\n" "2:\tlodsb\n\t" "testb %%al,%%al\n\t" "je 7f\n\t" - "movl %4,%%edi\n\t" - "movl %%edx,%%ecx\n\t" + "movl %8,%%edi\n\t" + "movl %2,%%ecx\n\t" "repne\n\t" "scasb\n\t" "je 2b\n\t" @@ -337,8 +372,8 @@ "3:\tlodsb\n\t" "testb %%al,%%al\n\t" "je 5f\n\t" - "movl %4,%%edi\n\t" - "movl %%edx,%%ecx\n\t" + "movl %8,%%edi\n\t" + "movl %2,%%ecx\n\t" "repne\n\t" "scasb\n\t" "jne 3b\n\t" @@ -356,9 +391,12 @@ "jne 8f\n\t" "movl %0,%1\n" "8:" - :"=b" (__res),"=S" (___strtok) - :"0" (___strtok),"1" (s),"g" (ct) - :"ax","cx","dx","di","memory"); + /* This constraint set is frightening: if I were the compiler, + I would try to eat the source file to avoid seeing it again :-). + Change "=&r" (__len) to "=&rm" (__len) if the compiler complains. */ + :"=b" (__res),"=S" (___strtok), "=&r" (__len), "=&D" (__ct), + "=&c" (__cnt), "=&a" (__val) + :"0" (___strtok),"1" (s),"g" (ct)); return __res; }
| |