csum_partial.S
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:4k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * This file is subject to the terms and conditions of the GNU General Public
  3.  * License.  See the file "COPYING" in the main directory of this archive
  4.  * for more details.
  5.  *
  6.  * Copyright (C) 1998 Ralf Baechle
  7.  */
  8. #include <asm/asm.h>
  9. #include <asm/regdef.h>
  10. #define ADDC(sum,reg)
  11. addu sum, reg;
  12. sltu v1, sum, reg;
  13. addu sum, v1
  14. #define CSUM_BIGCHUNK(src, offset, sum, t0, t1, t2, t3) 
  15. lw t0, (offset + 0x00)(src); 
  16. lw t1, (offset + 0x04)(src); 
  17. lw t2, (offset + 0x08)(src); 
  18. lw t3, (offset + 0x0c)(src); 
  19. ADDC(sum, t0);                    
  20. ADDC(sum, t1);                    
  21. ADDC(sum, t2);                    
  22. ADDC(sum, t3);                    
  23. lw t0, (offset + 0x10)(src); 
  24. lw t1, (offset + 0x14)(src); 
  25. lw t2, (offset + 0x18)(src); 
  26. lw t3, (offset + 0x1c)(src); 
  27. ADDC(sum, t0);                    
  28. ADDC(sum, t1);                    
  29. ADDC(sum, t2);                    
  30. ADDC(sum, t3);                    
  31. /*
  32.  * a0: source address
  33.  * a1: length of the area to checksum
  34.  * a2: partial checksum
  35.  */
  36. #define src a0
  37. #define dest a1
  38. #define sum v0
  39. .text
  40. .set noreorder
  41. /* unknown src alignment and < 8 bytes to go  */
  42. small_csumcpy:
  43. move a1, t2
  44. andi t0, a1, 4
  45. beqz t0, 1f
  46.  andi t0, a1, 2
  47. /* Still a full word to go  */
  48. ulw t1, (src)
  49. addiu src, 4
  50. ADDC(sum, t1)
  51. 1: move t1, zero
  52. beqz t0, 1f
  53.  andi t0, a1, 1
  54. /* Still a halfword to go  */
  55. ulhu t1, (src)
  56. addiu src, 2
  57. 1: beqz t0, 1f
  58.  sll t1, t1, 16
  59. lbu t2, (src)
  60.  nop
  61. #ifdef __MIPSEB__
  62. sll t2, t2, 8
  63. #endif
  64. or t1, t2
  65. 1: ADDC(sum, t1)
  66. /* fold checksum */
  67. sll v1, sum, 16
  68. addu sum, v1
  69. sltu v1, sum, v1
  70. srl sum, sum, 16
  71. addu sum, v1
  72. /* odd buffer alignment? */
  73. beqz t7, 1f
  74.  nop
  75. sll v1, sum, 8
  76. srl sum, sum, 8
  77. or sum, v1
  78. andi sum, 0xffff
  79. 1:
  80. .set reorder
  81. /* Add the passed partial csum.  */
  82. ADDC(sum, a2)
  83. jr ra
  84. .set noreorder
  85. /* ------------------------------------------------------------------------- */
  86. .align 5
  87. LEAF(csum_partial)
  88. move sum, zero
  89. move t7, zero
  90. sltiu t8, a1, 0x8
  91. bnez t8, small_csumcpy /* < 8 bytes to copy */
  92.  move t2, a1
  93. beqz a1, out
  94.  andi t7, src, 0x1 /* odd buffer? */
  95. hword_align:
  96. beqz t7, word_align
  97.  andi t8, src, 0x2
  98. lbu t0, (src)
  99. subu a1, a1, 0x1
  100. #ifdef __MIPSEL__
  101. sll t0, t0, 8
  102. #endif
  103. ADDC(sum, t0)
  104. addu src, src, 0x1
  105. andi t8, src, 0x2
  106. word_align:
  107. beqz t8, dword_align
  108.  sltiu t8, a1, 56
  109. lhu t0, (src)
  110. subu a1, a1, 0x2
  111. ADDC(sum, t0)
  112. sltiu t8, a1, 56
  113. addu src, src, 0x2
  114. dword_align:
  115. bnez t8, do_end_words
  116.  move t8, a1
  117. andi t8, src, 0x4
  118. beqz t8, qword_align
  119.  andi t8, src, 0x8
  120. lw t0, 0x00(src)
  121. subu a1, a1, 0x4
  122. ADDC(sum, t0)
  123. addu src, src, 0x4
  124. andi t8, src, 0x8
  125. qword_align:
  126. beqz t8, oword_align
  127.  andi t8, src, 0x10
  128. lw t0, 0x00(src)
  129. lw t1, 0x04(src)
  130. subu a1, a1, 0x8
  131. ADDC(sum, t0)
  132. ADDC(sum, t1)
  133. addu src, src, 0x8
  134. andi t8, src, 0x10
  135. oword_align:
  136. beqz t8, begin_movement
  137.  srl t8, a1, 0x7
  138. lw t3, 0x08(src)
  139. lw t4, 0x0c(src)
  140. lw t0, 0x00(src)
  141. lw t1, 0x04(src)
  142. ADDC(sum, t3)
  143. ADDC(sum, t4)
  144. ADDC(sum, t0)
  145. ADDC(sum, t1)
  146. subu a1, a1, 0x10
  147. addu src, src, 0x10
  148. srl t8, a1, 0x7
  149. begin_movement:
  150. beqz t8, 1f
  151.  andi t2, a1, 0x40
  152. move_128bytes:
  153. CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
  154. CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
  155. CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4)
  156. CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4)
  157. subu t8, t8, 0x01
  158. bnez t8, move_128bytes
  159.  addu src, src, 0x80
  160. 1:
  161. beqz t2, 1f
  162.  andi t2, a1, 0x20
  163. move_64bytes:
  164. CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
  165. CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
  166. addu src, src, 0x40
  167. 1:
  168. beqz t2, do_end_words
  169.  andi t8, a1, 0x1c
  170. move_32bytes:
  171. CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
  172. andi t8, a1, 0x1c
  173. addu src, src, 0x20
  174. do_end_words:
  175. beqz t8, maybe_end_cruft
  176.  srl t8, t8, 0x2
  177. end_words:
  178. lw t0, (src)
  179. subu t8, t8, 0x1
  180. ADDC(sum, t0)
  181. bnez t8, end_words
  182.  addu src, src, 0x4
  183. maybe_end_cruft:
  184. andi t2, a1, 0x3
  185. small_memcpy:
  186.  j small_csumcpy; move a1, t2
  187. beqz t2, out
  188.  move a1, t2
  189. end_bytes:
  190. lb t0, (src)
  191. subu a1, a1, 0x1
  192. bnez a2, end_bytes
  193.  addu src, src, 0x1
  194. out:
  195. jr ra
  196.  move v0, sum
  197. END(csum_partial)