EGCS and Linux 2.1.89 patch

Christof Petig (christof.petig@wtal.de)
Mon, 16 Mar 1998 12:07:50 +0100


This is a multi-part message in MIME format.
--------------5684A7852201BD6A9DF4EA19
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hello,

last night I made some patches to the i386 asms to support
earlyclobbers. This is a menacing task. Any typo, forgetfulness or just
misunderstanding will definitely break the kernel.

BEWARE!

This patch (at last) compiles for me, though I get an early OOPS in idle
process (system halted). I just post it for having someone else take a
look at it and to start discussion whether it's the right way to go.
Interesting, the newer parts of the kernel (string-486.h) sometimes
already implemented earlyclobbers. Also there is a chance that I removed
some hidden bugs (I'm not always content with the argument passing.
Somewhere there might have been a "&" missing?).

If you fix it, please mail me directly - I'll take a closer look next
week.

Any comments welcome
Christof

PS: It has some pro and cons to apply a (perhaps working) patch for egcs
before 2.2.
+ egcs will definitely get popular (think of STL) and a lot of people
will use it for kernel compilation.
- This patch definitely destabilizes everything if it contains the
slightest error.

PPS: I wrote this message Friday, It took me three tries (today) to get
it send without 64 bit encoding with netscape.
--------------5684A7852201BD6A9DF4EA19
Content-Type: text/plain; charset=us-ascii; name="egcs.patch2"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="egcs.patch2"

diff -ru linux_orig/arch/i386/lib/checksum.c mylinux/arch/i386/lib/checksum.c
--- linux_orig/arch/i386/lib/checksum.c Wed Feb 11 17:18:21 1998
+++ mylinux/arch/i386/lib/checksum.c Fri Mar 13 10:57:35 1998
@@ -27,6 +27,7 @@
*/

unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) {
+int __clobber0,__clobber1;
/*
* Experiments with ethernet and slip connections show that buff
* is aligned on either a 2-byte or 4-byte boundary. We get at
@@ -91,9 +92,9 @@
6: addl %%ecx,%%eax
adcl $0, %%eax
7: "
- : "=a"(sum)
- : "0"(sum), "c"(len), "S"(buff)
- : "bx", "cx", "dx", "si");
+ : "=&a"(sum), "=&c" (__clobber0), "=&S" (__clobber1)
+ : "0"(sum), "1"(len), "2"(buff)
+ : "bx", "dx");
return(sum);
}

@@ -122,7 +123,7 @@

unsigned int csum_partial_copy_generic (const char *src, char *dst,
int len, int sum, int *src_err_ptr, int *dst_err_ptr)
-{
+{ int __clobber0,__clobber1,__clobber2;
__asm__ __volatile__ ( "
testl $2, %%edi # Check alignment.
jz 2f # Jump if alignment is ok.
@@ -212,18 +213,18 @@
#
6000: #
#
- movl %7, (%%ebx) #
+ movl $-14, (%%ebx) # -EFAULT
#
# FIXME: do zeroing of rest of the buffer here. #
#
jmp 5000b #
#
6001: #
- movl %1, %%ebx #
+ movl %4, %%ebx #
jmp 6000b #
#
6002: #
- movl %2, %%ebx #
+ movl %5, %%ebx #
jmp 6000b #
#
.previous #
@@ -231,10 +232,11 @@
################################################

"
- : "=a" (sum), "=m" (src_err_ptr), "=m" (dst_err_ptr)
- : "0" (sum), "c" (len), "S" (src), "D" (dst),
- "i" (-EFAULT)
- : "bx", "cx", "dx", "si", "di" );
+ : "=&a" (sum), "=&c" (__clobber0), "=&S" (__clobber1),
+ "=&D" (__clobber2), "=m" (src_err_ptr), "=m" (dst_err_ptr)
+ : "0" (sum), "1" (len), "2" (src), "3" (dst)
+ : "bx", "dx" );
+ /* Sorry, I had to hardcode -EFAULT, out of parameters */

return(sum);
}
diff -ru linux_orig/arch/i386/lib/delay.c mylinux/arch/i386/lib/delay.c
--- linux_orig/arch/i386/lib/delay.c Mon Jan 5 11:39:08 1998
+++ mylinux/arch/i386/lib/delay.c Thu Mar 12 20:26:02 1998
@@ -25,11 +25,10 @@
}

inline void __const_udelay(unsigned long xloops)
-{
+{ int __clobber0;
__asm__("mull %0"
- :"=d" (xloops)
- :"a" (xloops),"0" (current_cpu_data.loops_per_sec)
- :"ax");
+ :"=&a" (__clobber0), "=d" (xloops)
+ :"0" (xloops),"1" (current_cpu_data.loops_per_sec));
__delay(xloops);
}

diff -ru linux_orig/arch/i386/lib/usercopy.c mylinux/arch/i386/lib/usercopy.c
--- linux_orig/arch/i386/lib/usercopy.c Wed Feb 11 17:18:08 1998
+++ mylinux/arch/i386/lib/usercopy.c Fri Mar 13 11:14:31 1998
@@ -29,6 +29,7 @@
*/

