lkml.org 
[lkml]   [1997]   [Oct]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectRe: AMD K6


On Thu, 2 Oct 1997, Aaron Tiensivu wrote:

> > WHERE can I find PGCC ???
>
> ftp.goof.com
>
> > Does it compile the kernel without problems?
>
> AFAICT.

It won't compile correctly the following network drivers:

de4x5, depca, ewrk3

(tested on 970924 pgcc release).

I have a patch (attached) which seems to work, and hope it does not break
anything else. The file to patch is linux/include/asm-i386/string.h.

I had myself problems to believe that this could be the cause. Code
generated without the patch is _obviously_ wrong at the machine code level
where inlined strstr() are used. See the attached example.

If anybody uses one of these network drivers, please tell me the result.
This patch could do very bad things it it has a glitch. But I have the
impression that I have finally learnt to use inline assembly constraints
correctly.

BTW: I have seen that there is a single ___strtok global variable in the
whole kernel (even 2.1.56). Is it SMP safe ?

Gabriel.The following code:
for (i=0; i<siglen; i++) {
if (strstr(name,de4x5_signatures[i])!=NULL) break;
}


generates (see what happens to %edi):

00004c68 <PCI_signature+94> xorl %ebx,%ebx
00004c6a <PCI_signature+96> cmpl $0x5,%ebx
00004c6d <PCI_signature+99> jnl 00004cae <PCI_signature+da>
00004c6f <PCI_signature+9b> leal 0x18(%esp,1),%ecx
00004c73 <PCI_signature+9f> movl %ecx,0x10(%esp,1)
00004c77 <PCI_signature+a3> xorl %eax,%eax
00004c79 <PCI_signature+a5> movl $0xffffffff,%ecx
00004c7e <PCI_signature+aa> movl %ebp,%esi
00004c80 <PCI_signature+ac> movl 0x10(%esp,1),%edi
00004c84 <PCI_signature+b0> cld
00004c85 <PCI_signature+b1> movl (%edi,%ebx,4),%edi
00004c88 <PCI_signature+b4> repnz scasb %es:(%edi),%al
00004c8a <PCI_signature+b6> notl %ecx
00004c8c <PCI_signature+b8> decl %ecx
00004c8d <PCI_signature+b9> movl %ecx,%edx
00004c8f <PCI_signature+bb> movl (%edi,%ebx,4),%edi
00004c92 <PCI_signature+be> movl %esi,%eax
00004c94 <PCI_signature+c0> movl %edx,%ecx
00004c96 <PCI_signature+c2> repz cmpsb %ds:(%esi),%es:(%edi)
00004c98 <PCI_signature+c4> je 00004ca4 <PCI_signature+d0>
00004c9a <PCI_signature+c6> xchgl %eax,%esi
00004c9b <PCI_signature+c7> incl %esi
00004c9c <PCI_signature+c8> cmpb $0x0,0xffffffff(%eax)
00004ca0 <PCI_signature+cc> jne 00004c8f <PCI_signature+bb>
00004ca2 <PCI_signature+ce> xorl %eax,%eax
00004ca4 <PCI_signature+d0> testl %eax,%eax
00004ca6 <PCI_signature+d2> jne 00004cae <PCI_signature+da>
00004ca8 <PCI_signature+d4> incl %ebx
00004ca9 <PCI_signature+d5> cmpl $0x5,%ebx
00004cac <PCI_signature+d8> jl 00004c77 <PCI_signature+a3>
--- 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;
}
\
 
 \ /
  Last update: 2005-03-22 13:40    [W:0.040 / U:0.112 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site