i386/69257: in_cksum_hdr is non-functional without -O compiler
flag
Mike Bristow
mike at urgle.com
Wed Aug 25 02:40:27 PDT 2004
The following reply was made to PR i386/69257; it has been noted by GNATS.
From: Mike Bristow <mike at urgle.com>
To: freebsd-gnats-submit at FreeBSD.org, qing.li at 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;
More information about the freebsd-i386
mailing list