#define __do_strncpy_from_user(dst,src,count,res) \
+({ int __clobber0,__clobber1; \
__asm__ __volatile__( \
" testl %1,%1\n" \
" jz 2f\n" \
@@ -41,16 +42,18 @@
"1: subl %1,%0\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
- "3: movl %2,%0\n" \
+ "3: movl %4,%0\n" \
" jmp 2b\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
" .align 4\n" \
" .long 0b,3b\n" \
".previous" \
- : "=d"(res), "=c"(count) \
- : "i"(-EFAULT), "0"(count), "1"(count), "S"(src), "D"(dst) \
- : "si", "di", "ax", "memory")
+ : "=d"(res), "=c"(count), "=&S"(__clobber0), \
+ "=&D"(__clobber1) \
+ : "i"(-EFAULT), "0"(count), "1"(count), "2"(src), "3"(dst) \
+ : "ax", "memory"); \
+})

long
__strncpy_from_user(char *dst, const char *src, long count)
@@ -74,14 +77,15 @@
* Zero Userspace
*/

-#define __do_clear_user(addr,size) \
+#define __do_clear_user(addr,size) \
+({ int __clobber0; \
__asm__ __volatile__( \
"0: rep; stosl\n" \
- " movl %1,%0\n" \
+ " movl %2,%0\n" \
"1: rep; stosb\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
- "3: lea 0(%1,%0,4),%0\n" \
+ "3: lea 0(%2,%0,4),%0\n" \
" jmp 2b\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
@@ -89,9 +93,9 @@
" .long 0b,3b\n" \
" .long 1b,2b\n" \
".previous" \
- : "=&c"(size) \
- : "r"(size & 3), "0"(size / 4), "D"(addr), "a"(0) \
- : "di")
+ : "=&c"(size), "=&D" (__clobber0) \
+ : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \
+})

unsigned long
clear_user(void *to, unsigned long n)
diff -ru linux_orig/arch/i386/mm/init.c mylinux/arch/i386/mm/init.c
--- linux_orig/arch/i386/mm/init.c Thu Jan 15 08:13:56 1998
+++ mylinux/arch/i386/mm/init.c Thu Mar 12 20:26:02 1998
@@ -48,24 +48,26 @@
pte_t * __bad_pagetable(void)
{
extern char empty_bad_page_table[PAGE_SIZE];
+ int __clobber0,__clobber1;

- __asm__ __volatile__("cld ; rep ; stosl":
+ __asm__ __volatile__("cld ; rep ; stosl"
+ :"=&D" (__clobber0), "=&c" (__clobber1)
:"a" (pte_val(BAD_PAGE)),
- "D" ((long) empty_bad_page_table),
- "c" (PAGE_SIZE/4)
- :"di","cx");
+ "0" ((long) empty_bad_page_table),
+ "1" (PAGE_SIZE/4));
return (pte_t *) empty_bad_page_table;
}

pte_t __bad_page(void)
{
extern char empty_bad_page[PAGE_SIZE];
+ int __clobber0,__clobber1;

- __asm__ __volatile__("cld ; rep ; stosl":
+ __asm__ __volatile__("cld ; rep ; stosl"
+ :"=&D" (__clobber0), "=&c" (__clobber1)
:"a" (0),
- "D" ((long) empty_bad_page),
- "c" (PAGE_SIZE/4)
- :"di","cx");
+ "0" ((long) empty_bad_page),
+ "1" (PAGE_SIZE/4));
return pte_mkdirty(mk_pte((unsigned long) empty_bad_page, PAGE_SHARED));
}

diff -ru linux_orig/include/asm-i386/bitops.h mylinux/include/asm-i386/bitops.h
--- linux_orig/include/asm-i386/bitops.h Tue Dec 2 13:09:00 1997
+++ mylinux/include/asm-i386/bitops.h Thu Mar 12 17:48:40 1998
@@ -127,7 +127,7 @@
*/
extern __inline__ int find_first_zero_bit(void * addr, unsigned size)
{
- int res;
+ int res,__clobber0,__clobber1;

if (!size)
return 0;
@@ -142,9 +142,9 @@
"1:\tsubl %%ebx,%%edi\n\t"
"shll $3,%%edi\n\t"
"addl %%edi,%%edx"
- :"=d" (res)
- :"c" ((size + 31) >> 5), "D" (addr), "b" (addr)
- :"ax", "cx", "di");
+ :"=d" (res), "=&c" (__clobber0), "=&D" (__clobber1)
+ :"1" ((size + 31) >> 5), "2" (addr), "b" (addr)
+ :"ax");
return res;
}

diff -ru linux_orig/include/asm-i386/bugs.h mylinux/include/asm-i386/bugs.h
--- linux_orig/include/asm-i386/bugs.h Fri Jan 23 09:06:07 1998
+++ mylinux/include/asm-i386/bugs.h Thu Mar 12 19:31:55 1998
@@ -133,14 +133,14 @@
__initfunc(static void check_popad(void))
{
#ifdef CONFIG_M386
- int res, inp = (int) &res;
+ int res, inp = (int) &res, __clobber0;

printk(KERN_INFO "Checking for popad bug... ");
__asm__ __volatile__(
"movl $12345678,%%eax; movl $0,%%edi; pusha; popa; movl (%%edx,%%edi),%%ecx "
- : "=eax" (res)
+ : "=eax" (res), "=edx" (__clobber0)
: "edx" (inp)
- : "eax", "ecx", "edx", "edi" );
+ : "ecx", "edi" );
/* If this fails, it means that any user program may lock CPU hard. Too bad. */
if (res != 12345678) printk( "Buggy.\n" );
else printk( "Ok.\n" );
diff -ru linux_orig/include/asm-i386/posix_types.h mylinux/include/asm-i386/posix_types.h
--- linux_orig/include/asm-i386/posix_types.h Wed Dec 10 12:23:07 1997
+++ mylinux/include/asm-i386/posix_types.h Thu Mar 12 22:54:34 1998
@@ -57,9 +57,12 @@

