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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * BK Id: SCCS/s.checksum.S 1.8 08/20/01 22:09:34 paulus
  3.  */
  4. /*
  5.  * This file contains assembly-language implementations
  6.  * of IP-style 1's complement checksum routines.
  7.  *
  8.  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  9.  *
  10.  *  This program is free software; you can redistribute it and/or
  11.  *  modify it under the terms of the GNU General Public License
  12.  *  as published by the Free Software Foundation; either version
  13.  *  2 of the License, or (at your option) any later version.
  14.  *
  15.  * Severely hacked about by Paul Mackerras (paulus@cs.anu.edu.au).
  16.  */
  17. #include <linux/sys.h>
  18. #include <asm/processor.h>
  19. #include <asm/errno.h>
  20. #include "../kernel/ppc_asm.tmpl"
  21. .text
  22. /*
  23.  * ip_fast_csum(buf, len) -- Optimized for IP header
  24.  * len is in words and is always >= 5.
  25.  */
  26. _GLOBAL(ip_fast_csum)
  27. lwz r0,0(r3)
  28. lwzu r5,4(r3)
  29. addic. r4,r4,-2
  30. addc r0,r0,r5
  31. mtctr r4
  32. blelr-
  33. 1: lwzu r4,4(r3)
  34. adde r0,r0,r4
  35. bdnz 1b
  36. addze r0,r0 /* add in final carry */
  37. rlwinm r3,r0,16,0,31 /* fold two halves together */
  38. add r3,r0,r3
  39. not r3,r3
  40. srwi r3,r3,16
  41. blr
  42. /*
  43.  * Compute checksum of TCP or UDP pseudo-header:
  44.  *   csum_tcpudp_magic(saddr, daddr, len, proto, sum)
  45.  */
  46. _GLOBAL(csum_tcpudp_magic)
  47. rlwimi r5,r6,16,0,15 /* put proto in upper half of len */
  48. addc r0,r3,r4 /* add 4 32-bit words together */
  49. adde r0,r0,r5
  50. adde r0,r0,r7
  51. addze r0,r0 /* add in final carry */
  52. rlwinm r3,r0,16,0,31 /* fold two halves together */
  53. add r3,r0,r3
  54. not r3,r3
  55. srwi r3,r3,16
  56. blr
  57. /*
  58.  * computes the checksum of a memory block at buff, length len,
  59.  * and adds in "sum" (32-bit)
  60.  *
  61.  * csum_partial(buff, len, sum)
  62.  */
  63. _GLOBAL(csum_partial)
  64. addic r0,r5,0
  65. subi r3,r3,4
  66. srwi. r6,r4,2
  67. beq 3f /* if we're doing < 4 bytes */
  68. andi. r5,r3,2 /* Align buffer to longword boundary */
  69. beq+ 1f
  70. lhz r5,4(r3) /* do 2 bytes to get aligned */
  71. addi r3,r3,2
  72. subi r4,r4,2
  73. addc r0,r0,r5
  74. srwi. r6,r4,2 /* # words to do */
  75. beq 3f
  76. 1: mtctr r6
  77. 2: lwzu r5,4(r3) /* the bdnz has zero overhead, so it should */
  78. adde r0,r0,r5 /* be unnecessary to unroll this loop */
  79. bdnz 2b
  80. andi. r4,r4,3
  81. 3: cmpi 0,r4,2
  82. blt+ 4f
  83. lhz r5,4(r3)
  84. addi r3,r3,2
  85. subi r4,r4,2
  86. adde r0,r0,r5
  87. 4: cmpi 0,r4,1
  88. bne+ 5f
  89. lbz r5,4(r3)
  90. slwi r5,r5,8 /* Upper byte of word */
  91. adde r0,r0,r5
  92. 5: addze r3,r0 /* add in final carry */
  93. blr
  94. /*
  95.  * Computes the checksum of a memory block at src, length len,
  96.  * and adds in "sum" (32-bit), while copying the block to dst.
  97.  * If an access exception occurs on src or dst, it stores -EFAULT
  98.  * to *src_err or *dst_err respectively, and (for an error on
  99.  * src) zeroes the rest of dst.
  100.  *
  101.  * csum_partial_copy_generic(src, dst, len, sum, src_err, dst_err)
  102.  */
  103. _GLOBAL(csum_partial_copy_generic)
  104. addic r0,r6,0
  105. subi r3,r3,4
  106. subi r4,r4,4
  107. srwi. r6,r5,2
  108. beq 3f /* if we're doing < 4 bytes */
  109. andi. r9,r4,2 /* Align dst to longword boundary */
  110. beq+ 1f
  111. 81: lhz r6,4(r3) /* do 2 bytes to get aligned */
  112. addi r3,r3,2
  113. subi r5,r5,2
  114. 91: sth r6,4(r4)
  115. addi r4,r4,2
  116. addc r0,r0,r6
  117. srwi. r6,r5,2 /* # words to do */
  118. beq 3f
  119. 1: srwi. r6,r5,4 /* # groups of 4 words to do */
  120. beq 10f
  121. mtctr r6
  122. 71: lwz r6,4(r3)
  123. 72: lwz r9,8(r3)
  124. 73: lwz r10,12(r3)
  125. 74: lwzu r11,16(r3)
  126. adde r0,r0,r6
  127. 75: stw r6,4(r4)
  128. adde r0,r0,r9
  129. 76: stw r9,8(r4)
  130. adde r0,r0,r10
  131. 77: stw r10,12(r4)
  132. adde r0,r0,r11
  133. 78: stwu r11,16(r4)
  134. bdnz 71b
  135. 10: rlwinm. r6,r5,30,30,31 /* # words left to do */
  136. beq 13f
  137. mtctr r6
  138. 82: lwzu r9,4(r3)
  139. 92: stwu r9,4(r4)
  140. adde r0,r0,r9
  141. bdnz 82b
  142. 13: andi. r5,r5,3
  143. 3: cmpi 0,r5,2
  144. blt+ 4f
  145. 83: lhz r6,4(r3)
  146. addi r3,r3,2
  147. subi r5,r5,2
  148. 93: sth r6,4(r4)
  149. addi r4,r4,2
  150. adde r0,r0,r6
  151. 4: cmpi 0,r5,1
  152. bne+ 5f
  153. 84: lbz r6,4(r3)
  154. 94: stb r6,4(r4)
  155. slwi r6,r6,8 /* Upper byte of word */
  156. adde r0,r0,r6
  157. 5: addze r3,r0 /* add in final carry */
  158. blr
  159. /* These shouldn't go in the fixup section, since that would
  160.    cause the ex_table addresses to get out of order. */
  161. src_error_4:
  162. mfctr r6 /* update # bytes remaining from ctr */
  163. rlwimi r5,r6,4,0,27
  164. b 79f
  165. src_error_1:
  166. li r6,0
  167. subi r5,r5,2
  168. 95: sth r6,4(r4)
  169. addi r4,r4,2
  170. 79: srwi. r6,r5,2
  171. beq 3f
  172. mtctr r6
  173. src_error_2:
  174. li r6,0
  175. 96: stwu r6,4(r4)
  176. bdnz 96b
  177. 3: andi. r5,r5,3
  178. beq src_error
  179. src_error_3:
  180. li r6,0
  181. mtctr r5
  182. addi r4,r4,3
  183. 97: stbu r6,1(r4)
  184. bdnz 97b
  185. src_error:
  186. cmpi 0,r7,0
  187. beq 1f
  188. li r6,-EFAULT
  189. stw r6,0(r7)
  190. 1: addze r3,r0
  191. blr
  192. dst_error:
  193. cmpi 0,r8,0
  194. beq 1f
  195. li r6,-EFAULT
  196. stw r6,0(r8)
  197. 1: addze r3,r0
  198. blr
  199. .section __ex_table,"a"
  200. .long 81b,src_error_1
  201. .long 91b,dst_error
  202. .long 71b,src_error_4
  203. .long 72b,src_error_4
  204. .long 73b,src_error_4
  205. .long 74b,src_error_4
  206. .long 75b,dst_error
  207. .long 76b,dst_error
  208. .long 77b,dst_error
  209. .long 78b,dst_error
  210. .long 82b,src_error_2
  211. .long 92b,dst_error
  212. .long 83b,src_error_3
  213. .long 93b,dst_error
  214. .long 84b,src_error_3
  215. .long 94b,dst_error
  216. .long 95b,dst_error
  217. .long 96b,dst_error
  218. .long 97b,dst_error