checksumcopy.S 2.1 KB

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