#undef __FD_ZERO
#define __FD_ZERO(fdsetp) \
+({ int __clobber0,__clobber1; \
__asm__ __volatile__("cld ; rep ; stosl" \
- :"=m" (*(__kernel_fd_set *) (fdsetp)) \
- :"a" (0), "c" (__FDSET_LONGS), \
- "D" ((__kernel_fd_set *) (fdsetp)) :"cx","di")
+ :"=m" (*(__kernel_fd_set *) (fdsetp)), \
+ "=&c" (__clobber0), "=&D" (__clobber1) \
+ :"a" (0), "1" (__FDSET_LONGS), \
+ "2" ((__kernel_fd_set *) (fdsetp))); \
+})

#endif
diff -ru linux_orig/include/asm-i386/string-486.h mylinux/include/asm-i386/string-486.h
--- linux_orig/include/asm-i386/string-486.h Mon Sep 29 12:48:10 1997
+++ mylinux/include/asm-i386/string-486.h Thu Mar 12 19:43:41 1998
@@ -198,9 +198,10 @@
extern inline size_t strspn(const char * cs, const char * ct)
{
register char * __res;
+int __clobber0,__clobber1;
__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"
@@ -209,14 +210,15 @@
"1:\tlodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %6,%%edi\n\t"
"movl %%edx,%%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");
+ :"=&S" (__res), "=&a" (__clobber0), "=&c" (__clobber1)
+ :"1" (0),"2" (0xffffffff),"0" (cs),"g" (ct)
+ :"dx","di");
return __res-cs;
}

@@ -224,9 +226,10 @@
extern inline size_t strcspn(const char * cs, const char * ct)
{
register char * __res;
+int __clobber0,__clobber1;
__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"
@@ -235,14 +238,15 @@
"1:\tlodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %6,%%edi\n\t"
"movl %%edx,%%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");
+ :"=&S" (__res), "=&a" (__clobber0), "=&c" (__clobber1)
+ :"1" (0),"2" (0xffffffff),"0" (cs),"g" (ct)
+ :"dx","di");
return __res-cs;
}

@@ -250,9 +254,10 @@
extern inline char * strpbrk(const char * cs,const char * ct)
{
register char * __res;
+int __clobber0,__clobber1;
__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"
@@ -261,7 +266,7 @@
"1:\tlodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %6,%%edi\n\t"
"movl %%edx,%%ecx\n\t"
"repne\n\t"
"scasb\n\t"
@@ -270,8 +275,9 @@
"jmp 3f\n"
"2:\txorl %0,%0\n"
"3:"
- :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
- :"ax","cx","dx","di");
+ :"=&S" (__res), "=&a" (__clobber0), "=&c" (__clobber1)
+ :"1" (0),"2" (0xffffffff),"0" (cs),"g" (ct)
+ :"dx","di");
return __res;
}

@@ -279,15 +285,16 @@
extern inline char * strstr(const char * cs,const char * ct)
{
register char * __res;
+int __clobber0,__clobber1;
__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" /* NOTE! This also sets Z if searchstring='' */
"movl %%ecx,%%edx\n"
- "1:\tmovl %4,%%edi\n\t"
+ "1:\tmovl %6,%%edi\n\t"
"movl %%esi,%%eax\n\t"
"movl %%edx,%%ecx\n\t"
"repe\n\t"
@@ -299,8 +306,9 @@
"jne 1b\n\t"
"xorl %%eax,%%eax\n\t"
"2:"
- :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
- :"cx","dx","di","si");
+ :"=a" (__res), "=&c" (__clobber0), "=&S" (__clobber1)
+ :"0" (0),"1" (0xffffffff),"2" (cs),"g" (ct)
+ :"dx","di");
return __res;
}

@@ -328,7 +336,7 @@
#define __HAVE_ARCH_STRNLEN
extern inline size_t strnlen(const char * s, size_t count)
{
-register int __res;
+register int __res,__clobber0;
__asm__ __volatile__(
"movl %1,%0\n\t"
"jmp 2f\n"
@@ -339,9 +347,8 @@
"cmpl $-1,%2\n\t"
"jne 1b\n"
"3:\tsubl %1,%0"
- :"=a" (__res)
- :"c" (s),"d" (count)
- :"dx");
+ :"=a" (__res), "=&d" (__clobber)
+ :"c" (s),"1" (count))
return __res;
}
/* end of additional stuff */
@@ -465,6 +472,7 @@
extern inline void * __memcpy_g(void * to, const void * from, size_t n)
{
register void *tmp = (void *)to;
+int __clobber0,__clobber1,__clobber2;
__asm__ __volatile__ (
"cld\n\t"
"shrl $1,%%ecx\n\t"
@@ -475,9 +483,9 @@
"movsw\n"
"2:\trep\n\t"
"movsl"
- : /* no output */
- :"c" (n),"D" ((long) tmp),"S" ((long) from)
- :"cx","di","si","memory");
+ :"=&c" (__clobber0),"=&D" (__clobber1),"=&S" (__clobber2)
+ :"0" (n),"1" ((long) tmp),"2" ((long) from)
+ :"memory");
return (to);
}

