- /*
- * Do as much of the checksum as possible 32 bits at at time.
- * In fact, this loop is unrolled to make overhead from
- * branches &c small.
- *
- * We can do a 16 bit ones complement sum 32 bits at a time
- * because the 32 bit register is acting as two 16 bit
- * registers for adding, with carries from the low added
- * into the high (by normal carry-chaining) and carries
- * from the high carried into the low on the next word
- * by use of the adwc instruction. This lets us run
- * this loop at almost memory speed.
- *
- * Here there is the danger of high order carry out, and
- * we carefully use adwc.
- */
- while ((nleft -= 32) >= 0) {
-#undef ADD
- asm("clrl r0"); /* clears carry */
-#define ADD asm("adwc (r9)+,r8;");
- ADD; ADD; ADD; ADD; ADD; ADD; ADD; ADD;
- asm("adwc $0,r8");
- }
- nleft += 32;
- while ((nleft -= 8) >= 0) {
- asm("clrl r0");
- ADD; ADD;
- asm("adwc $0,r8");
- }
- nleft += 8;
- /*
- * Now eliminate the possibility of carry-out's by
- * folding back to a 16 bit number (adding high and
- * low parts together.) Then mop up trailing words
- * and maybe an odd byte.
- */
- { asm("ashl $-16,r8,r0; addw2 r0,r8");
- asm("adwc $0,r8; movzwl r8,r8"); }
- while ((nleft -= 2) >= 0) {
- asm("movzwl (r9)+,r0; addl2 r0,r8");
- }
- if (nleft == -1) {
- sum += *(u_char *)w;