Date: Wed, 25 Aug 2004 09:40:26 GMT From: Mike Bristow <mike@urgle.com> To: freebsd-i386@FreeBSD.org Subject: Re: i386/69257: in_cksum_hdr is non-functional without -O compiler flag Message-ID: <200408250940.i7P9eQFh011459@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR i386/69257; it has been noted by GNATS. From: Mike Bristow <mike@urgle.com> To: freebsd-gnats-submit@FreeBSD.org, qing.li@bluecoat.com Cc: Subject: Re: i386/69257: in_cksum_hdr is non-functional without -O compiler flag Date: Wed, 25 Aug 2004 10:33:37 +0100 The patch below (might) fix this issue - I haven't yet built it into a kernel without -O to see. However, with a small test program, it generates identical (if we ignore whitespace) asm with -O, and what appears to different-but-correct assembler without. I do not believe that there is any other way of preventing the compiler inserting arbitrary instructions between different __asm statements (and that the commit message in revision 1.13 of in_cksum.h is now wrong on this point). From http://developer.apple.com/documentation/DeveloperTools/gcc-3.3/gcc/Extended-Asm.html ---8<---8<---8<--- You can't expect a sequence of volatile asm instructions to remain perfectly consecutive. If you want consecutive output, use a single asm. Also, GCC will perform some optimizations across a volatile asm instruction; GCC does not "forget everything" when it encounters a volatile asm instruction the way some other compilers do. ---8<---8<---8<--- Obviously, this may not be true anymore for gcc 3.4 - except that's the behaviour we are seeing, so I guess it is. --- sys/i386/include/in_cksum.h.orig Wed Apr 7 21:46:05 2004 +++ sys/i386/include/in_cksum.h Wed Aug 25 09:45:39 2004 @@ -55,22 +55,20 @@ { register u_int sum = 0; -/* __volatile is necessary here because the condition codes are used. */ -#define ADD(n) __asm __volatile ("addl %1, %0" : "+r" (sum) : \ - "g" (((const u_int32_t *)ip)[n / 4])) -#define ADDC(n) __asm __volatile ("adcl %1, %0" : "+r" (sum) : \ - "g" (((const u_int32_t *)ip)[n / 4])) -#define MOP __asm __volatile ("adcl $0, %0" : "+r" (sum)) - - ADD(0); - ADDC(4); - ADDC(8); - ADDC(12); - ADDC(16); - MOP; -#undef ADD -#undef ADDC -#undef MOP + __asm __volatile ( + "addl %1, %0\n" + "adcl %2, %0\n" + "adcl %3, %0\n" + "adcl %4, %0\n" + "adcl %5, %0\n" + "adcl $0, %0" + : "+r" (sum) + : "g" (((const u_int32_t *)ip)[0]), + "g" (((const u_int32_t *)ip)[1]), + "g" (((const u_int32_t *)ip)[2]), + "g" (((const u_int32_t *)ip)[3]), + "g" (((const u_int32_t *)ip)[4]) + ); sum = (sum & 0xffff) + (sum >> 16); if (sum > 0xffff) sum -= 0xffff;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200408250940.i7P9eQFh011459>