@@ -485,30 +493,31 @@
#define __HAVE_ARCH_MEMMOVE
extern inline void * memmove(void * dest,const void * src, size_t n)
{
+int __clobber0,__clobber1,__clobber2;
register void *tmp = (void *)dest;
if (dest<src)
__asm__ __volatile__ (
"cld\n\t"
"rep\n\t"
"movsb"
- : /* no output */
- :"c" (n),"S" (src),"D" (tmp)
- :"cx","si","di");
+ :"=&c" (__clobber0),"=&D" (__clobber1),"=&S" (__clobber2)
+ :"0" (n),"2" (src),"1" (tmp)
+ :"memory");
else
__asm__ __volatile__ (
"std\n\t"
"rep\n\t"
"movsb\n\t"
"cld"
- : /* no output */
- :"c" (n), "S" (n-1+(const char *)src), "D" (n-1+(char *)tmp)
- :"cx","si","di","memory");
+ :"=&c" (__clobber0),"=&D" (__clobber1),"=&S" (__clobber2)
+ :"0" (n), "2" (n-1+(const char *)src), "1" (n-1+(char *)tmp)
+ :"memory");
return dest;
}

extern inline int memcmp(const void * cs,const void * ct,size_t count)
{
-register int __res;
+register int __res,__clobber0,__clobber1,__clobber2;
__asm__ __volatile__(
"cld\n\t"
"repe\n\t"
@@ -517,8 +526,9 @@
"sbbl %0,%0\n\t"
"orb $1,%b0\n"
"1:"
- :"=abd" (__res):"0" (0),"S" (cs),"D" (ct),"c" (count)
- :"si","di","cx");
+ :"=abd" (__res), "=&S" (__clobber0), "=&D" (__clobber1),
+ "=&c" (__clobber2)
+ :"0" (0),"1" (cs),"2" (ct),"3" (count));
return __res;
}

@@ -526,6 +536,7 @@
extern inline void * memchr(const void * cs,int c,size_t count)
{
register void * __res;
+int __clobber0;
if (!count)
return NULL;
__asm__ __volatile__(
@@ -535,8 +546,8 @@
"je 1f\n\t"
"movl $1,%0\n"
"1:\tdecl %0"
- :"=D" (__res):"a" (c),"D" (cs),"c" (count)
- :"cx");
+ :"=D" (__res), "=&c" (__clobber0)
+ :"a" (c),"0" (cs),"1" (count));
return __res;
}

@@ -644,6 +655,7 @@
extern inline void * __memset_cg(void * s, char c, size_t count)
{
register void *tmp = (void *)s;
+int __clobber0,__clobber1;
__asm__ __volatile__ (
"shrl $1,%%ecx\n\t"
"rep\n\t"
@@ -651,15 +663,16 @@
"jnc 1f\n\t"
"movb %%al,(%%edi)\n"
"1:"
- : /* no output */
- :"c" (count),"D" (tmp), "a" (0x0101U * (unsigned char) c)
- :"cx","di","memory");
+ :"=&c" (__clobber0), "=&D" (__clobber1)
+ :"0" (count),"1" (tmp), "a" (0x0101U * (unsigned char) c)
+ :"memory");
return s;
}

extern inline void * __memset_gg(void * s,char c,size_t count)
{
register void *tmp = (void *)s;
+int __clobber0,__clobber1;
__asm__ __volatile__ (
"movb %%al,%%ah\n\t"
"shrl $1,%%ecx\n\t"
@@ -668,9 +681,9 @@
"jnc 1f\n\t"
"movb %%al,(%%edi)\n"
"1:"
- : /* no output */
- :"c" (count),"D" (tmp), "a" (c)
- :"cx","di","memory");
+ :"=&c" (__clobber0), "=&D" (__clobber1)
+ :"0" (count),"1" (tmp), "a" (c)
+ :"memory");
return s;
}

diff -ru linux_orig/include/asm-i386/string.h mylinux/include/asm-i386/string.h
--- linux_orig/include/asm-i386/string.h Mon Sep 29 13:10:03 1997
+++ mylinux/include/asm-i386/string.h Thu Mar 12 23:20:18 1998
@@ -30,20 +30,23 @@
#define __HAVE_ARCH_STRCPY
extern inline char * strcpy(char * dest,const char *src)
{
+int __clobber0,__clobber1;
__asm__ __volatile__(
"cld\n"
"1:\tlodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b"
- : /* no output */
- :"S" (src),"D" (dest):"si","di","ax","memory");
+ :"=&S" (__clobber0), "=&D" (__clobber1) /* earlyclobber */
+ :"0" (src),"1" (dest)
+ :"ax","memory");
return dest;
}

#define __HAVE_ARCH_STRNCPY
extern inline char * strncpy(char * dest,const char *src,size_t count)
{
+int __clobber0,__clobber1,__clobber2;
__asm__ __volatile__(
"cld\n"
"1:\tdecl %2\n\t"
@@ -55,14 +58,16 @@
"rep\n\t"
"stosb\n"
"2:"
- : /* no output */
- :"S" (src),"D" (dest),"c" (count):"si","di","ax","cx","memory");
+ :"=&S" (__clobber0), "=&D" (__clobber1), "=&c" (__clobber2)
+ :"0" (src),"1" (dest),"2" (count)
+ :"ax","memory");
return dest;
}

