csum_partial.S
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:4k
源码类别:

嵌入式Linux

开发平台:

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