Sophie

Sophie

distrib > Mandriva > 2009.0 > i586 > by-pkgid > 0e3fdb557fa7934b4aa1ea3c70702470 > files > 9

dip-3.3.7o-28mdv2009.0.src.rpm

--- dip-3.3.7o/command.c.ppc	2004-07-09 20:13:03.232570358 +0200
+++ dip-3.3.7o/command.c	2004-07-09 20:13:03.297570846 +0200
@@ -2499,7 +2499,131 @@
 	return(csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, 0));
 }
 
-#elif defined(__i386__) /* !__alpha__ && !__sparc__ */
+#elif defined(__powerpc__)
+
+/*
+ * Compute IP checksums
+ *   _ip_fast_csum(buf, len) -- Optimized for IP header
+ *   _ip_compute_csum(buf, len)
+ */
+__asm__ (
+"        .text\n"
+"        .globl _ip_fast_csum\n"
+"_ip_fast_csum:\n"
+"	li	%r0,0\n"
+"	addic	%r0,%r0,0\n"		/* Clear initial carry */
+"	lwz	%r4,0(%r3)\n"
+"	lwz	%r5,4(%r3)\n"
+"	adde	%r0,%r0,%r4\n"
+"	lwz	%r4,8(%r3)\n"
+"	adde	%r0,%r0,%r5\n"
+"	lwz	%r5,12(%r3)\n"
+"	adde	%r0,%r0,%r4\n"
+"	lwz	%r4,16(%r3)\n"
+"	adde	%r0,%r0,%r5\n"
+"	adde	%r0,%r0,%r4\n"
+"	mr	%r3,%r0\n"
+"	andi.	%r3,%r3,0xFFFF\n"
+"	srwi	%r0,%r0,16\n"
+"	adde	%r3,%r3,%r0\n"
+"	andis.	%r0,%r3,1\n"
+"	beq	10f\n"
+"	addi	%r3,%r3,1\n"
+"10:	not	%r3,%r3\n"
+"	andi.	%r3,%r3,0xFFFF\n"
+"	blr\n"
+"\n"
+"        .globl  _ip_compute_csum\n"
+"_ip_compute_csum:\n"
+"	li	%r0,0\n"
+"	addic	%r0,%r0,0\n"
+"finish_ip_csum:	\n"
+"	subi	%r3,%r3,4\n"
+"	andi.	%r5,%r3,2\n"		/* Align buffer to longword boundary */
+"	beq	10f\n"
+"	lhz	%r5,4(%r3)\n"
+"	adde	%r0,%r0,%r5\n"
+"	addi	%r3,%r3,2\n"
+"	subi	%r4,%r4,2\n"
+"10:	cmpi	0,%r4,16\n"		/* unrolled loop - 16 bytes at a time */
+"	blt	20f\n"
+"	lwz	%r5,4(%r3)\n"
+"	lwz	%r6,8(%r3)\n"
+"	adde	%r0,%r0,%r5\n"
+"	lwz	%r5,12(%r3)\n"
+"	adde	%r0,%r0,%r6\n"
+"	lwzu	%r6,16(%r3)\n"
+"	adde	%r0,%r0,%r5\n"
+"	adde	%r0,%r0,%r6\n"
+"	subi	%r4,%r4,16\n"
+"	b	10b\n"
+"20:	cmpi	0,%r4,4\n"
+"	blt	30f\n"
+"	lwzu	%r5,4(%r3)\n"
+"	adde	%r0,%r0,%r5\n"
+"	subi	%r4,%r4,4\n"
+"	b	20b\n"
+"30:	cmpi	0,%r4,2\n"
+"	blt	40f\n"
+"	lhz	%r5,4(%r3)\n"
+"	addi	%r3,%r3,2\n"
+"	adde	%r0,%r0,%r5\n"
+"	subi	%r4,%r4,2\n"
+"40:	cmpi	0,%r4,1\n"
+"	bne	50f\n"
+"	lbz	%r5,4(%r3)\n"
+"	slwi	%r5,%r5,8\n"		/* Upper byte of word */
+"	adde	%r0,%r0,%r5\n"
+"50:	mr	%r3,%r0\n"
+"	andi.	%r3,%r3,0xFFFF\n"
+"	srwi	%r0,%r0,16\n"
+"	adde	%r3,%r3,%r0\n"
+"	andis.	%r0,%r3,1\n"
+"	beq	60f\n"
+"	addi	%r3,%r3,1\n"
+"60:	not	%r3,%r3\n"
+"	andi.	%r3,%r3,0xFFFF\n"
+"	blr\n"
+"\n"
+"        .globl  _udp_check\n"
+"_udp_check:\n"
+"	addc	%r0,%r5,%r6\n"	/* Add in header fields */
+"	adde	%r0,%r0,%r7\n"
+"	b	finish_ip_csum	\n"
+);
+
+extern unsigned short _ip_fast_csum(unsigned char *buf);
+
+unsigned short
+ip_fast_csum(unsigned char *buf, unsigned int len)
+{
+	unsigned short _val;
+	_val = _ip_fast_csum(buf);
+#if 0
+	printk("IP CKSUM(%x, %d) = %x\n", buf, len, _val);
+	dump_buf(buf, len*4);
+#endif	
+	return (_val);
+}
+
+unsigned short
+_udp_check(unsigned char *buf, int len, int saddr, int daddr, int hdr);
+
+unsigned short
+udp_check(unsigned char *buf, int len, int saddr, int daddr)
+{
+	unsigned short _val;
+	int hdr;
+	hdr = (len << 16) + IPPROTO_UDP;
+	_val = _udp_check(buf, len, saddr, daddr, hdr);
+#if 0
+	printk("UDP CSUM(%x,%d,%x,%x) = %x\n", buf, len, saddr, daddr, _val);
+	dump_buf(buf, len);
+#endif	
+	return (_val);
+}
+
+#elif defined(__i386__) /* !__alpha__ && !__sparc__ && !__powerpc__ */
 
 /* This is a version of ip_compute_csum() optimized for IP headers, which
    always checksum on 4 octet boundaries. */