#define __HAVE_ARCH_STRCAT
extern inline char * strcat(char * dest,const char * src)
{
+int __clobber0,__clobber1,__clobber2,__clobber3;
__asm__ __volatile__(
"cld\n\t"
"repne\n\t"
@@ -72,20 +77,23 @@
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b"
- : /* no output */
- :"S" (src),"D" (dest),"a" (0),"c" (0xffffffff):"si","di","ax","cx");
+ :"=&S" (__clobber0), "=&D" (__clobber1), "=&a" (__clobber2),
+ "=&c" (__clobber3)
+ :"0" (src),"1" (dest),"2" (0),"3" (0xffffffff)
+ :"memory");
return dest;
}

#define __HAVE_ARCH_STRNCAT
extern inline char * strncat(char * dest,const char * src,size_t count)
{
+int __clobber0,__clobber1,__clobber2,__clobber3;
__asm__ __volatile__(
"cld\n\t"
"repne\n\t"
"scasb\n\t"
"decl %1\n\t"
- "movl %4,%3\n"
+ "movl %8,%3\n"
"1:\tdecl %3\n\t"
"js 2f\n\t"
"lodsb\n\t"
@@ -94,16 +102,17 @@
"jne 1b\n"
"2:\txorl %2,%2\n\t"
"stosb"
- : /* no output */
- :"S" (src),"D" (dest),"a" (0),"c" (0xffffffff),"g" (count)
- :"si","di","ax","cx","memory");
+ :"=&S" (__clobber0), "=&D" (__clobber1), "=&a" (__clobber2),
+ "=&c" (__clobber3)
+ :"0" (src),"1" (dest),"2" (0),"3" (0xffffffff),"g" (count)
+ :"memory");
return dest;
}

#define __HAVE_ARCH_STRCMP
extern inline int strcmp(const char * cs,const char * ct)
{
-register int __res;
+register int __res,__clobber0,__clobber1;
__asm__ __volatile__(
"cld\n"
"1:\tlodsb\n\t"
@@ -116,7 +125,8 @@
"2:\tsbbl %%eax,%%eax\n\t"
"orb $1,%%eax\n"
"3:"
- :"=a" (__res):"S" (cs),"D" (ct):"si","di");
+ :"=a" (__res), "=&S" (__clobber0), "=&D" (__clobber1)
+ :"1" (cs),"2" (ct));
return __res;
}

@@ -124,6 +134,7 @@
extern inline int strncmp(const char * cs,const char * ct,size_t count)
{
register int __res;
+int __clobber0,__clobber1,__clobber2;
__asm__ __volatile__(
"cld\n"
"1:\tdecl %3\n\t"
@@ -138,7 +149,9 @@
"3:\tsbbl %%eax,%%eax\n\t"
"orb $1,%%al\n"
"4:"
- :"=a" (__res):"S" (cs),"D" (ct),"c" (count):"si","di","cx");
+ :"=a" (__res), "=&S" (__clobber0), "=&D" (__clobber1),
+ "=&c" (__clobber2)
+ :"1" (cs),"2" (ct),"3" (count));
return __res;
}

@@ -146,6 +159,7 @@
extern inline char * strchr(const char * s, int c)
{
register char * __res;
+int __clobber0;
__asm__ __volatile__(
"cld\n\t"
"movb %%al,%%ah\n"
@@ -157,7 +171,8 @@
"movl $1,%1\n"
"2:\tmovl %1,%0\n\t"
"decl %0"
- :"=a" (__res):"S" (s),"0" (c):"si");
+ :"=a" (__res), "=&S" (__clobber0)
+ :"0" (c),"1" (s));
return __res;
}

@@ -165,6 +180,7 @@
extern inline char * strrchr(const char * s, int c)
{
register char * __res;
+int __clobber0,__clobber1;
__asm__ __volatile__(
"cld\n\t"
"movb %%al,%%ah\n"
@@ -174,7 +190,8 @@
"leal -1(%%esi),%0\n"
"2:\ttestb %%al,%%al\n\t"
"jne 1b"
- :"=d" (__res):"0" (0),"S" (s),"a" (c):"ax","si");
+ :"=d" (__res), "=&S" (__clobber0), "=&a" (__clobber1)
+ :"0" (0),"1" (s),"2" (c));
return __res;
}

@@ -182,9 +199,10 @@
extern inline size_t strspn(const char * cs, const char * ct)
{
register char * __res;
+int __clobber0,__clobber1;
__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"
@@ -193,14 +211,15 @@
"1:\tlodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %6,%%edi\n\t"
"movl %%edx,%%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");
+ :"=S" (__res),"=&a" (__clobber0), "=&c" (__clobber1)
+ :"1" (0),"2" (0xffffffff),"0" (cs),"g" (ct)
+ :"dx","di");
return __res-cs;
}

