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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * This file contains assembly-language implementations
  3.  * of IP-style 1's complement checksum routines.
  4.  *
  5.  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  6.  *
  7.  *  This program is free software; you can redistribute it and/or
  8.  *  modify it under the terms of the GNU General Public License
  9.  *  as published by the Free Software Foundation; either version
  10.  *  2 of the License, or (at your option) any later version.
  11.  *
  12.  * Severely hacked about by Paul Mackerras (paulus@cs.anu.edu.au).
  13.  */
  14. #include <linux/sys.h>
  15. #include <asm/processor.h>
  16. #include <asm/errno.h>
  17. #include <asm/ppc_asm.tmpl>
  18. .text
  19. /*
  20.  * ip_fast_csum(r3=buf, r4=len) -- Optimized for IP header
  21.  * len is in words and is always >= 5.
  22.  *
  23.  * In practice len == 5, but this is not guaranteed.  So this code does not
  24.  * attempt to use doubleword instructions.
  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.         rldicl  r4,r0,32,0      /* fold two 32-bit halves together */
  38.         add     r0,r0,r4
  39.         srdi    r0,r0,32
  40. rlwinm r3,r0,16,0,31 /* fold two halves together */
  41. add r3,r0,r3
  42. not r3,r3
  43. srwi r3,r3,16
  44. blr
  45. /*
  46.  * Compute checksum of TCP or UDP pseudo-header:
  47.  *   csum_tcpudp_magic(r3=saddr, r4=daddr, r5=len, r6=proto, r7=sum)
  48.  * No real gain trying to do this specially for 64 bit, but
  49.  * the 32 bit addition may spill into the upper bits of
  50.  * the doubleword so we still must fold it down from 64.
  51.  */
  52. _GLOBAL(csum_tcpudp_magic)
  53. rlwimi r5,r6,16,0,15 /* put proto in upper half of len */
  54. addc r0,r3,r4 /* add 4 32-bit words together */
  55. adde r0,r0,r5
  56. adde r0,r0,r7
  57.         rldicl  r4,r0,32,0      /* fold 64 bit value */
  58.         add     r0,r4,r0
  59.         srdi    r0,r0,32
  60. rlwinm r3,r0,16,0,31 /* fold two halves together */
  61. add r3,r0,r3
  62. not r3,r3
  63. srwi r3,r3,16
  64. blr
  65. /*
  66.  * Computes the checksum of a memory block at buff, length len,
  67.  * and adds in "sum" (32-bit).
  68.  *
  69.  * This code assumes at least halfword alignment, though the length
  70.  * can be any number of bytes.  The sum is accumulated in r5.
  71.  *
  72.  * csum_partial(r3=buff, r4=len, r5=sum)
  73.  */
  74. _GLOBAL(csum_partial)
  75.         subi r3,r3,8 /* we'll offset by 8 for the loads */
  76.         srdi. r6,r4,3         /* divide by 8 for doubleword count */
  77.         addic   r5,r5,0         /* clear carry */
  78.         beq 3f              /* if we're doing < 8 bytes */
  79.         andi. r0,r3,2         /* aligned on a word boundary already? */
  80.         beq+ 1f
  81.         lhz     r6,8(r3)        /* do 2 bytes to get aligned */
  82.         addi    r3,r3,2
  83.         subi    r4,r4,2
  84.         addc    r5,r5,r6
  85.         srdi.   r6,r4,3         /* recompute number of doublewords */
  86.         beq     3f              /* any left? */
  87. 1:      mtctr   r6
  88. 2:      ldu     r6,8(r3)        /* main sum loop */
  89.         adde    r5,r5,r6
  90.         bdnz    2b
  91.         andi. r4,r4,7         /* compute bytes left to sum after doublewords */
  92. 3: cmpi 0,r4,4 /* is at least a full word left? */
  93. blt 4f
  94. lwz r6,8(r3) /* sum this word */
  95. addi r3,r3,4
  96. subi r4,r4,4
  97. adde r5,r5,r6
  98. 4:      cmpi    0,r4,2 /* is at least a halfword left? */
  99.         blt+ 5f
  100.         lhz     r6,8(r3)        /* sum this halfword */
  101.         addi    r3,r3,2
  102.         subi    r4,r4,2
  103.         adde    r5,r5,r6
  104. 5:      cmpi    0,r4,1 /* is at least a byte left? */
  105.         bne+    6f
  106.         lbz     r6,8(r3)        /* sum this byte */
  107.         slwi    r6,r6,8         /* this byte is assumed to be the upper byte of a halfword */
  108.         adde    r5,r5,r6
  109. 6:      addze r5,r5 /* add in final carry */
  110. rldicl  r4,r5,32,0      /* fold two 32-bit halves together */
  111.         add     r3,r4,r5
  112.         srdi    r3,r3,32
  113.         blr
  114. /*
  115.  * Computes the checksum of a memory block at src, length len,
  116.  * and adds in "sum" (32-bit), while copying the block to dst.
  117.  * If an access exception occurs on src or dst, it stores -EFAULT
  118.  * to *src_err or *dst_err respectively, and (for an error on
  119.  * src) zeroes the rest of dst.
  120.  *
  121.  * This code needs to be reworked to take advantage of 64 bit sum+copy.
  122.  * However, due to tokenring halfword alignment problems this will be very
  123.  * tricky.  For now we'll leave it until we instrument it somehow.
  124.  *
  125.  * csum_partial_copy_generic(r3=src, r4=dst, r5=len, r6=sum, r7=src_err, r8=dst_err)
  126.  */
  127. _GLOBAL(csum_partial_copy_generic)
  128. addic r0,r6,0
  129. subi r3,r3,4
  130. subi r4,r4,4
  131. srwi. r6,r5,2
  132. beq 3f /* if we're doing < 4 bytes */
  133. andi. r9,r4,2 /* Align dst to longword boundary */
  134. beq+ 1f
  135. 81: lhz r6,4(r3) /* do 2 bytes to get aligned */
  136. addi r3,r3,2
  137. subi r5,r5,2
  138. 91: sth r6,4(r4)
  139. addi r4,r4,2
  140. addc r0,r0,r6
  141. srwi. r6,r5,2 /* # words to do */
  142. beq 3f
  143. 1: mtctr r6
  144. 82: lwzu r6,4(r3) /* the bdnz has zero overhead, so it should */
  145. 92: stwu r6,4(r4) /* be unnecessary to unroll this loop */
  146. adde r0,r0,r6
  147. bdnz 82b
  148. andi. r5,r5,3
  149. 3: cmpi 0,r5,2
  150. blt+ 4f
  151. 83: lhz r6,4(r3)
  152. addi r3,r3,2
  153. subi r5,r5,2
  154. 93: sth r6,4(r4)
  155. addi r4,r4,2
  156. adde r0,r0,r6
  157. 4: cmpi 0,r5,1
  158. bne+ 5f
  159. 84: lbz r6,4(r3)
  160. 94: stb r6,4(r4)
  161. slwi r6,r6,8 /* Upper byte of word */
  162. adde r0,r0,r6
  163. 5: addze r3,r0 /* add in final carry (unlikely with 64-bit regs) */
  164.         rldicl  r4,r3,32,0      /* fold 64 bit value */
  165.         add     r3,r4,r3
  166.         srdi    r3,r3,32
  167. blr
  168. /* These shouldn't go in the fixup section, since that would
  169.    cause the ex_table addresses to get out of order. */
  170. .globl src_error_1
  171. src_error_1:
  172. li r6,0
  173. subi r5,r5,2
  174. 95: sth r6,4(r4)
  175. addi r4,r4,2
  176. srwi. r6,r5,2
  177. beq 3f
  178. mtctr r6
  179. .globl src_error_2
  180. src_error_2:
  181. li r6,0
  182. 96: stwu r6,4(r4)
  183. bdnz 96b
  184. 3: andi. r5,r5,3
  185. beq src_error
  186. .globl src_error_3
  187. src_error_3:
  188. li r6,0
  189. mtctr r5
  190. addi r4,r4,3
  191. 97: stbu r6,1(r4)
  192. bdnz 97b
  193. .globl src_error
  194. src_error:
  195. cmpi 0,r7,0
  196. beq 1f
  197. li r6,-EFAULT
  198. stw r6,0(r7)
  199. 1: addze r3,r0
  200. blr
  201. .globl dst_error
  202. dst_error:
  203. cmpi 0,r8,0
  204. beq 1f
  205. li r6,-EFAULT
  206. stw r6,0(r8)
  207. 1: addze r3,r0
  208. blr
  209. .section __ex_table,"a"
  210. .align  3
  211. .llong 81b,src_error_1
  212. .llong 91b,dst_error
  213. .llong 82b,src_error_2
  214. .llong 92b,dst_error
  215. .llong 83b,src_error_3
  216. .llong 93b,dst_error
  217. .llong 84b,src_error_3
  218. .llong 94b,dst_error
  219. .llong 95b,dst_error
  220. .llong 96b,dst_error
  221. .llong 97b,dst_error