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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* checksum.S: Sparc V9 optimized checksum code.
  2.  *
  3.  *  Copyright(C) 1995 Linus Torvalds
  4.  *  Copyright(C) 1995 Miguel de Icaza
  5.  *  Copyright(C) 1996, 2000 David S. Miller
  6.  *  Copyright(C) 1997 Jakub Jelinek
  7.  *
  8.  * derived from:
  9.  * Linux/Alpha checksum c-code
  10.  *      Linux/ix86 inline checksum assembly
  11.  *      RFC1071 Computing the Internet Checksum (esp. Jacobsons m68k code)
  12.  * David Mosberger-Tang for optimized reference c-code
  13.  * BSD4.4 portable checksum routine
  14.  */
  15. #include <asm/errno.h>
  16. #include <asm/head.h>
  17. #include <asm/ptrace.h>
  18. #include <asm/asi.h>
  19. #include <asm/page.h>
  20. #include <asm/asm_offsets.h>
  21. /* The problem with the "add with carry" instructions on Ultra
  22.  * are two fold.  Firstly, they cannot pair with jack shit,
  23.  * and also they only add in the 32-bit carry condition bit
  24.  * into the accumulated sum.  The following is much better.
  25.  * For larger chunks we use VIS code, which is faster ;)
  26.  */
  27. #define src o0
  28. #define dst o1
  29. #define len o2
  30. #define sum o3
  31. .text
  32. /* I think I have an erection...  Once _AGAIN_ the SunSoft
  33.  * engineers are caught asleep at the keyboard, tsk tsk...
  34.  */
  35. #define CSUMCOPY_LASTCHUNK(off, t0, t1)
  36. ldxa [%src - off - 0x08] %asi, t0;
  37. ldxa [%src - off - 0x00] %asi, t1;
  38. nop; nop;
  39. addcc t0, %sum, %sum;
  40. stw t0, [%dst - off - 0x04];
  41. srlx t0, 32, t0;
  42. bcc,pt %xcc, 51f;
  43.  stw t0, [%dst - off - 0x08];
  44. add %sum, 1, %sum;
  45. 51: addcc t1, %sum, %sum;
  46. stw t1, [%dst - off + 0x04];
  47. srlx t1, 32, t1;
  48. bcc,pt %xcc, 52f;
  49.  stw t1, [%dst - off - 0x00];
  50. add %sum, 1, %sum;
  51. 52:
  52. cpc_start:
  53. cc_end_cruft:
  54. andcc %g7, 8, %g0 ! IEU1 Group
  55. be,pn %icc, 1f ! CTI
  56.  and %g7, 4, %g5 ! IEU0
  57. ldxa [%src + 0x00] %asi, %g2 ! Load Group
  58. add %dst, 8, %dst ! IEU0
  59. add %src, 8, %src ! IEU1
  60. addcc %g2, %sum, %sum ! IEU1 Group + 2 bubbles
  61. stw %g2, [%dst - 0x04] ! Store
  62. srlx %g2, 32, %g2 ! IEU0
  63. bcc,pt %xcc, 1f ! CTI Group
  64.  stw %g2, [%dst - 0x08] ! Store
  65. add %sum, 1, %sum ! IEU0
  66. 1: brz,pt %g5, 1f ! CTI Group
  67.  clr %g2 ! IEU0
  68. lduwa [%src + 0x00] %asi, %g2 ! Load
  69. add %dst, 4, %dst ! IEU0 Group
  70. add %src, 4, %src ! IEU1
  71. stw %g2, [%dst - 0x04] ! Store Group + 2 bubbles
  72. sllx %g2, 32, %g2 ! IEU0
  73. 1: andcc %g7, 2, %g0 ! IEU1
  74. be,pn %icc, 1f ! CTI Group
  75.  clr %o4 ! IEU1
  76. lduha [%src + 0x00] %asi, %o4 ! Load
  77. add %src, 2, %src ! IEU0 Group
  78. add %dst, 2, %dst ! IEU1
  79. sth %o4, [%dst - 0x2] ! Store Group + 2 bubbles
  80. sll %o4, 16, %o4 ! IEU0
  81. 1: andcc %g7, 1, %g0 ! IEU1
  82. be,pn %icc, 1f ! CTI Group
  83.  clr %o5 ! IEU0
  84. lduba [%src + 0x00] %asi, %o5 ! Load
  85. stb %o5, [%dst + 0x00] ! Store Group + 2 bubbles
  86. sll %o5, 8, %o5 ! IEU0
  87. 1: or %g2, %o4, %o4 ! IEU1
  88. or %o5, %o4, %o4 ! IEU0 Group
  89. addcc %o4, %sum, %sum ! IEU1
  90. bcc,pt %xcc, ccfold ! CTI
  91.  sethi %uhi(PAGE_OFFSET), %g4 ! IEU0 Group
  92. b,pt %xcc, ccfold ! CTI
  93.  add %sum, 1, %sum ! IEU1
  94. cc_fixit:
  95. cmp %len, 6 ! IEU1 Group
  96. bl,a,pn %icc, ccte ! CTI
  97.  andcc %len, 0xf, %g7 ! IEU1 Group
  98. andcc %src, 2, %g0 ! IEU1 Group
  99. be,pn %icc, 1f ! CTI
  100.  andcc %src, 0x4, %g0 ! IEU1 Group
  101. lduha [%src + 0x00] %asi, %g4 ! Load
  102. sub %len, 2, %len ! IEU0
  103. add %src, 2, %src ! IEU0 Group
  104. add %dst, 2, %dst ! IEU1
  105. sll %g4, 16, %g3 ! IEU0 Group + 1 bubble
  106. addcc %g3, %sum, %sum ! IEU1
  107. bcc,pt %xcc, 0f ! CTI
  108.  srl %sum, 16, %g3 ! IEU0 Group
  109. add %g3, 1, %g3 ! IEU0 4 clocks (mispredict)
  110. 0: andcc %src, 0x4, %g0 ! IEU1 Group
  111. sth %g4, [%dst - 0x2] ! Store
  112. sll %sum, 16, %sum ! IEU0
  113. sll %g3, 16, %g3 ! IEU0 Group
  114. srl %sum, 16, %sum ! IEU0 Group
  115. or %g3, %sum, %sum ! IEU0 Group (regdep)
  116. 1: be,pt %icc, ccmerge ! CTI
  117.  andcc %len, 0xf0, %g1 ! IEU1
  118. lduwa [%src + 0x00] %asi, %g4 ! Load Group
  119. sub %len, 4, %len ! IEU0
  120. add %src, 4, %src ! IEU1
  121. add %dst, 4, %dst ! IEU0 Group
  122. addcc %g4, %sum, %sum ! IEU1 Group + 1 bubble
  123. stw %g4, [%dst - 0x4] ! Store
  124. bcc,pt %xcc, ccmerge ! CTI
  125.  andcc %len, 0xf0, %g1 ! IEU1 Group
  126. b,pt %xcc, ccmerge ! CTI 4 clocks (mispredict)
  127.  add %sum, 1, %sum ! IEU0
  128. .align 32
  129. .globl csum_partial_copy_sparc64
  130. csum_partial_copy_sparc64: /* %o0=src, %o1=dest, %o2=len, %o3=sum */
  131. xorcc %src, %dst, %o4 ! IEU1 Group
  132. srl %sum, 0, %sum ! IEU0
  133. andcc %o4, 3, %g0 ! IEU1 Group
  134. srl %len, 0, %len ! IEU0
  135. bne,pn %icc, ccslow ! CTI
  136.  andcc %src, 1, %g0 ! IEU1 Group
  137. bne,pn %icc, ccslow ! CTI
  138.  cmp %len, 256 ! IEU1 Group
  139. bgeu,pt %icc, csum_partial_copy_vis ! CTI
  140.  andcc %src, 7, %g0 ! IEU1 Group
  141. bne,pn %icc, cc_fixit ! CTI
  142.  andcc %len, 0xf0, %g1 ! IEU1 Group
  143. ccmerge:be,pn %icc, ccte ! CTI
  144.  andcc %len, 0xf, %g7 ! IEU1 Group
  145. sll %g1, 2, %o4 ! IEU0
  146. 13: sethi %hi(12f), %o5 ! IEU0 Group
  147. add %src, %g1, %src ! IEU1
  148. sub %o5, %o4, %o5 ! IEU0 Group
  149. jmpl %o5 + %lo(12f), %g0 ! CTI Group brk forced
  150.  add %dst, %g1, %dst ! IEU0 Group
  151. cctbl: CSUMCOPY_LASTCHUNK(0xe8,%g2,%g3)
  152. CSUMCOPY_LASTCHUNK(0xd8,%g2,%g3)
  153. CSUMCOPY_LASTCHUNK(0xc8,%g2,%g3)
  154. CSUMCOPY_LASTCHUNK(0xb8,%g2,%g3)
  155. CSUMCOPY_LASTCHUNK(0xa8,%g2,%g3)
  156. CSUMCOPY_LASTCHUNK(0x98,%g2,%g3)
  157. CSUMCOPY_LASTCHUNK(0x88,%g2,%g3)
  158. CSUMCOPY_LASTCHUNK(0x78,%g2,%g3)
  159. CSUMCOPY_LASTCHUNK(0x68,%g2,%g3)
  160. CSUMCOPY_LASTCHUNK(0x58,%g2,%g3)
  161. CSUMCOPY_LASTCHUNK(0x48,%g2,%g3)
  162. CSUMCOPY_LASTCHUNK(0x38,%g2,%g3)
  163. CSUMCOPY_LASTCHUNK(0x28,%g2,%g3)
  164. CSUMCOPY_LASTCHUNK(0x18,%g2,%g3)
  165. CSUMCOPY_LASTCHUNK(0x08,%g2,%g3)
  166. 12:
  167. andcc %len, 0xf, %g7 ! IEU1 Group
  168. ccte: bne,pn %icc, cc_end_cruft ! CTI
  169.  sethi %uhi(PAGE_OFFSET), %g4 ! IEU0
  170. ccfold: sllx %sum, 32, %o0 ! IEU0 Group
  171. addcc %sum, %o0, %o0 ! IEU1 Group (regdep)
  172. srlx %o0, 32, %o0 ! IEU0 Group (regdep)
  173. bcs,a,pn %xcc, 1f ! CTI
  174.  add %o0, 1, %o0 ! IEU1 4 clocks (mispredict)
  175. 1: retl ! CTI Group brk forced
  176.  sllx %g4, 32, %g4 ! IEU0 Group
  177. ccslow: mov 0, %g5
  178. brlez,pn %len, 4f
  179.  andcc %src, 1, %o5
  180. be,a,pt %icc, 1f
  181.  srl %len, 1, %g7
  182. sub %len, 1, %len
  183. lduba [%src] %asi, %g5
  184. add %src, 1, %src
  185. stb %g5, [%dst]
  186. srl %len, 1, %g7
  187. add %dst, 1, %dst
  188. 1: brz,a,pn %g7, 3f
  189.  andcc %len, 1, %g0
  190. andcc %src, 2, %g0
  191. be,a,pt %icc, 1f
  192.  srl %g7, 1, %g7
  193. lduha [%src] %asi, %o4
  194. sub %len, 2, %len
  195. srl %o4, 8, %g2
  196. sub %g7, 1, %g7
  197. stb %g2, [%dst]
  198. add %o4, %g5, %g5
  199. stb %o4, [%dst + 1]
  200. add %src, 2, %src
  201. srl %g7, 1, %g7
  202. add %dst, 2, %dst
  203. 1: brz,a,pn %g7, 2f
  204.  andcc %len, 2, %g0
  205. lduwa [%src] %asi, %o4
  206. 5: srl %o4, 24, %g2
  207. srl %o4, 16, %g3
  208. stb %g2, [%dst]
  209. srl %o4, 8, %g2
  210. stb %g3, [%dst + 1]
  211. add %src, 4, %src
  212. stb %g2, [%dst + 2]
  213. addcc %o4, %g5, %g5
  214. stb %o4, [%dst + 3]
  215. addc %g5, %g0, %g5
  216. add %dst, 4, %dst
  217. subcc %g7, 1, %g7
  218. bne,a,pt %icc, 5b
  219.  lduwa [%src] %asi, %o4
  220. sll %g5, 16, %g2
  221. srl %g5, 16, %g5
  222. srl %g2, 16, %g2
  223. andcc %len, 2, %g0
  224. add %g2, %g5, %g5 
  225. 2: be,a,pt %icc, 3f
  226.  andcc %len, 1, %g0
  227. lduha [%src] %asi, %o4
  228. andcc %len, 1, %g0
  229. srl %o4, 8, %g2
  230. add %src, 2, %src
  231. stb %g2, [%dst]
  232. add %g5, %o4, %g5
  233. stb %o4, [%dst + 1]
  234. add %dst, 2, %dst
  235. 3: be,a,pt %icc, 1f
  236.  sll %g5, 16, %o4
  237. lduba [%src] %asi, %g2
  238. sll %g2, 8, %o4
  239. stb %g2, [%dst]
  240. add %g5, %o4, %g5
  241. sll %g5, 16, %o4
  242. 1: addcc %o4, %g5, %g5
  243. srl %g5, 16, %o4
  244. addc %g0, %o4, %g5
  245. brz,pt %o5, 4f
  246.  srl %g5, 8, %o4
  247. and %g5, 0xff, %g2
  248. and %o4, 0xff, %o4
  249. sll %g2, 8, %g2
  250. or %g2, %o4, %g5
  251. 4: addcc %sum, %g5, %sum
  252. addc %g0, %sum, %o0
  253. retl
  254.  srl %o0, 0, %o0
  255. cpc_end:
  256. /* Now the version with userspace as the destination */
  257. #define CSUMCOPY_LASTCHUNK_USER(off, t0, t1)
  258. ldx [%src - off - 0x08], t0;
  259. ldx [%src - off - 0x00], t1;
  260. nop; nop;
  261. addcc t0, %sum, %sum;
  262. stwa t0, [%dst - off - 0x04] %asi;
  263. srlx t0, 32, t0;
  264. bcc,pt %xcc, 51f;
  265.  stwa t0, [%dst - off - 0x08] %asi;
  266. add %sum, 1, %sum;
  267. 51: addcc t1, %sum, %sum;
  268. stwa t1, [%dst - off + 0x04] %asi;
  269. srlx t1, 32, t1;
  270. bcc,pt %xcc, 52f;
  271.  stwa t1, [%dst - off - 0x00] %asi;
  272. add %sum, 1, %sum;
  273. 52:
  274. cpc_user_start:
  275. cc_user_end_cruft:
  276. andcc %g7, 8, %g0 ! IEU1 Group
  277. be,pn %icc, 1f ! CTI
  278.  and %g7, 4, %g5 ! IEU0
  279. ldx [%src + 0x00], %g2 ! Load Group
  280. add %dst, 8, %dst ! IEU0
  281. add %src, 8, %src ! IEU1
  282. addcc %g2, %sum, %sum ! IEU1 Group + 2 bubbles
  283. stwa %g2, [%dst - 0x04] %asi ! Store
  284. srlx %g2, 32, %g2 ! IEU0
  285. bcc,pt %xcc, 1f ! CTI Group
  286.  stwa %g2, [%dst - 0x08] %asi ! Store
  287. add %sum, 1, %sum ! IEU0
  288. 1: brz,pt %g5, 1f ! CTI Group
  289.  clr %g2 ! IEU0
  290. lduw [%src + 0x00], %g2 ! Load
  291. add %dst, 4, %dst ! IEU0 Group
  292. add %src, 4, %src ! IEU1
  293. stwa %g2, [%dst - 0x04] %asi ! Store Group + 2 bubbles
  294. sllx %g2, 32, %g2 ! IEU0
  295. 1: andcc %g7, 2, %g0 ! IEU1
  296. be,pn %icc, 1f ! CTI Group
  297.  clr %o4 ! IEU1
  298. lduh [%src + 0x00], %o4 ! Load
  299. add %src, 2, %src ! IEU0 Group
  300. add %dst, 2, %dst ! IEU1
  301. stha %o4, [%dst - 0x2] %asi ! Store Group + 2 bubbles
  302. sll %o4, 16, %o4 ! IEU0
  303. 1: andcc %g7, 1, %g0 ! IEU1
  304. be,pn %icc, 1f ! CTI Group
  305.  clr %o5 ! IEU0
  306. ldub [%src + 0x00], %o5 ! Load
  307. stba %o5, [%dst + 0x00] %asi ! Store Group + 2 bubbles
  308. sll %o5, 8, %o5 ! IEU0
  309. 1: or %g2, %o4, %o4 ! IEU1
  310. or %o5, %o4, %o4 ! IEU0 Group
  311. addcc %o4, %sum, %sum ! IEU1
  312. bcc,pt %xcc, ccuserfold ! CTI
  313.  sethi %uhi(PAGE_OFFSET), %g4 ! IEU0 Group
  314. b,pt %xcc, ccuserfold ! CTI
  315.  add %sum, 1, %sum ! IEU1
  316. cc_user_fixit:
  317. cmp %len, 6 ! IEU1 Group
  318. bl,a,pn %icc, ccuserte ! CTI
  319.  andcc %len, 0xf, %g7 ! IEU1 Group
  320. andcc %src, 2, %g0 ! IEU1 Group
  321. be,pn %icc, 1f ! CTI
  322.  andcc %src, 0x4, %g0 ! IEU1 Group
  323. lduh [%src + 0x00], %g4 ! Load
  324. sub %len, 2, %len ! IEU0
  325. add %src, 2, %src ! IEU0 Group
  326. add %dst, 2, %dst ! IEU1
  327. sll %g4, 16, %g3 ! IEU0 Group + 1 bubble
  328. addcc %g3, %sum, %sum ! IEU1
  329. bcc,pt %xcc, 0f ! CTI
  330.  srl %sum, 16, %g3 ! IEU0 Group
  331. add %g3, 1, %g3 ! IEU0 4 clocks (mispredict)
  332. 0: andcc %src, 0x4, %g0 ! IEU1 Group
  333. stha %g4, [%dst - 0x2] %asi ! Store
  334. sll %sum, 16, %sum ! IEU0
  335. sll %g3, 16, %g3 ! IEU0 Group
  336. srl %sum, 16, %sum ! IEU0 Group
  337. or %g3, %sum, %sum ! IEU0 Group (regdep)
  338. 1: be,pt %icc, ccusermerge ! CTI
  339.  andcc %len, 0xf0, %g1 ! IEU1
  340. lduw [%src + 0x00], %g4 ! Load Group
  341. sub %len, 4, %len ! IEU0
  342. add %src, 4, %src ! IEU1
  343. add %dst, 4, %dst ! IEU0 Group
  344. addcc %g4, %sum, %sum ! IEU1 Group + 1 bubble
  345. stwa %g4, [%dst - 0x4] %asi ! Store
  346. bcc,pt %xcc, ccusermerge ! CTI
  347.  andcc %len, 0xf0, %g1 ! IEU1 Group
  348. b,pt %xcc, ccusermerge ! CTI 4 clocks (mispredict)
  349.  add %sum, 1, %sum ! IEU0
  350. .align 32
  351. .globl csum_partial_copy_user_sparc64
  352. csum_partial_copy_user_sparc64: /* %o0=src, %o1=dest, %o2=len, %o3=sum */
  353. xorcc %src, %dst, %o4 ! IEU1 Group
  354. srl %sum, 0, %sum ! IEU0
  355. andcc %o4, 3, %g0 ! IEU1 Group
  356. srl %len, 0, %len ! IEU0
  357. bne,pn %icc, ccuserslow ! CTI
  358.  andcc %src, 1, %g0 ! IEU1 Group
  359. bne,pn %icc, ccuserslow ! CTI
  360.  cmp %len, 256 ! IEU1 Group
  361. bgeu,pt %icc, csum_partial_copy_user_vis ! CTI
  362.  andcc %src, 7, %g0 ! IEU1 Group
  363. bne,pn %icc, cc_user_fixit ! CTI
  364.  andcc %len, 0xf0, %g1 ! IEU1 Group
  365. ccusermerge:
  366. be,pn %icc, ccuserte ! CTI
  367.  andcc %len, 0xf, %g7 ! IEU1 Group
  368. sll %g1, 2, %o4 ! IEU0
  369. 13: sethi %hi(12f), %o5 ! IEU0 Group
  370. add %src, %g1, %src ! IEU1
  371. sub %o5, %o4, %o5 ! IEU0 Group
  372. jmpl %o5 + %lo(12f), %g0 ! CTI Group brk forced
  373.  add %dst, %g1, %dst ! IEU0 Group
  374. ccusertbl:
  375. CSUMCOPY_LASTCHUNK_USER(0xe8,%g2,%g3)
  376. CSUMCOPY_LASTCHUNK_USER(0xd8,%g2,%g3)
  377. CSUMCOPY_LASTCHUNK_USER(0xc8,%g2,%g3)
  378. CSUMCOPY_LASTCHUNK_USER(0xb8,%g2,%g3)
  379. CSUMCOPY_LASTCHUNK_USER(0xa8,%g2,%g3)
  380. CSUMCOPY_LASTCHUNK_USER(0x98,%g2,%g3)
  381. CSUMCOPY_LASTCHUNK_USER(0x88,%g2,%g3)
  382. CSUMCOPY_LASTCHUNK_USER(0x78,%g2,%g3)
  383. CSUMCOPY_LASTCHUNK_USER(0x68,%g2,%g3)
  384. CSUMCOPY_LASTCHUNK_USER(0x58,%g2,%g3)
  385. CSUMCOPY_LASTCHUNK_USER(0x48,%g2,%g3)
  386. CSUMCOPY_LASTCHUNK_USER(0x38,%g2,%g3)
  387. CSUMCOPY_LASTCHUNK_USER(0x28,%g2,%g3)
  388. CSUMCOPY_LASTCHUNK_USER(0x18,%g2,%g3)
  389. CSUMCOPY_LASTCHUNK_USER(0x08,%g2,%g3)
  390. 12:
  391. andcc %len, 0xf, %g7 ! IEU1 Group
  392. ccuserte:
  393. bne,pn %icc, cc_user_end_cruft ! CTI
  394.  sethi %uhi(PAGE_OFFSET), %g4 ! IEU0
  395. ccuserfold:
  396. sllx %sum, 32, %o0 ! IEU0 Group
  397. addcc %sum, %o0, %o0 ! IEU1 Group (regdep)
  398. srlx %o0, 32, %o0 ! IEU0 Group (regdep)
  399. bcs,a,pn %xcc, 1f ! CTI
  400.  add %o0, 1, %o0 ! IEU1 4 clocks (mispredict)
  401. 1: retl ! CTI Group brk forced
  402.  sllx %g4, 32, %g4 ! IEU0 Group
  403. ccuserslow:
  404. mov 0, %g5
  405. brlez,pn %len, 4f
  406.  andcc %src, 1, %o5
  407. be,a,pt %icc, 1f
  408.  srl %len, 1, %g7
  409. sub %len, 1, %len
  410. ldub [%src], %g5
  411. add %src, 1, %src
  412. stba %g5, [%dst] %asi
  413. srl %len, 1, %g7
  414. add %dst, 1, %dst
  415. 1: brz,a,pn %g7, 3f
  416.  andcc %len, 1, %g0
  417. andcc %src, 2, %g0
  418. be,a,pt %icc, 1f
  419.  srl %g7, 1, %g7
  420. lduh [%src], %o4
  421. sub %len, 2, %len
  422. srl %o4, 8, %g2
  423. sub %g7, 1, %g7
  424. stba %g2, [%dst] %asi
  425. add %o4, %g5, %g5
  426. stba %o4, [%dst + 1] %asi
  427. add %src, 2, %src
  428. srl %g7, 1, %g7
  429. add %dst, 2, %dst
  430. 1: brz,a,pn %g7, 2f
  431.  andcc %len, 2, %g0
  432. lduw [%src], %o4
  433. 5: srl %o4, 24, %g2
  434. srl %o4, 16, %g3
  435. stba %g2, [%dst] %asi
  436. srl %o4, 8, %g2
  437. stba %g3, [%dst + 1] %asi
  438. add %src, 4, %src
  439. stba %g2, [%dst + 2] %asi
  440. addcc %o4, %g5, %g5
  441. stba %o4, [%dst + 3] %asi
  442. addc %g5, %g0, %g5
  443. add %dst, 4, %dst
  444. subcc %g7, 1, %g7
  445. bne,a,pt %icc, 5b
  446.  lduw [%src], %o4
  447. sll %g5, 16, %g2
  448. srl %g5, 16, %g5
  449. srl %g2, 16, %g2
  450. andcc %len, 2, %g0
  451. add %g2, %g5, %g5 
  452. 2: be,a,pt %icc, 3f
  453.  andcc %len, 1, %g0
  454. lduh [%src], %o4
  455. andcc %len, 1, %g0
  456. srl %o4, 8, %g2
  457. add %src, 2, %src
  458. stba %g2, [%dst] %asi
  459. add %g5, %o4, %g5
  460. stba %o4, [%dst + 1] %asi
  461. add %dst, 2, %dst
  462. 3: be,a,pt %icc, 1f
  463.  sll %g5, 16, %o4
  464. ldub [%src], %g2
  465. sll %g2, 8, %o4
  466. stba  %g2, [%dst] %asi
  467. add %g5, %o4, %g5
  468. sll %g5, 16, %o4
  469. 1: addcc %o4, %g5, %g5
  470. srl %g5, 16, %o4
  471. addc %g0, %o4, %g5
  472. brz,pt %o5, 4f
  473.  srl %g5, 8, %o4
  474. and %g5, 0xff, %g2
  475. and %o4, 0xff, %o4
  476. sll %g2, 8, %g2
  477. or %g2, %o4, %g5
  478. 4: addcc %sum, %g5, %sum
  479. addc %g0, %sum, %o0
  480. retl
  481.  srl %o0, 0, %o0
  482. cpc_user_end:
  483. .globl cpc_handler
  484. cpc_handler:
  485. ldx [%sp + 0x7ff + 128], %g1
  486. ldub [%g6 + AOFF_task_thread + AOFF_thread_current_ds], %g3
  487. sub %g0, EFAULT, %g2
  488. brnz,a,pt %g1, 1f
  489.  st %g2, [%g1]
  490. 1: sethi %uhi(PAGE_OFFSET), %g4
  491. wr %g3, %g0, %asi
  492. retl
  493.  sllx %g4, 32, %g4
  494. .section __ex_table
  495. .align  4
  496. .word cpc_start, 0, cpc_end, cpc_handler
  497. .word cpc_user_start, 0, cpc_user_end, cpc_handler