csum-copy_64.S 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. /*
  2. * Copyright 2002, 2003 Andi Kleen, SuSE Labs.
  3. *
  4. * This file is subject to the terms and conditions of the GNU General Public
  5. * License. See the file COPYING in the main directory of this archive
  6. * for more details. No warranty for anything given at all.
  7. */
  8. #include <linux/linkage.h>
  9. #include <asm/dwarf2.h>
  10. #include <asm/errno.h>
  11. /*
  12. * Checksum copy with exception handling.
  13. * On exceptions src_err_ptr or dst_err_ptr is set to -EFAULT and the
  14. * destination is zeroed.
  15. *
  16. * Input
  17. * rdi source
  18. * rsi destination
  19. * edx len (32bit)
  20. * ecx sum (32bit)
  21. * r8 src_err_ptr (int)
  22. * r9 dst_err_ptr (int)
  23. *
  24. * Output
  25. * eax 64bit sum. undefined in case of exception.
  26. *
  27. * Wrappers need to take care of valid exception sum and zeroing.
  28. * They also should align source or destination to 8 bytes.
  29. */
  30. .macro source
  31. 10:
  32. .section __ex_table, "a"
  33. .align 8
  34. .quad 10b, .Lbad_source
  35. .previous
  36. .endm
  37. .macro dest
  38. 20:
  39. .section __ex_table, "a"
  40. .align 8
  41. .quad 20b, .Lbad_dest
  42. .previous
  43. .endm
  44. .macro ignore L=.Lignore
  45. 30:
  46. .section __ex_table, "a"
  47. .align 8
  48. .quad 30b, \L
  49. .previous
  50. .endm
  51. ENTRY(csum_partial_copy_generic)
  52. CFI_STARTPROC
  53. cmpl $3*64, %edx
  54. jle .Lignore
  55. .Lignore:
  56. subq $7*8, %rsp
  57. CFI_ADJUST_CFA_OFFSET 7*8
  58. movq %rbx, 2*8(%rsp)
  59. CFI_REL_OFFSET rbx, 2*8
  60. movq %r12, 3*8(%rsp)
  61. CFI_REL_OFFSET r12, 3*8
  62. movq %r14, 4*8(%rsp)
  63. CFI_REL_OFFSET r14, 4*8
  64. movq %r13, 5*8(%rsp)
  65. CFI_REL_OFFSET r13, 5*8
  66. movq %rbp, 6*8(%rsp)
  67. CFI_REL_OFFSET rbp, 6*8
  68. movq %r8, (%rsp)
  69. movq %r9, 1*8(%rsp)
  70. movl %ecx, %eax
  71. movl %edx, %ecx
  72. xorl %r9d, %r9d
  73. movq %rcx, %r12
  74. shrq $6, %r12
  75. jz .Lhandle_tail /* < 64 */
  76. clc
  77. /* main loop. clear in 64 byte blocks */
  78. /* r9: zero, r8: temp2, rbx: temp1, rax: sum, rcx: saved length */
  79. /* r11: temp3, rdx: temp4, r12 loopcnt */
  80. /* r10: temp5, rbp: temp6, r14 temp7, r13 temp8 */
  81. .p2align 4
  82. .Lloop:
  83. source
  84. movq (%rdi), %rbx
  85. source
  86. movq 8(%rdi), %r8
  87. source
  88. movq 16(%rdi), %r11
  89. source
  90. movq 24(%rdi), %rdx
  91. source
  92. movq 32(%rdi), %r10
  93. source
  94. movq 40(%rdi), %rbp
  95. source
  96. movq 48(%rdi), %r14
  97. source
  98. movq 56(%rdi), %r13
  99. ignore 2f
  100. prefetcht0 5*64(%rdi)
  101. 2:
  102. adcq %rbx, %rax
  103. adcq %r8, %rax
  104. adcq %r11, %rax
  105. adcq %rdx, %rax
  106. adcq %r10, %rax
  107. adcq %rbp, %rax
  108. adcq %r14, %rax
  109. adcq %r13, %rax
  110. decl %r12d
  111. dest
  112. movq %rbx, (%rsi)
  113. dest
  114. movq %r8, 8(%rsi)
  115. dest
  116. movq %r11, 16(%rsi)
  117. dest
  118. movq %rdx, 24(%rsi)
  119. dest
  120. movq %r10, 32(%rsi)
  121. dest
  122. movq %rbp, 40(%rsi)
  123. dest
  124. movq %r14, 48(%rsi)
  125. dest
  126. movq %r13, 56(%rsi)
  127. 3:
  128. leaq 64(%rdi), %rdi
  129. leaq 64(%rsi), %rsi
  130. jnz .Lloop
  131. adcq %r9, %rax
  132. /* do last up to 56 bytes */
  133. .Lhandle_tail:
  134. /* ecx: count */
  135. movl %ecx, %r10d
  136. andl $63, %ecx
  137. shrl $3, %ecx
  138. jz .Lfold
  139. clc
  140. .p2align 4
  141. .Lloop_8:
  142. source
  143. movq (%rdi), %rbx
  144. adcq %rbx, %rax
  145. decl %ecx
  146. dest
  147. movq %rbx, (%rsi)
  148. leaq 8(%rsi), %rsi /* preserve carry */
  149. leaq 8(%rdi), %rdi
  150. jnz .Lloop_8
  151. adcq %r9, %rax /* add in carry */
  152. .Lfold:
  153. /* reduce checksum to 32bits */
  154. movl %eax, %ebx
  155. shrq $32, %rax
  156. addl %ebx, %eax
  157. adcl %r9d, %eax
  158. /* do last up to 6 bytes */
  159. .Lhandle_7:
  160. movl %r10d, %ecx
  161. andl $7, %ecx
  162. shrl $1, %ecx
  163. jz .Lhandle_1
  164. movl $2, %edx
  165. xorl %ebx, %ebx
  166. clc
  167. .p2align 4
  168. .Lloop_1:
  169. source
  170. movw (%rdi), %bx
  171. adcl %ebx, %eax
  172. decl %ecx
  173. dest
  174. movw %bx, (%rsi)
  175. leaq 2(%rdi), %rdi
  176. leaq 2(%rsi), %rsi
  177. jnz .Lloop_1
  178. adcl %r9d, %eax /* add in carry */
  179. /* handle last odd byte */
  180. .Lhandle_1:
  181. testl $1, %r10d
  182. jz .Lende
  183. xorl %ebx, %ebx
  184. source
  185. movb (%rdi), %bl
  186. dest
  187. movb %bl, (%rsi)
  188. addl %ebx, %eax
  189. adcl %r9d, %eax /* carry */
  190. CFI_REMEMBER_STATE
  191. .Lende:
  192. movq 2*8(%rsp), %rbx
  193. CFI_RESTORE rbx
  194. movq 3*8(%rsp), %r12
  195. CFI_RESTORE r12
  196. movq 4*8(%rsp), %r14
  197. CFI_RESTORE r14
  198. movq 5*8(%rsp), %r13
  199. CFI_RESTORE r13
  200. movq 6*8(%rsp), %rbp
  201. CFI_RESTORE rbp
  202. addq $7*8, %rsp
  203. CFI_ADJUST_CFA_OFFSET -7*8
  204. ret
  205. CFI_RESTORE_STATE
  206. /* Exception handlers. Very simple, zeroing is done in the wrappers */
  207. .Lbad_source:
  208. movq (%rsp), %rax
  209. testq %rax, %rax
  210. jz .Lende
  211. movl $-EFAULT, (%rax)
  212. jmp .Lende
  213. .Lbad_dest:
  214. movq 8(%rsp), %rax
  215. testq %rax, %rax
  216. jz .Lende
  217. movl $-EFAULT, (%rax)
  218. jmp .Lende
  219. CFI_ENDPROC
  220. ENDPROC(csum_partial_copy_generic)