1 /*
2  * Copyright (c) 1983 Regents of the University of California.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms are permitted
6  * provided that this notice is preserved and that due credit is given
7  * to the University of California at Berkeley. The name of the University
8  * may not be used to endorse or promote products derived from this
9  * software without specific prior written permission. This software
10  * is provided ``as is'' without express or implied warranty.
11  */
12 
13 #ifndef lint
14 static char sccsid[] = "@(#)cksum.vax.c	1.3 (Berkeley) 12/23/87";
15 #endif /* not lint */
16 
17 #include <sys/types.h>
18 
19 #define ADD	asm("adwc (r9)+,r8;");
20 
21 /* computes the checksum for ip packets for the VAX */
22 
23 in_cksum(addr, len)
24 u_short *addr;
25 int len;
26 {
27 	register int nleft = len;	/* on vax, (user mode), r11 */
28 #ifndef lint
29 	register int xxx;		/* on vax, (user mode), r10 */
30 #endif not lint
31 	register u_short *w = addr;	/* on vax, known to be r9 */
32 	register int sum = 0;		/* on vax, known to be r8 */
33 
34 	if (((int)w&0x2) && nleft >= 2) {
35 		sum += *w++;
36 		nleft -= 2;
37 	}
38 	while ((nleft -= 32) >= 0) {
39 		asm("clrl r0");		/* clears carry */
40 		ADD; ADD; ADD; ADD; ADD; ADD; ADD; ADD;
41 		asm("adwc $0,r8");
42 	}
43 	nleft += 32;
44 	while ((nleft -= 8) >= 0) {
45 		asm("clrl r0");
46 		ADD; ADD;
47 		asm("adwc $0,r8");
48 	}
49 	nleft += 8;
50 	{ asm("ashl $-16,r8,r0; addw2 r0,r8");
51 	  asm("adwc $0,r8; movzwl r8,r8"); }
52 	while ((nleft -= 2) >= 0) {
53 		asm("movzwl (r9)+,r0; addl2 r0,r8");
54 	}
55 	if (nleft == -1) {
56 		sum += *(u_char *)w;
57 	}
58 
59 	{ asm("ashl $-16,r8,r0; addw2 r0,r8; adwc $0,r8");
60 	  asm("mcoml r8,r8; movzwl r8,r8"); }
61 	return (sum);
62 }
63