@@ -208,9 +227,10 @@
extern inline size_t strcspn(const char * cs, const char * ct)
{
register char * __res;
+int __clobber0,__clobber1;
__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"
@@ -219,14 +239,15 @@
"1:\tlodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %6,%%edi\n\t"
"movl %%edx,%%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");
+ :"=S" (__res), "=&a" (__clobber0), "=&c" (__clobber1)
+ :"1" (0),"2" (0xffffffff),"0" (cs),"g" (ct)
+ :"dx","di");
return __res-cs;
}

@@ -234,9 +255,10 @@
extern inline char * strpbrk(const char * cs,const char * ct)
{
register char * __res;
+int __clobber0,__clobber1;
__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"
@@ -245,7 +267,7 @@
"1:\tlodsb\n\t"
"testb %%al,%%al\n\t"
"je 2f\n\t"
- "movl %4,%%edi\n\t"
+ "movl %6,%%edi\n\t"
"movl %%edx,%%ecx\n\t"
"repne\n\t"
"scasb\n\t"
@@ -254,8 +276,9 @@
"jmp 3f\n"
"2:\txorl %0,%0\n"
"3:"
- :"=S" (__res):"a" (0),"c" (0xffffffff),"0" (cs),"g" (ct)
- :"ax","cx","dx","di");
+ :"=S" (__res), "=&a" (__clobber0), "=&c" (__clobber1)
+ :"1" (0),"2" (0xffffffff),"0" (cs),"g" (ct)
+ :"dx","di");
return __res;
}

@@ -263,15 +286,16 @@
extern inline char * strstr(const char * cs,const char * ct)
{
register char * __res;
+int __clobber0,__clobber1;
__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" /* NOTE! This also sets Z if searchstring='' */
"movl %%ecx,%%edx\n"
- "1:\tmovl %4,%%edi\n\t"
+ "1:\tmovl %6,%%edi\n\t"
"movl %%esi,%%eax\n\t"
"movl %%edx,%%ecx\n\t"
"repe\n\t"
@@ -283,22 +307,24 @@
"jne 1b\n\t"
"xorl %%eax,%%eax\n\t"
"2:"
- :"=a" (__res):"0" (0),"c" (0xffffffff),"S" (cs),"g" (ct)
- :"cx","dx","di","si");
+ :"=a" (__res), "=&c" (__clobber0), "=&S" (__clobber1)
+ :"0" (0),"1" (0xffffffff),"2" (cs),"g" (ct)
+ :"dx","di");
return __res;
}

#define __HAVE_ARCH_STRLEN
extern inline size_t strlen(const char * s)
{
-register int __res;
+register int __res,__clobber0;
__asm__ __volatile__(
"cld\n\t"
"repne\n\t"
"scasb\n\t"
"notl %0\n\t"
"decl %0"
- :"=c" (__res):"D" (s),"a" (0),"0" (0xffffffff):"di");
+ :"=c" (__res), "=&D" (__clobber0)
+ :"1" (s),"a" (0),"0" (0xffffffff));
return __res;
}

@@ -365,19 +391,20 @@

extern inline void * __memcpy(void * to, const void * from, size_t n)
{
+int __clobber0,__clobber1,__clobber2;
__asm__ __volatile__(
"cld\n\t"
"rep ; movsl\n\t"
- "testb $2,%b1\n\t"
+ "testb $2,%b4\n\t"
"je 1f\n\t"
"movsw\n"
- "1:\ttestb $1,%b1\n\t"
+ "1:\ttestb $1,%b4\n\t"
"je 2f\n\t"
"movsb\n"
"2:"
- : /* no output */
- :"c" (n/4), "q" (n),"D" ((long) to),"S" ((long) from)
- : "cx","di","si","memory");
+ :"=&c" (__clobber0), "=&D" (__clobber1), "=&S" (__clobber2)
+ :"0" (n/4), "q" (n),"1" ((long) to),"2" ((long) from)
+ :"memory");
return (to);
}

@@ -434,11 +461,11 @@
__asm__("cld\n\t" \
"rep ; movsl" \
x \
- : /* no outputs */ \
- : "c" (n/4),"D" ((long) to),"S" ((long) from) \
- : "cx","di","si","memory");
+ : "=&c" (__clobber0), "=&D" (__clobber1), "=&S" (__clobber2) \
+ : "0" (n/4),"1" ((long) to),"2" ((long) from) \
+ : "memory");

- switch (n % 4) {
+ switch (n % 4) { int __clobber0,__clobber1,__clobber2;
case 0: COMMON(""); return to;
case 1: COMMON("\n\tmovsb"); return to;
case 2: COMMON("\n\tmovsw"); return to;
@@ -455,26 +482,26 @@

#define __HAVE_ARCH_MEMMOVE
extern inline void * memmove(void * dest,const void * src, size_t n)
-{
+{ int __clobber0,__clobber1,__clobber2;
if (dest<src)
__asm__ __volatile__(
"cld\n\t"
"rep\n\t"
"movsb"
- : /* no output */
- :"c" (n),"S" (src),"D" (dest)
- :"cx","si","di");
+ :"=&c" (__clobber0), "=&S" (__clobber1), "=&D" (__clobber2)
+ :"0" (n),"1" (src),"2" (dest)
+ :"memory");
else
__asm__ __volatile__(
"std\n\t"
"rep\n\t"
"movsb\n\t"
"cld"
- : /* no output */
- :"c" (n),
- "S" (n-1+(const char *)src),
- "D" (n-1+(char *)dest)
- :"cx","si","di","memory");
+ :"=&c" (__clobber0), "=&S" (__clobber1), "=&D" (__clobber2)
+ :"0" (n),
+ "1" (n-1+(const char *)src),
+ "2" (n-1+(char *)dest)
+ :"memory");
return dest;
}

@@ -484,6 +511,7 @@
extern inline void * memchr(const void * cs,int c,size_t count)
{
register void * __res;
+int __clobber0;
if (!count)
return NULL;
__asm__ __volatile__(
@@ -493,20 +521,21 @@
"je 1f\n\t"
"movl $1,%0\n"
"1:\tdecl %0"
- :"=D" (__res):"a" (c),"D" (cs),"c" (count)
- :"cx");
+ :"=D" (__res), "=&c" (__clobber0)
+ :"a" (c),"0" (cs),"1" (count));
return __res;
}

