;-*- MODE: LISP; BASE: 8.; READTABLE: ZL -*- (DEFCONST UC-TCP-IP '( ;;Support for TCP/IP checksum (misc-inst-entry %ip-checksum) ;call: (%ip-checksum array sum count odd-p) ;Register usage: ; (vma) current address in array ; (m-a) bytes remaining (as a fixnum) ; (m-b) 0,1,2,3 -- byte within word ; (m-c) 0,1 -- have-word flag ; (m-d) 0,1 -- odd-p (0 -> add to high-sum, 1 -> add to low-sum) ; (m-1) high-sum ; (m-2) low-sum ; (m-t) current byte ; (md) current word from array ;Get odd-p into m-t ((m-t) c-pdl-buffer-pointer-pop) (jump-equal-xct-next m-t a-v-nil checksum-not-odd-p) ((m-d) a-zero) ((m-d) a-minus-one) checksum-not-odd-p ;Get count into m-a ((m-a) q-pointer c-pdl-buffer-pointer-pop) ;Get sum into m-t, high-sum into m-1, and low-sum into m-2 ((m-t) c-pdl-buffer-pointer-pop) ;Get array into m-array-pointer ((m-array-pointer) invalidate-array-cache c-pdl-buffer-pointer-pop) ((pdl-push) m-t) ;Save sum ((pdl-push) m-d) ;Save odd-p (call-xct-next GADPTR) ;Get array header, following indirection ((pdl-push) m-a) ;Save count ((m-a) pdl-pop) ;Restore count ((m-d) pdl-pop) ;Restore odd-p ((m-1) ldb (byte-field 8. 8.) pdl-top) ;Get high-sum into m-1 ((m-2) ldb (byte-field 8. 0) pdl-pop) ;Get low-sum into m-2 ((m-3) add m-a a-q) ;count + initial index (jump-greater-xct-next m-3 a-array-length checksum-done) ;bounds check ((m-b) m-q) ;Initial index into m-b ((m-3) ldb (byte-field 23. 2) m-q) ;High-bytes of initial index ((m-3) m-a-1 m-3 a-zero) ; ... -1 ((vma) add m-array-origin a-3) ;Now vma points one before first actual word of array (jump-equal-xct-next m-a a-zero checksum-done) ;If count is zero, we are done ((m-c) a-zero) ;We don't have a word yet checksum-loop (jump-equal-xct-next m-c a-minus-one checksum-have-word) ;branch if we already have word ((m-c) a-minus-one) ;Indicate we have word ((vma-start-read) m+1 vma) ;Read next word (check-page-read) checksum-have-word (dispatch-xct-next (byte-field 2 0) m-b d-checksum-byte) ((m-a) m-a-1 m-a a-zero) (locality d-mem) (start-dispatch 2 0) d-checksum-byte (checksum-byte-0) (checksum-byte-1) (checksum-byte-2) (checksum-byte-3) (end-dispatch) (locality i-mem) checksum-byte-0 (jump-xct-next checksum-have-byte) ((m-t) ldb (byte-field 8. 0) md) checksum-byte-1 (jump-xct-next checksum-have-byte) ((m-t) ldb (byte-field 8. 8.) md) checksum-byte-2 (jump-xct-next checksum-have-byte) ((m-t) ldb (byte-field 8. 16.) md) checksum-byte-3 ((m-t) ldb (byte-field 8. 24.) md) ((m-c) a-zero) ;Need a new word next time checksum-have-byte (jump-not-equal-xct-next m-d a-zero checksum-add-to-low) ((m-b) m+1 m-b) ;Point to next byte within word ((m-1) add m-1 a-t) ;Add to high-sum (jump-not-equal-xct-next m-a a-zero checksum-loop) ;Go get next byte ((m-d) a-minus-one) ;Add to low-sum next time (jump checksum-done) ;We are done -- go assemble the checksum checksum-add-to-low ((m-2) add m-2 a-t) ;Add to low-sum (jump-not-equal-xct-next m-a a-zero checksum-loop) ;Go get next byte ((m-d) a-zero) ;Add to high-sum next time checksum-done ((m-3) ldb (byte-field 24. 8.) m-2) ;Get carry from low-sum ((m-1) add m-1 a-3) ;Add into high-sum ((m-2) dpb m-1 (byte-field 24. 8.) a-2) ;Stick high-sum above low-sum checksum-done-loop ((m-3) ldb (byte-field 16. 16.) m-2) ;Get carry from concatenated bytes (jump-equal-xct-next m-3 a-zero checksum-return) ;If no carry, we are done ((m-1) ldb (byte-field 16. 0.) m-2) ;Put low 16 bits of sum into m-1 (jump-xct-next checksum-done-loop) ((m-2) add m-1 a-3) ;Add carry into sum checksum-return (popj-after-next ;Move checksum to m-t, box it, and return (m-t) dpb m-2 q-pointer (a-constant (byte-value q-data-type dtp-fix))) (no-op) ))