checksumcopy.S 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. /*
  2. * A fast checksum+copy routine using movem
  3. * Copyright (c) 1998-2007 Axis Communications AB
  4. *
  5. * Authors: Bjorn Wesen
  6. *
  7. * csum_partial_copy_nocheck(const char *src, char *dst,
  8. * int len, unsigned int sum)
  9. */
  10. .globl csum_partial_copy_nocheck
  11. csum_partial_copy_nocheck:
  12. ;; r10 - src
  13. ;; r11 - dst
  14. ;; r12 - length
  15. ;; r13 - checksum
  16. ;; Optimized for large packets
  17. subq 10*4, $r12
  18. blt _word_loop
  19. move.d $r12, $acr
  20. subq 9*4,$sp
  21. clearf c
  22. movem $r8,[$sp]
  23. ;; do a movem copy and checksum
  24. 1: ;; A failing userspace access (the read) will have this as PC.
  25. _mloop: movem [$r10+],$r9 ; read 10 longwords
  26. addoq -10*4, $acr, $acr ; loop counter in latency cycle
  27. movem $r9,[$r11+] ; write 10 longwords
  28. ;; perform dword checksumming on the 10 longwords
  29. addc $r0,$r13
  30. addc $r1,$r13
  31. addc $r2,$r13
  32. addc $r3,$r13
  33. addc $r4,$r13
  34. addc $r5,$r13
  35. addc $r6,$r13
  36. addc $r7,$r13
  37. addc $r8,$r13
  38. addc $r9,$r13
  39. ;; test $acr, without trashing carry.
  40. move.d $acr, $acr
  41. bpl _mloop
  42. ;; r12 <= acr is needed after mloop and in the exception handlers.
  43. move.d $acr, $r12
  44. ;; fold the last carry into r13
  45. addc 0, $r13
  46. movem [$sp+],$r8 ; restore regs
  47. _word_loop:
  48. addq 10*4,$r12 ; compensate for last loop underflowing length
  49. ;; fold 32-bit checksum into a 16-bit checksum, to avoid carries below
  50. ;; r9 can be used as temporary.
  51. move.d $r13,$r9
  52. lsrq 16,$r9 ; r0 = checksum >> 16
  53. and.d 0xffff,$r13 ; checksum = checksum & 0xffff
  54. subq 2, $r12
  55. blt _no_words
  56. add.d $r9,$r13 ; checksum += r0
  57. ;; copy and checksum the rest of the words
  58. 2: ;; A failing userspace access for the read below will have this as PC.
  59. _wloop: move.w [$r10+],$r9
  60. addu.w $r9,$r13
  61. subq 2,$r12
  62. bge _wloop
  63. move.w $r9,[$r11+]
  64. _no_words:
  65. addq 2,$r12
  66. bne _do_byte
  67. nop
  68. ret
  69. move.d $r13,$r10
  70. _do_byte:
  71. ;; copy and checksum the last byte
  72. 3: ;; A failing userspace access for the read below will have this as PC.
  73. move.b [$r10],$r9
  74. addu.b $r9,$r13
  75. move.b $r9,[$r11]
  76. ret
  77. move.d $r13,$r10