[parisc-linux-cvs] [DIFF] 2.4.17-pa13 diff (IPV6)

Grant Grundler grundler@dsl2.external.hp.com
Mon, 21 Jan 2002 22:16:00 -0700


Grant Grundler wrote:
> 	include/asm-parisc: checksum.h 
> 
> Log message:
> 2.4.17-pa13
> replace BUG() in csum_ipv6_magic() with both PA2.0 and PA1.1 __asm__.
> I modeled the asm after the generic csum_ipv6_magic().
> This code is *NOT* tested since I have no clue about IPV6.


Index: Makefile
===================================================================
RCS file: /var/cvs/linux/Makefile,v
retrieving revision 1.250
diff -u -p -r1.250 Makefile
--- Makefile	2002/01/21 00:15:15	1.250
+++ Makefile	2002/01/22 05:08:24
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 17
-EXTRAVERSION = -pa12
+EXTRAVERSION = -pa13
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
Index: include/asm-parisc/checksum.h
===================================================================
RCS file: /var/cvs/linux/include/asm-parisc/checksum.h,v
retrieving revision 1.11
diff -u -p -r1.11 checksum.h
--- include/asm-parisc/checksum.h	2001/05/12 16:55:11	1.11
+++ include/asm-parisc/checksum.h	2002/01/22 05:08:24
@@ -143,6 +143,7 @@ static inline unsigned short ip_compute_
 	 return csum_fold (csum_partial(buf, len, 0));
 }
 
+
 #define _HAVE_ARCH_IPV6_CSUM
 static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr,
 						     struct in6_addr *daddr,
@@ -150,7 +151,62 @@ static __inline__ unsigned short int csu
 						     unsigned short proto,
 						     unsigned int sum) 
 {
-	BUG();
+	__asm__ __volatile__ (
+
+#if BITS_PER_LONG > 32
+
+	/*
+	** We can execute two loads and two adds per cycle on PA 8000.
+	** But add insn's get serialized waiting for the carry bit.
+	** Try to keep 4 registers with "live" values ahead of the ALU.
+	*/
+
+"	ldd,ma		4(%1), %%r19\n"	/* get 1st saddr word */
+"	ldd,ma		4(%2), %%r20\n"	/* get 1st daddr word */
+"	add		%4, %3, %3\n"/* add 16-bit proto + len */
+"	add		%%r19, %0, %0\n"
+"	ldd,ma		4(%1), %%r21\n"	/* 2cd saddr */
+"	ldd,ma		4(%2), %%r22\n"	/* 2cd daddr */
+"	add,dc		%%r20, %0, %0\n"
+"	add,dc		%%r21, %0, %0\n"
+"	add,dc		%%r22, %0, %0\n"
+"	add,dc		%3, %0, %0\n"  /* fold in proto+len | carry bit */
+"	extrd,u		%0, 31, 32, %%r19\n"	/* copy upper half down */
+"	depdi		0, 31, 32, %0\n"	/* clear upper half */
+"	add		%%r19, %0, %0\n"	/* fold into 32-bits */
+"	addc		0, %0, %0\n"		/* add carry */
+
+#else
+
+	/*
+	** For PA 1.x, the insn order doesn't matter as much.
+	** Insn stream is serialized on the carry bit here too.
+	** result from the previous operation (eg r0 + x)
+	*/
+
+"	ldw,ma		4(%1), %%r19\n"	/* get 1st saddr word */
+"	ldw,ma		4(%2), %%r20\n"	/* get 1st daddr word */
+"	add		%4, %3, %3\n"	/* add 16-bit proto + len */
+"	add		%%r19, %0, %0\n"
+"	ldw,ma		4(%1), %%r21\n"	/* 2cd saddr */
+"	addc		%%r20, %0, %0\n"
+"	ldw,ma		4(%2), %%r22\n"	/* 2cd daddr */
+"	addc		%%r21, %0, %0\n"
+"	ldw,ma		4(%1), %%r19\n"	/* 3rd saddr */
+"	addc		%%r22, %0, %0\n"
+"	ldw,ma		4(%2), %%r20\n"	/* 3rd daddr */
+"	addc		%%r19, %0, %0\n"
+"	ldw,ma		4(%1), %%r21\n"	/* 4th saddr */
+"	addc		%%r20, %0, %0\n"
+"	ldw,ma		4(%2), %%r22\n"	/* 4th daddr */
+"	addc		%%r21, %0, %0\n"
+"	addc		%%r22, %0, %0\n"
+"	addc		%3, %0, %0\n"	/* fold in proto+len, catch carry */
+
+#endif
+	: "=r" (sum), "=r" (saddr), "=r" (daddr), "=r" (len)
+	: "0" (sum), "1" (saddr), "2" (daddr), "3" (len), "r" (proto)
+	: "r19", "r20", "r21", "r22");
 	return csum_fold(sum);
 }