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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  *  linux/arch/arm/lib/csumpartialcopygeneric.S
  3.  *
  4.  *  Copyright (C) 1995-2001 Russell King
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License version 2 as
  8.  * published by the Free Software Foundation.
  9.  */
  10. /*
  11.  * unsigned int
  12.  * csum_partial_copy_xxx(const char *src, char *dst, int len, int sum, )
  13.  *  r0 = src, r1 = dst, r2 = len, r3 = sum
  14.  *  Returns : r0 = checksum
  15.  *
  16.  * Note that 'tst' and 'teq' preserve the carry flag.
  17.  */
  18. src .req r0
  19. dst .req r1
  20. len .req r2
  21. sum .req r3
  22. .zero: mov r0, sum
  23. load_regs ea
  24. /*
  25.  * Align an unaligned destination pointer.  We know that
  26.  * we have >= 8 bytes here, so we don't need to check
  27.  * the length.  Note that the source pointer hasn't been
  28.  * aligned yet.
  29.  */
  30. .dst_unaligned: tst dst, #1
  31. beq .dst_16bit
  32. load1b ip
  33. sub len, len, #1
  34. adcs sum, sum, ip, lsl #8 @ update checksum
  35. strb ip, [dst], #1
  36. tst dst, #2
  37. moveq pc, lr @ dst is now 32bit aligned
  38. .dst_16bit: load2b r8, ip
  39. sub len, len, #2
  40. adcs sum, sum, r8
  41. strb r8, [dst], #1
  42. adcs sum, sum, ip, lsl #8
  43. strb ip, [dst], #1
  44. mov pc, lr @ dst is now 32bit aligned
  45. /*
  46.  * Handle 0 to 7 bytes, with any alignment of source and
  47.  * destination pointers.  Note that when we get here, C = 0
  48.  */
  49. .less8: teq len, #0 @ check for zero count
  50. beq .zero
  51. /* we must have at least one byte. */
  52. tst dst, #1 @ dst 16-bit aligned
  53. beq .less8_aligned
  54. /* Align dst */
  55. load1b ip
  56. sub len, len, #1
  57. adcs sum, sum, ip, lsl #8 @ update checksum
  58. strb ip, [dst], #1
  59. tst len, #6
  60. beq .less8_byteonly
  61. 1: load2b r8, ip
  62. sub len, len, #2
  63. adcs sum, sum, r8
  64. strb r8, [dst], #1
  65. adcs sum, sum, ip, lsl #8
  66. strb ip, [dst], #1
  67. .less8_aligned: tst len, #6
  68. bne 1b
  69. .less8_byteonly:
  70. tst len, #1
  71. beq .done
  72. load1b r8
  73. adcs sum, sum, r8 @ update checksum
  74. strb r8, [dst], #1
  75. b .done
  76. FN_ENTRY
  77. mov ip, sp
  78. save_regs
  79. sub fp, ip, #4
  80. cmp len, #8 @ Ensure that we have at least
  81. blo .less8 @ 8 bytes to copy.
  82. adds sum, sum, #0 @ C = 0
  83. tst dst, #3 @ Test destination alignment
  84. blne .dst_unaligned @ align destination, return here
  85. /*
  86.  * Ok, the dst pointer is now 32bit aligned, and we know
  87.  * that we must have more than 4 bytes to copy.  Note
  88.  * that C contains the carry from the dst alignment above.
  89.  */
  90. tst src, #3 @ Test source alignment
  91. bne .src_not_aligned
  92. /* Routine for src & dst aligned */
  93. bics ip, len, #15
  94. beq 2f
  95. 1: load4l r4, r5, r6, r7
  96. stmia dst!, {r4, r5, r6, r7}
  97. adcs sum, sum, r4
  98. adcs sum, sum, r5
  99. adcs sum, sum, r6
  100. adcs sum, sum, r7
  101. sub ip, ip, #16
  102. teq ip, #0
  103. bne 1b
  104. 2: ands ip, len, #12
  105. beq 4f
  106. tst ip, #8
  107. beq 3f
  108. load2l r4, r5
  109. stmia dst!, {r4, r5}
  110. adcs sum, sum, r4
  111. adcs sum, sum, r5
  112. tst ip, #4
  113. beq 4f
  114. 3: load1l r4
  115. str r4, [dst], #4
  116. adcs sum, sum, r4
  117. 4: ands len, len, #3
  118. beq .done
  119. load1l r4
  120. tst len, #2
  121. beq .exit
  122. adcs sum, sum, r4, lsl #16
  123. strb r4, [dst], #1
  124. mov r4, r4, lsr #8
  125. strb r4, [dst], #1
  126. mov r4, r4, lsr #8
  127. .exit: tst len, #1
  128. strneb r4, [dst], #1
  129. andne r4, r4, #255
  130. adcnes sum, sum, r4
  131. /*
  132.  * If the dst pointer was not 16-bit aligned, we
  133.  * need to rotate the checksum here to get around
  134.  * the inefficient byte manipulations in the
  135.  * architecture independent code.
  136.  */
  137. .done: adc r0, sum, #0
  138. ldr sum, [sp, #0] @ dst
  139. tst sum, #1
  140. movne sum, r0, lsl #8
  141. orrne r0, sum, r0, lsr #24
  142. load_regs ea
  143. .src_not_aligned:
  144. adc sum, sum, #0 @ include C from dst alignment
  145. and ip, src, #3
  146. bic src, src, #3
  147. load1l r4
  148. cmp ip, #2
  149. beq .src2_aligned
  150. bhi .src3_aligned
  151. mov r4, r4, lsr #8 @ C = 0
  152. bics ip, len, #15
  153. beq 2f
  154. 1: load4l r5, r6, r7, r8
  155. orr r4, r4, r5, lsl #24
  156. mov r5, r5, lsr #8
  157. orr r5, r5, r6, lsl #24
  158. mov r6, r6, lsr #8
  159. orr r6, r6, r7, lsl #24
  160. mov r7, r7, lsr #8
  161. orr r7, r7, r8, lsl #24
  162. stmia dst!, {r4, r5, r6, r7}
  163. adcs sum, sum, r4
  164. adcs sum, sum, r5
  165. adcs sum, sum, r6
  166. adcs sum, sum, r7
  167. mov r4, r8, lsr #8
  168. sub ip, ip, #16
  169. teq ip, #0
  170. bne 1b
  171. 2: ands ip, len, #12
  172. beq 4f
  173. tst ip, #8
  174. beq 3f
  175. load2l r5, r6
  176. orr r4, r4, r5, lsl #24
  177. mov r5, r5, lsr #8
  178. orr r5, r5, r6, lsl #24
  179. stmia dst!, {r4, r5}
  180. adcs sum, sum, r4
  181. adcs sum, sum, r5
  182. mov r4, r6, lsr #8
  183. tst ip, #4
  184. beq 4f
  185. 3: load1l r5
  186. orr r4, r4, r5, lsl #24
  187. str r4, [dst], #4
  188. adcs sum, sum, r4
  189. mov r4, r5, lsr #8
  190. 4: ands len, len, #3
  191. beq .done
  192. tst len, #2
  193. beq .exit
  194. adcs sum, sum, r4, lsl #16
  195. strb r4, [dst], #1
  196. mov r4, r4, lsr #8
  197. strb r4, [dst], #1
  198. mov r4, r4, lsr #8
  199. b .exit
  200. .src2_aligned: mov r4, r4, lsr #16
  201. adds sum, sum, #0
  202. bics ip, len, #15
  203. beq 2f
  204. 1: load4l r5, r6, r7, r8
  205. orr r4, r4, r5, lsl #16
  206. mov r5, r5, lsr #16
  207. orr r5, r5, r6, lsl #16
  208. mov r6, r6, lsr #16
  209. orr r6, r6, r7, lsl #16
  210. mov r7, r7, lsr #16
  211. orr r7, r7, r8, lsl #16
  212. stmia dst!, {r4, r5, r6, r7}
  213. adcs sum, sum, r4
  214. adcs sum, sum, r5
  215. adcs sum, sum, r6
  216. adcs sum, sum, r7
  217. mov r4, r8, lsr #16
  218. sub ip, ip, #16
  219. teq ip, #0
  220. bne 1b
  221. 2: ands ip, len, #12
  222. beq 4f
  223. tst ip, #8
  224. beq 3f
  225. load2l r5, r6
  226. orr r4, r4, r5, lsl #16
  227. mov r5, r5, lsr #16
  228. orr r5, r5, r6, lsl #16
  229. stmia dst!, {r4, r5}
  230. adcs sum, sum, r4
  231. adcs sum, sum, r5
  232. mov r4, r6, lsr #16
  233. tst ip, #4
  234. beq 4f
  235. 3: load1l r5
  236. orr r4, r4, r5, lsl #16
  237. str r4, [dst], #4
  238. adcs sum, sum, r4
  239. mov r4, r5, lsr #16
  240. 4: ands len, len, #3
  241. beq .done
  242. tst len, #2
  243. beq .exit
  244. adcs sum, sum, r4, lsl #16
  245. strb r4, [dst], #1
  246. mov r4, r4, lsr #8
  247. strb r4, [dst], #1
  248. tst len, #1
  249. beq .done
  250. load1b r4
  251. b .exit
  252. .src3_aligned: mov r4, r4, lsr #24
  253. adds sum, sum, #0
  254. bics ip, len, #15
  255. beq 2f
  256. 1: load4l r5, r6, r7, r8
  257. orr r4, r4, r5, lsl #8
  258. mov r5, r5, lsr #24
  259. orr r5, r5, r6, lsl #8
  260. mov r6, r6, lsr #24
  261. orr r6, r6, r7, lsl #8
  262. mov r7, r7, lsr #24
  263. orr r7, r7, r8, lsl #8
  264. stmia dst!, {r4, r5, r6, r7}
  265. adcs sum, sum, r4
  266. adcs sum, sum, r5
  267. adcs sum, sum, r6
  268. adcs sum, sum, r7
  269. mov r4, r8, lsr #24
  270. sub ip, ip, #16
  271. teq ip, #0
  272. bne 1b
  273. 2: ands ip, len, #12
  274. beq 4f
  275. tst ip, #8
  276. beq 3f
  277. load2l r5, r6
  278. orr r4, r4, r5, lsl #8
  279. mov r5, r5, lsr #24
  280. orr r5, r5, r6, lsl #8
  281. stmia dst!, {r4, r5}
  282. adcs sum, sum, r4
  283. adcs sum, sum, r5
  284. mov r4, r6, lsr #24
  285. tst ip, #4
  286. beq 4f
  287. 3: load1l r5
  288. orr r4, r4, r5, lsl #8
  289. str r4, [dst], #4
  290. adcs sum, sum, r4
  291. mov r4, r5, lsr #24
  292. 4: ands len, len, #3
  293. beq .done
  294. tst len, #2
  295. beq .exit
  296. adcs sum, sum, r4, lsl #16
  297. strb r4, [dst], #1
  298. load1l r4
  299. strb r4, [dst], #1
  300. adcs sum, sum, r4, lsl #24
  301. mov r4, r4, lsr #8
  302. b .exit