lkml.org 
[lkml]   [1996]   [May]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
SubjectPatch to make include/asm-i386/checksum.h nicer for gcc & people
A while back I asked on linux-gcc about a patch to system.h that added
what looks like a gratuitous "&" to some __asm__ output operand
constraints. I never got an authoritative answer about why that patch
was made. It turns out that using "&" where it isn't really needed
can result in some suboptimal code generation. So I went back and
deleted some similar cruft in include/asm-i386/checksum.h (which I put
there in the first place).

I also and added some comments about non-obvious goings on in the
__asm__ stuff.

And relaxed some operand constraints to allow operands to be used from
memory, which avoids making gcc allocate a whole pile of registers for
an __asm__ when it doesn't have to.

And I rewrote csum_tcpudp_magic() and ip_compute_csum() in terms of
csum_fold(), which seems to have been added since the last time I
looked at checksum.h.

This patch is against 1.3.97. I've been running with it since April 8
using gcc-2.7.2.

--- linux/include/asm-i386/checksum.h.0 Tue Oct 3 02:45:59 1995
+++ linux/include/asm-i386/checksum.h Mon Apr 8 09:17:57 1996
@@ -65,14 +65,30 @@
notl %0
2:
"
- : "=&r" (sum), "=&r" (iph), "=&r" (ihl)
+ /* Since the input registers which are loaded with iph and ipl
+ are modified, we must also specify them as outputs, or gcc
+ will assume they contain their original values. */
+ : "=r" (sum), "=r" (iph), "=r" (ihl)
: "1" (iph), "2" (ihl));
return(sum);
}

+/*
+ * Fold a partial checksum
+ */

-
-
+static inline unsigned int csum_fold(unsigned int sum)
+{
+ __asm__("
+ addl %1, %0
+ adcl $0xffff, %0
+ "
+ : "=r" (sum)
+ : "r" (sum << 16), "0" (sum & 0xffff0000)
+ );
+ return (~sum) >> 16;
+}
+
/*
* computes the checksum of the TCP/UDP pseudo-header
* returns a 16-bit checksum, already complemented
@@ -85,55 +101,21 @@
unsigned int sum) {
__asm__("
addl %1, %0
- adcl %4, %0
- adcl %5, %0
- adcl $0, %0
- movl %0, %1
- shrl $16, %1
- addw %w1, %w0
+ adcl %2, %0
+ adcl %3, %0
adcl $0, %0
- notl %0
"
- : "=&r" (sum), "=&r" (saddr)
- : "0" (daddr), "1"(saddr), "r"((ntohs(len)<<16)+proto*256), "r"(sum));
- return((unsigned short)sum);
-}
-
-/*
- * Fold a partial checksum without adding pseudo headers
- */
-
-static inline unsigned int csum_fold(unsigned int sum)
-{
- __asm__("
- addl %1, %0
- adcl $0xffff, %0
- "
- : "=r" (sum)
- : "r" (sum << 16), "0" (sum & 0xffff0000)
- );
- return (~sum) >> 16;
+ : "=r" (sum)
+ : "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum));
+ return csum_fold(sum);
}
-
/*
* this routine is used for miscellaneous IP-like checksums, mainly
* in icmp.c
*/

static inline unsigned short ip_compute_csum(unsigned char * buff, int len) {
- unsigned int sum;
-
- unsigned int scratch;
- __asm__("
- movl %0, %1
- shrl $16, %1
- addw %w1, %w0
- adcl $0, %0
- notl %0
- "
- : "=a"(sum), "=r" (scratch)
- : "0" (csum_partial(buff, len, 0)));
- return(sum);
+ return csum_fold (csum_partial(buff, len, 0));
}

#endif

Tom.


\
 
 \ /
  Last update: 2005-03-22 13:37    [W:0.045 / U:1.280 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site