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