lkml.org 
[lkml]   [1996]   [May]   [2]   [last100]   RSS Feed
Views: [more markup]  [less markup]  [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
DateWed, 1 May 1996 19:27:51 -0700
From(Tom May)
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    [from the cache]
©2003-2008