faster cksum
[unix-history] / usr / src / sys / vax / vax / in_cksum.c
CommitLineData
4d0a6cbd 1/* in_cksum.c 1.4 81/10/20 */
51041fae
BJ
2
3#include <sys/types.h>
4#include "../bbnnet/net.h"
5#include "../bbnnet/count.h"
6
7/*
8 * Network primitives; this file varies per-cpu,
9 * and the code here is for VAX only.
10 */
51041fae
BJ
11
12/*
13 * Checksum routine for TCP/IP headers. This
14 * is very heavily used in the network
15 * code and should be rewritten for each CPU
16 * to be as fast as possible.
17 */
1e92f1b1 18cksum(m, len)
51041fae
BJ
19 register struct mbuf *m;
20 register int len;
21{
4d0a6cbd 22 register long *l; /* known to be r9 */
51041fae 23 register int sum = 0; /* known to be r8 */
4d0a6cbd 24 register u_short *w; /* known to be r7 */
51041fae 25 register int mlen = 0;
1e92f1b1 26COUNT(CKSUM);
51041fae
BJ
27
28 for (;;) {
29 w = (u_short *)((int)m + m->m_off);
30 if (mlen == -1) {
31 sum += *(u_char *)w << 8;
32 w = (unsigned short *)((char *)w + 1);
33 mlen = m->m_len - 1;
34 len--;
35 } else
36 mlen = m->m_len;
37 m = m->m_next;
38 if (len < mlen)
39 mlen = len;
40 len -= mlen;
4d0a6cbd 41 l = (long *)w;
51041fae 42 while ((mlen -= 32) >= 0) {
4d0a6cbd
BJ
43 asm("clrl r0"); /* clears carry */
44#undef ADD
45#define ADD asm("adwc (r9)+,r8;");
51041fae 46 ADD; ADD; ADD; ADD; ADD; ADD; ADD; ADD;
4d0a6cbd 47 asm("adwc $0,r8");
51041fae
BJ
48 }
49 mlen += 32;
50 while ((mlen -= 8) >= 0) {
4d0a6cbd
BJ
51 asm("clrl r0");
52 ADD; ADD;
53 asm("adwc $0,r8");
51041fae
BJ
54 }
55 mlen += 8;
4d0a6cbd
BJ
56 sum = ((sum >> 16) & 0xffff) + (sum & 0xffff);
57 w = (u_short *)l;
51041fae 58 while ((mlen -= 2) >= 0) {
4d0a6cbd 59 asm("movzwl (r7)+,r0; addl2 r0,r8");
51041fae
BJ
60 }
61 if (mlen == -1)
62 sum += *(u_char *)w;
63 if (len == 0)
64 break;
65 for (;;) {
f248b7ed
BJ
66 if (m == 0) {
67 printf("cksum: out of data");
68 goto done;
69 }
51041fae
BJ
70 if (m->m_len)
71 break;
72 m = m->m_next;
73 }
74 }
f248b7ed 75done:
51041fae
BJ
76 return(~(sum + (sum >> 16)) & 0xffff);
77}