extern inline void * __memset_generic(void * s, char c,size_t count)
-{
+{
+int __clobber0,__clobber1;
__asm__ __volatile__(
"cld\n\t"
"rep\n\t"
"stosb"
- : /* no output */
- :"a" (c),"D" (s),"c" (count)
- :"cx","di","memory");
+ :"=&c" (__clobber0), "=&D" (__clobber1)
+ :"a" (c),"1" (s),"0" (count)
+ :"memory");
return s;
}

@@ -520,19 +549,20 @@
*/
extern inline void * __constant_c_memset(void * s, unsigned long c, size_t count)
{
+int __clobber0,__clobber1;
__asm__ __volatile__(
"cld\n\t"
"rep ; stosl\n\t"
- "testb $2,%b1\n\t"
+ "testb $2,%b3\n\t"
"je 1f\n\t"
"stosw\n"
- "1:\ttestb $1,%b1\n\t"
+ "1:\ttestb $1,%b3\n\t"
"je 2f\n\t"
"stosb\n"
"2:"
- : /* no output */
- :"a" (c), "q" (count), "c" (count/4), "D" ((long) s)
- :"cx","di","memory");
+ :"=&c" (__clobber0), "=&D" (__clobber1)
+ :"a" (c), "q" (count), "0" (count/4), "1" ((long) s)
+ :"memory");
return (s);
}

@@ -540,20 +570,19 @@
#define __HAVE_ARCH_STRNLEN
extern inline size_t strnlen(const char * s, size_t count)
{
-register int __res;
+register int __res,__clobber0;
__asm__ __volatile__(
- "movl %1,%0\n\t"
+ "movl %2,%0\n\t"
"jmp 2f\n"
"1:\tcmpb $0,(%0)\n\t"
"je 3f\n\t"
"incl %0\n"
- "2:\tdecl %2\n\t"
- "cmpl $-1,%2\n\t"
+ "2:\tdecl %1\n\t"
+ "cmpl $-1,%1\n\t"
"jne 1b\n"
- "3:\tsubl %1,%0"
- :"=a" (__res)
- :"c" (s),"d" (count)
- :"dx");
+ "3:\tsubl %2,%0"
+ :"=a" (__res), "=&d" (__clobber0)
+ :"c" (s),"1" (count));
return __res;
}
/* end of additional stuff */
@@ -585,11 +614,12 @@
__asm__("cld\n\t" \
"rep ; stosl" \
x \
- : /* no outputs */ \
- : "a" (pattern),"c" (count/4),"D" ((long) s) \
- : "cx","di","memory")
+ : "=&c" (__clobber0), "=&D" (__clobber1) \
+ : "a" (pattern),"0" (count/4),"1" ((long) s) \
+ : "memory")

switch (count % 4) {
+ int __clobber0,__clobber1;
case 0: COMMON(""); return s;
case 1: COMMON("\n\tstosb"); return s;
case 2: COMMON("\n\tstosw"); return s;
@@ -627,7 +657,7 @@
jnz 1f
dec %%edi
1: "
- : "=D" (addr), "=c" (size)
+ : "=D" (addr), "=c" (size) /* why this ??? */
: "0" (addr), "1" (size), "a" (c));
return addr;
}
diff -ru linux_orig/include/asm-i386/system.h mylinux/include/asm-i386/system.h
--- linux_orig/include/asm-i386/system.h Wed Feb 11 17:19:33 1998
+++ mylinux/include/asm-i386/system.h Fri Mar 13 00:00:38 1998
@@ -114,29 +114,31 @@
#endif

#define _set_base(addr,base) \
-__asm__("movw %%dx,%0\n\t" \
+({ int __clobber0; \
+__asm__("movw %%dx,%1\n\t" \
"rorl $16,%%edx\n\t" \
- "movb %%dl,%1\n\t" \
- "movb %%dh,%2" \
- : /* no output */ \
+ "movb %%dl,%2\n\t" \
+ "movb %%dh,%3" \
+ :"=&d" (__clobber0) \
:"m" (*((addr)+2)), \
"m" (*((addr)+4)), \
"m" (*((addr)+7)), \
- "d" (base) \
- :"dx")
+ "0" (base)); \
+})

