[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);
}