checksum.S 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. /*
  2. * A fast checksum routine using movem
  3. * Copyright (c) 1998-2007 Axis Communications AB
  4. *
  5. * csum_partial(const unsigned char * buff, int len, unsigned int sum)
  6. */
  7. .globl csum_partial
  8. csum_partial:
  9. ;; r10 - src
  10. ;; r11 - length
  11. ;; r12 - checksum
  12. ;; Optimized for large packets
  13. subq 10*4, $r11
  14. blt _word_loop
  15. move.d $r11, $acr
  16. subq 9*4,$sp
  17. clearf c
  18. movem $r8,[$sp]
  19. ;; do a movem checksum
  20. _mloop: movem [$r10+],$r9 ; read 10 longwords
  21. ;; Loop count without touching the c flag.
  22. addoq -10*4, $acr, $acr
  23. ;; perform dword checksumming on the 10 longwords
  24. addc $r0,$r12
  25. addc $r1,$r12
  26. addc $r2,$r12
  27. addc $r3,$r12
  28. addc $r4,$r12
  29. addc $r5,$r12
  30. addc $r6,$r12
  31. addc $r7,$r12
  32. addc $r8,$r12
  33. addc $r9,$r12
  34. ;; test $acr without trashing carry.
  35. move.d $acr, $acr
  36. bpl _mloop
  37. ;; r11 <= acr is not really needed in the mloop, just using the dslot
  38. ;; to prepare for what is needed after mloop.
  39. move.d $acr, $r11
  40. ;; fold the last carry into r13
  41. addc 0, $r12
  42. movem [$sp+],$r8 ; restore regs
  43. _word_loop:
  44. addq 10*4,$r11 ; compensate for last loop underflowing length
  45. moveq -1,$r9 ; put 0xffff in r9, faster than move.d 0xffff,r9
  46. lsrq 16,$r9
  47. move.d $r12,$r13
  48. lsrq 16,$r13 ; r13 = checksum >> 16
  49. and.d $r9,$r12 ; checksum = checksum & 0xffff
  50. _no_fold:
  51. subq 2,$r11
  52. blt _no_words
  53. add.d $r13,$r12 ; checksum += r13
  54. ;; checksum the rest of the words
  55. _wloop: subq 2,$r11
  56. bge _wloop
  57. addu.w [$r10+],$r12
  58. _no_words:
  59. addq 2,$r11
  60. ;; see if we have one odd byte more
  61. bne _do_byte
  62. nop
  63. ret
  64. move.d $r12,$r10
  65. _do_byte:
  66. ;; copy and checksum the last byte
  67. addu.b [$r10],$r12
  68. ret
  69. move.d $r12,$r10