#define _set_limit(addr,limit) \
-__asm__("movw %%dx,%0\n\t" \
+({ int __clobber0; \
+__asm__("movw %%dx,%1\n\t" \
"rorl $16,%%edx\n\t" \
- "movb %1,%%dh\n\t" \
+ "movb %2,%%dh\n\t" \
"andb $0xf0,%%dh\n\t" \
"orb %%dh,%%dl\n\t" \
- "movb %%dl,%1" \
- : /* no output */ \
+ "movb %%dl,%2" \
+ :"=&d" (__clobber0) \
:"m" (*(addr)), \
"m" (*((addr)+6)), \
- "d" (limit) \
- :"dx")
+ "0" (limit)); \
+})

#define set_base(ldt,base) _set_base( ((char *)&(ldt)) , base )
#define set_limit(ldt,limit) _set_limit( ((char *)&(ldt)) , (limit-1)>>12 )
@@ -247,15 +249,18 @@
#endif

#define _set_gate(gate_addr,type,dpl,addr) \
+({ \
+int __clobber0,__clobber1; \
__asm__ __volatile__ ("movw %%dx,%%ax\n\t" \
- "movw %2,%%dx\n\t" \
+ "movw %4,%%dx\n\t" \
"movl %%eax,%0\n\t" \
"movl %%edx,%1" \
:"=m" (*((long *) (gate_addr))), \
- "=m" (*(1+(long *) (gate_addr))) \
+ "=m" (*(1+(long *) (gate_addr))), \
+ "=&a" (__clobber0), "=&d" (__clobber1) \
:"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \
- "d" ((char *) (addr)),"a" (__KERNEL_CS << 16) \
- :"ax","dx")
+ "3" ((char *) (addr)),"2" (__KERNEL_CS << 16)); \
+})

#define set_intr_gate(n,addr) \
_set_gate(idt+(n),14,0,addr)
diff -ru linux_orig/include/asm-i386/uaccess.h mylinux/include/asm-i386/uaccess.h
--- linux_orig/include/asm-i386/uaccess.h Wed Feb 11 17:18:10 1998
+++ mylinux/include/asm-i386/uaccess.h Fri Mar 13 09:30:22 1998
@@ -249,13 +249,14 @@

/* Generic arbitrary sized copy. */
#define __copy_user(to,from,size) \
+({ int __clobber0,__clobber1; \
__asm__ __volatile__( \
"0: rep; movsl\n" \
- " movl %1,%0\n" \
+ " movl %3,%0\n" \
"1: rep; movsb\n" \
"2:\n" \
".section .fixup,\"ax\"\n" \
- "3: lea 0(%1,%0,4),%0\n" \
+ "3: lea 0(%3,%0,4),%0\n" \
" jmp 2b\n" \
".previous\n" \
".section __ex_table,\"a\"\n" \
@@ -263,9 +264,10 @@
" .long 0b,3b\n" \
" .long 1b,2b\n" \
".previous" \
- : "=&c"(size) \
- : "r"(size & 3), "0"(size / 4), "D"(to), "S"(from) \
- : "di", "si", "memory")
+ : "=&c"(size), "=&D" (__clobber0), "=&S" (__clobber1) \
+ : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from) \
+ : "memory"); \
+})

/* We let the __ versions of copy_from/to_user inline, because they're often
* used in fast paths and have only a small space overhead.
@@ -287,7 +289,7 @@

/* Optimize just a little bit when we know the size of the move. */
#define __constant_copy_user(to, from, size) \
-do { \
+do { int __clobber0,__clobber1; \
switch (size & 3) { \
default: \
__asm__ __volatile__( \
@@ -301,9 +303,10 @@
" .align 4\n" \
" .long 0b,2b\n" \
".previous" \
- : "=c"(size) \
- : "S"(from), "D"(to), "0"(size/4) \
- : "di", "si", "memory"); \
+ : "=c"(size), "=&D" (__clobber0), \
+ "=&S" (__clobber1) \
+ : "2"(from), "1"(to), "0"(size/4) \
+ : "memory"); \
break; \
case 1: \
__asm__ __volatile__( \
@@ -320,9 +323,10 @@
" .long 0b,3b\n" \
" .long 1b,4b\n" \
".previous" \
- : "=c"(size) \
- : "S"(from), "D"(to), "0"(size/4) \
- : "di", "si", "memory"); \
+ : "=c"(size), "=&D" (__clobber0), \
+ "=&S" (__clobber1) \
+ : "2"(from), "1"(to), "0"(size/4) \
+ : "memory"); \
break; \
case 2: \
__asm__ __volatile__( \
@@ -339,9 +343,10 @@
" .long 0b,3b\n" \
" .long 1b,4b\n" \
".previous" \
- : "=c"(size) \
- : "S"(from), "D"(to), "0"(size/4) \
- : "di", "si", "memory"); \
+ : "=c"(size), "=&D" (__clobber0), \
+ "=&S" (__clobber1) \
+ : "2"(from), "1"(to), "0"(size/4) \
+ : "memory"); \
break; \
case 3: \
__asm__ __volatile__( \
@@ -361,9 +366,10 @@
" .long 1b,5b\n" \
" .long 2b,6b\n" \
".previous" \
- : "=c"(size) \
- : "S"(from), "D"(to), "0"(size/4) \
- : "di", "si", "memory"); \
+ : "=c"(size), "=&D" (__clobber0), \
+ "=&S" (__clobber1) \
+ : "2"(from), "1"(to), "0"(size/4) \
+ : "memory"); \
break; \
} \
} while (0)

--------------5684A7852201BD6A9DF4EA19--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu