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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* memcpy.S: Sparc optimized memcpy, bcopy and memmove code
  2.  * Hand optimized from GNU libc's memcpy, bcopy and memmove
  3.  * Copyright (C) 1991,1996 Free Software Foundation
  4.  * Copyright (C) 1995 Linus Torvalds (Linus.Torvalds@helsinki.fi)
  5.  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
  6.  * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
  7.  * Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  8.  */
  9. #ifdef __KERNEL__
  10. #include <asm/cprefix.h>
  11. #define FUNC(x) 
  12. .globl C_LABEL(x);
  13. .type C_LABEL(x),@function;
  14. .align 4;
  15. C_LABEL(x):
  16. #undef FASTER_REVERSE
  17. #undef FASTER_NONALIGNED
  18. #define FASTER_ALIGNED
  19. /* In kernel these functions don't return a value.
  20.  * One should use macros in asm/string.h for that purpose.
  21.  * We return 0, so that bugs are more apparent.
  22.  */
  23. #define SETUP_RETL
  24. #define RETL_INSN clr %o0
  25. #else
  26. /* libc */
  27. #include "DEFS.h"
  28. #define FASTER_REVERSE
  29. #define FASTER_NONALIGNED
  30. #define FASTER_ALIGNED
  31. #define SETUP_RETL mov %o0, %g6
  32. #define RETL_INSN mov %g6, %o0
  33. #endif
  34. /* Both these macros have to start with exactly the same insn */
  35. #define MOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) 
  36. ldd [%src + offset + 0x00], %t0; 
  37. ldd [%src + offset + 0x08], %t2; 
  38. ldd [%src + offset + 0x10], %t4; 
  39. ldd [%src + offset + 0x18], %t6; 
  40. st %t0, [%dst + offset + 0x00]; 
  41. st %t1, [%dst + offset + 0x04]; 
  42. st %t2, [%dst + offset + 0x08]; 
  43. st %t3, [%dst + offset + 0x0c]; 
  44. st %t4, [%dst + offset + 0x10]; 
  45. st %t5, [%dst + offset + 0x14]; 
  46. st %t6, [%dst + offset + 0x18]; 
  47. st %t7, [%dst + offset + 0x1c];
  48. #define MOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) 
  49. ldd [%src + offset + 0x00], %t0; 
  50. ldd [%src + offset + 0x08], %t2; 
  51. ldd [%src + offset + 0x10], %t4; 
  52. ldd [%src + offset + 0x18], %t6; 
  53. std %t0, [%dst + offset + 0x00]; 
  54. std %t2, [%dst + offset + 0x08]; 
  55. std %t4, [%dst + offset + 0x10]; 
  56. std %t6, [%dst + offset + 0x18];
  57. #define MOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) 
  58. ldd [%src - offset - 0x10], %t0; 
  59. ldd [%src - offset - 0x08], %t2; 
  60. st %t0, [%dst - offset - 0x10]; 
  61. st %t1, [%dst - offset - 0x0c]; 
  62. st %t2, [%dst - offset - 0x08]; 
  63. st %t3, [%dst - offset - 0x04];
  64. #define MOVE_LASTALIGNCHUNK(src, dst, offset, t0, t1, t2, t3) 
  65. ldd [%src - offset - 0x10], %t0; 
  66. ldd [%src - offset - 0x08], %t2; 
  67. std %t0, [%dst - offset - 0x10]; 
  68. std %t2, [%dst - offset - 0x08];
  69. #define MOVE_SHORTCHUNK(src, dst, offset, t0, t1) 
  70. ldub [%src - offset - 0x02], %t0; 
  71. ldub [%src - offset - 0x01], %t1; 
  72. stb %t0, [%dst - offset - 0x02]; 
  73. stb %t1, [%dst - offset - 0x01];
  74. /* Both these macros have to start with exactly the same insn */
  75. #define RMOVE_BIGCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) 
  76. ldd [%src - offset - 0x20], %t0; 
  77. ldd [%src - offset - 0x18], %t2; 
  78. ldd [%src - offset - 0x10], %t4; 
  79. ldd [%src - offset - 0x08], %t6; 
  80. st %t0, [%dst - offset - 0x20]; 
  81. st %t1, [%dst - offset - 0x1c]; 
  82. st %t2, [%dst - offset - 0x18]; 
  83. st %t3, [%dst - offset - 0x14]; 
  84. st %t4, [%dst - offset - 0x10]; 
  85. st %t5, [%dst - offset - 0x0c]; 
  86. st %t6, [%dst - offset - 0x08]; 
  87. st %t7, [%dst - offset - 0x04];
  88. #define RMOVE_BIGALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, t7) 
  89. ldd [%src - offset - 0x20], %t0; 
  90. ldd [%src - offset - 0x18], %t2; 
  91. ldd [%src - offset - 0x10], %t4; 
  92. ldd [%src - offset - 0x08], %t6; 
  93. std %t0, [%dst - offset - 0x20]; 
  94. std %t2, [%dst - offset - 0x18]; 
  95. std %t4, [%dst - offset - 0x10]; 
  96. std %t6, [%dst - offset - 0x08];
  97. #define RMOVE_LASTCHUNK(src, dst, offset, t0, t1, t2, t3) 
  98. ldd [%src + offset + 0x00], %t0; 
  99. ldd [%src + offset + 0x08], %t2; 
  100. st %t0, [%dst + offset + 0x00]; 
  101. st %t1, [%dst + offset + 0x04]; 
  102. st %t2, [%dst + offset + 0x08]; 
  103. st %t3, [%dst + offset + 0x0c];
  104. #define RMOVE_SHORTCHUNK(src, dst, offset, t0, t1) 
  105. ldub [%src + offset + 0x00], %t0; 
  106. ldub [%src + offset + 0x01], %t1; 
  107. stb %t0, [%dst + offset + 0x00]; 
  108. stb %t1, [%dst + offset + 0x01];
  109. #define SMOVE_CHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) 
  110. ldd [%src + offset + 0x00], %t0; 
  111. ldd [%src + offset + 0x08], %t2; 
  112. srl %t0, shir, %t5; 
  113. srl %t1, shir, %t6; 
  114. sll %t0, shil, %t0; 
  115. or %t5, %prev, %t5; 
  116. sll %t1, shil, %prev; 
  117. or %t6, %t0, %t0; 
  118. srl %t2, shir, %t1; 
  119. srl %t3, shir, %t6; 
  120. sll %t2, shil, %t2; 
  121. or %t1, %prev, %t1; 
  122. std %t4, [%dst + offset + offset2 - 0x04]; 
  123. std %t0, [%dst + offset + offset2 + 0x04];
  124. sll %t3, shil, %prev; 
  125. or %t6, %t2, %t4;
  126. #define SMOVE_ALIGNCHUNK(src, dst, offset, t0, t1, t2, t3, t4, t5, t6, prev, shil, shir, offset2) 
  127. ldd [%src + offset + 0x00], %t0; 
  128. ldd [%src + offset + 0x08], %t2; 
  129. srl %t0, shir, %t4; 
  130. srl %t1, shir, %t5; 
  131. sll %t0, shil, %t6; 
  132. or %t4, %prev, %t0; 
  133. sll %t1, shil, %prev; 
  134. or %t5, %t6, %t1; 
  135. srl %t2, shir, %t4; 
  136. srl %t3, shir, %t5; 
  137. sll %t2, shil, %t6; 
  138. or %t4, %prev, %t2; 
  139. sll %t3, shil, %prev; 
  140. or %t5, %t6, %t3;
  141. std %t0, [%dst + offset + offset2 + 0x00]; 
  142. std %t2, [%dst + offset + offset2 + 0x08];
  143. .text
  144. .align 4
  145. #ifdef FASTER_REVERSE
  146. 70: /* rdword_align */
  147. andcc %o1, 1, %g0
  148. be 4f
  149.  andcc %o1, 2, %g0
  150. ldub [%o1 - 1], %g2
  151. sub %o1, 1, %o1
  152. stb %g2, [%o0 - 1]
  153. sub %o2, 1, %o2
  154. be 3f
  155.  sub %o0, 1, %o0
  156. 4:
  157. lduh [%o1 - 2], %g2
  158. sub %o1, 2, %o1
  159. sth %g2, [%o0 - 2]
  160. sub %o2, 2, %o2
  161. b 3f
  162.  sub %o0, 2, %o0
  163. #endif /* FASTER_REVERSE */
  164. 0:
  165. retl
  166.  nop ! Only bcopy returns here and it retuns void...
  167. FUNC(bcopy)
  168. mov %o0, %o3
  169. mov %o1, %o0
  170. mov %o3, %o1
  171. tst %o2
  172. bcs 0b
  173.  /* Do the cmp in the delay slot */
  174. #ifdef __KERNEL__
  175. FUNC(amemmove)
  176. FUNC(__memmove)
  177. #endif
  178. FUNC(memmove)
  179. cmp %o0, %o1
  180. SETUP_RETL
  181. bleu 9f
  182.  sub %o0, %o1, %o4
  183. add %o1, %o2, %o3
  184. cmp %o3, %o0
  185. bleu 0f
  186.  andcc %o4, 3, %o5
  187. #ifndef FASTER_REVERSE
  188. add %o1, %o2, %o1
  189. add %o0, %o2, %o0
  190. sub %o1, 1, %o1
  191. sub %o0, 1, %o0
  192. 1: /* reverse_bytes */
  193. ldub [%o1], %o4
  194. subcc %o2, 1, %o2
  195. stb %o4, [%o0]
  196. sub %o1, 1, %o1
  197. bne 1b
  198.  sub %o0, 1, %o0
  199. retl
  200.  RETL_INSN
  201. #else /* FASTER_REVERSE */
  202. add %o1, %o2, %o1
  203. add %o0, %o2, %o0
  204. bne 77f
  205.  cmp %o2, 15
  206. bleu 91f
  207.  andcc %o1, 3, %g0
  208. bne 70b
  209. 3:
  210.  andcc %o1, 4, %g0
  211. be 2f
  212.  mov %o2, %g1
  213. ld [%o1 - 4], %o4
  214. sub %g1, 4, %g1
  215. st %o4, [%o0 - 4]
  216. sub %o1, 4, %o1
  217. sub %o0, 4, %o0
  218. 2:
  219. andcc %g1, 0xffffff80, %g7
  220. be 3f
  221.  andcc %o0, 4, %g0
  222. be 74f + 4
  223. 5:
  224. RMOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
  225. RMOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
  226. RMOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
  227. RMOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
  228. subcc %g7, 128, %g7
  229. sub %o1, 128, %o1
  230. bne 5b
  231.  sub %o0, 128, %o0
  232. 3:
  233. andcc %g1, 0x70, %g7
  234. be 72f
  235.  andcc %g1, 8, %g0
  236. sethi %hi(72f), %o5
  237. srl %g7, 1, %o4
  238. add %g7, %o4, %o4
  239. sub %o1, %g7, %o1
  240. sub %o5, %o4, %o5
  241. jmpl %o5 + %lo(72f), %g0
  242.  sub %o0, %g7, %o0
  243. 71: /* rmemcpy_table */
  244. RMOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
  245. RMOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
  246. RMOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
  247. RMOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
  248. RMOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
  249. RMOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
  250. RMOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
  251. 72: /* rmemcpy_table_end */
  252. be 73f
  253.  andcc %g1, 4, %g0
  254. ldd [%o1 - 0x08], %g2
  255. sub %o0, 8, %o0
  256. sub %o1, 8, %o1
  257. st %g2, [%o0]
  258. st %g3, [%o0 + 0x04]
  259. 73: /* rmemcpy_last7 */
  260. be 1f
  261.  andcc %g1, 2, %g0
  262. ld [%o1 - 4], %g2
  263. sub %o1, 4, %o1
  264. st %g2, [%o0 - 4]
  265. sub %o0, 4, %o0
  266. 1:
  267. be 1f
  268.  andcc %g1, 1, %g0
  269. lduh [%o1 - 2], %g2
  270. sub %o1, 2, %o1
  271. sth %g2, [%o0 - 2]
  272. sub %o0, 2, %o0
  273. 1:
  274. be 1f
  275.  nop
  276. ldub [%o1 - 1], %g2
  277. stb %g2, [%o0 - 1]
  278. 1:
  279. retl
  280.    RETL_INSN
  281. 74: /* rldd_std */
  282. RMOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
  283. RMOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
  284. RMOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
  285. RMOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
  286. subcc %g7, 128, %g7
  287. sub %o1, 128, %o1
  288. bne 74b
  289.  sub %o0, 128, %o0
  290. andcc %g1, 0x70, %g7
  291. be 72b
  292.  andcc %g1, 8, %g0
  293. sethi %hi(72b), %o5
  294. srl %g7, 1, %o4
  295. add %g7, %o4, %o4
  296. sub %o1, %g7, %o1
  297. sub %o5, %o4, %o5
  298. jmpl %o5 + %lo(72b), %g0
  299.  sub %o0, %g7, %o0
  300. 75: /* rshort_end */
  301. and %o2, 0xe, %o3
  302. 2:
  303. sethi %hi(76f), %o5
  304. sll %o3, 3, %o4
  305. sub %o0, %o3, %o0
  306. sub %o5, %o4, %o5
  307. sub %o1, %o3, %o1
  308. jmpl %o5 + %lo(76f), %g0
  309.  andcc %o2, 1, %g0
  310. RMOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
  311. RMOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
  312. RMOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
  313. RMOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
  314. RMOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
  315. RMOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
  316. RMOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
  317. 76: /* rshort_table_end */
  318. be 1f
  319.  nop
  320. ldub [%o1 - 1], %g2
  321. stb %g2, [%o0 - 1]
  322. 1:
  323. retl
  324.    RETL_INSN
  325. 91: /* rshort_aligned_end */
  326. bne 75b
  327.  andcc %o2, 8, %g0
  328. be 1f
  329.  andcc %o2, 4, %g0
  330. ld [%o1 - 0x08], %g2
  331. ld [%o1 - 0x04], %g3
  332. sub %o1, 8, %o1
  333. st %g2, [%o0 - 0x08]
  334. st %g3, [%o0 - 0x04]
  335. sub %o0, 8, %o0
  336. 1:
  337. b 73b
  338.  mov %o2, %g1
  339. 77: /* rnon_aligned */
  340. cmp %o2, 15
  341. bleu 75b
  342.  andcc %o0, 3, %g0
  343. be 64f
  344.  andcc %o0, 1, %g0
  345. be 63f
  346.  andcc %o0, 2, %g0
  347. ldub [%o1 - 1], %g5
  348. sub %o1, 1, %o1
  349. stb %g5, [%o0 - 1]
  350. sub %o0, 1, %o0
  351. be 64f
  352.  sub %o2, 1, %o2
  353. 63:
  354. ldub [%o1 - 1], %g5
  355. sub %o1, 2, %o1
  356. stb %g5, [%o0 - 1]
  357. sub %o0, 2, %o0
  358. ldub [%o1], %g5
  359. sub %o2, 2, %o2
  360. stb %g5, [%o0]
  361. 64:
  362. and %o1, 3, %g2
  363. and %o1, -4, %o1
  364. and %o2, 0xc, %g3
  365. add %o1, 4, %o1
  366. cmp %g3, 4
  367. sll %g2, 3, %g4
  368. mov 32, %g2
  369. be 4f
  370.  sub %g2, %g4, %g7
  371. blu 3f
  372.  cmp %g3, 8
  373. be 2f
  374.  srl %o2, 2, %g3
  375. ld [%o1 - 4], %o3
  376. add %o0, -8, %o0
  377. ld [%o1 - 8], %o4
  378. add %o1, -16, %o1
  379. b 7f
  380.  add %g3, 1, %g3
  381. 2:
  382. ld [%o1 - 4], %o4
  383. add %o0, -4, %o0
  384. ld [%o1 - 8], %g1
  385. add %o1, -12, %o1
  386. b 8f
  387.  add %g3, 2, %g3
  388. 3:
  389. ld [%o1 - 4], %o5
  390. add %o0, -12, %o0
  391. ld [%o1 - 8], %o3
  392. add %o1, -20, %o1
  393. b 6f
  394.  srl %o2, 2, %g3
  395. 4:
  396. ld [%o1 - 4], %g1
  397. srl %o2, 2, %g3
  398. ld [%o1 - 8], %o5
  399. add %o1, -24, %o1
  400. add %o0, -16, %o0
  401. add %g3, -1, %g3
  402. ld [%o1 + 12], %o3
  403. 5:
  404. sll %o5, %g4, %g2
  405. srl %g1, %g7, %g5
  406. or %g2, %g5, %g2
  407. st %g2, [%o0 + 12]
  408. 6:
  409. ld [%o1 + 8], %o4
  410. sll %o3, %g4, %g2
  411. srl %o5, %g7, %g5
  412. or %g2, %g5, %g2
  413. st %g2, [%o0 + 8]
  414. 7:
  415. ld [%o1 + 4], %g1
  416. sll %o4, %g4, %g2
  417. srl %o3, %g7, %g5
  418. or %g2, %g5, %g2
  419. st %g2, [%o0 + 4]
  420. 8:
  421. ld [%o1], %o5
  422. sll %g1, %g4, %g2
  423. srl %o4, %g7, %g5
  424. addcc %g3, -4, %g3
  425. or %g2, %g5, %g2
  426. add %o1, -16, %o1
  427. st %g2, [%o0]
  428. add %o0, -16, %o0
  429. bne,a 5b
  430.  ld [%o1 + 12], %o3
  431. sll %o5, %g4, %g2
  432. srl %g1, %g7, %g5
  433. srl %g4, 3, %g3
  434. or %g2, %g5, %g2
  435. add %o1, %g3, %o1
  436. andcc %o2, 2, %g0
  437. st %g2, [%o0 + 12]
  438. be 1f
  439.  andcc %o2, 1, %g0
  440. ldub [%o1 + 15], %g5
  441. add %o1, -2, %o1
  442. stb %g5, [%o0 + 11]
  443. add %o0, -2, %o0
  444. ldub [%o1 + 16], %g5
  445. stb %g5, [%o0 + 12]
  446. 1:
  447. be 1f
  448.  nop
  449. ldub [%o1 + 15], %g5
  450. stb %g5, [%o0 + 11]
  451. 1:
  452. retl
  453.  RETL_INSN
  454. #endif /* FASTER_REVERSE */
  455. /* NOTE: This code is executed just for the cases,
  456.          where %src (=%o1) & 3 is != 0.
  457.  We need to align it to 4. So, for (%src & 3)
  458.  1 we need to do ldub,lduh
  459.  2 lduh
  460.  3 just ldub
  461.          so even if it looks weird, the branches
  462.          are correct here. -jj
  463.  */
  464. 78: /* dword_align */
  465. andcc %o1, 1, %g0
  466. be 4f
  467.  andcc %o1, 2, %g0
  468. ldub [%o1], %g2
  469. add %o1, 1, %o1
  470. stb %g2, [%o0]
  471. sub %o2, 1, %o2
  472. bne 3f
  473.  add %o0, 1, %o0
  474. 4:
  475. lduh [%o1], %g2
  476. add %o1, 2, %o1
  477. sth %g2, [%o0]
  478. sub %o2, 2, %o2
  479. b 3f
  480.  add %o0, 2, %o0
  481. #ifdef __KERNEL__
  482. FUNC(__memcpy)
  483. #endif
  484. FUNC(memcpy) /* %o0=dst %o1=src %o2=len */
  485. sub %o0, %o1, %o4
  486. SETUP_RETL
  487. 9:
  488. andcc %o4, 3, %o5
  489. 0:
  490. bne 86f
  491.  cmp %o2, 15
  492. bleu 90f
  493.  andcc %o1, 3, %g0
  494. bne 78b
  495. 3:
  496.  andcc %o1, 4, %g0
  497. be 2f
  498.  mov %o2, %g1
  499. ld [%o1], %o4
  500. sub %g1, 4, %g1
  501. st %o4, [%o0]
  502. add %o1, 4, %o1
  503. add %o0, 4, %o0
  504. 2:
  505. andcc %g1, 0xffffff80, %g7
  506. be 3f
  507.  andcc %o0, 4, %g0
  508. be 82f + 4
  509. 5:
  510. MOVE_BIGCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
  511. MOVE_BIGCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
  512. MOVE_BIGCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
  513. MOVE_BIGCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
  514. subcc %g7, 128, %g7
  515. add %o1, 128, %o1
  516. bne 5b
  517.  add %o0, 128, %o0
  518. 3:
  519. andcc %g1, 0x70, %g7
  520. be 80f
  521.  andcc %g1, 8, %g0
  522. sethi %hi(80f), %o5
  523. srl %g7, 1, %o4
  524. add %g7, %o4, %o4
  525. add %o1, %g7, %o1
  526. sub %o5, %o4, %o5
  527. jmpl %o5 + %lo(80f), %g0
  528.  add %o0, %g7, %o0
  529. 79: /* memcpy_table */
  530. MOVE_LASTCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
  531. MOVE_LASTCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
  532. MOVE_LASTCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
  533. MOVE_LASTCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
  534. MOVE_LASTCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
  535. MOVE_LASTCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
  536. MOVE_LASTCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
  537. 80: /* memcpy_table_end */
  538. be 81f
  539.  andcc %g1, 4, %g0
  540. ldd [%o1], %g2
  541. add %o0, 8, %o0
  542. st %g2, [%o0 - 0x08]
  543. add %o1, 8, %o1
  544. st %g3, [%o0 - 0x04]
  545. 81: /* memcpy_last7 */
  546. be 1f
  547.  andcc %g1, 2, %g0
  548. ld [%o1], %g2
  549. add %o1, 4, %o1
  550. st %g2, [%o0]
  551. add %o0, 4, %o0
  552. 1:
  553. be 1f
  554.  andcc %g1, 1, %g0
  555. lduh [%o1], %g2
  556. add %o1, 2, %o1
  557. sth %g2, [%o0]
  558. add %o0, 2, %o0
  559. 1:
  560. be 1f
  561.  nop
  562. ldub [%o1], %g2
  563. stb %g2, [%o0]
  564. 1:
  565. retl
  566.    RETL_INSN
  567. 82: /* ldd_std */
  568. MOVE_BIGALIGNCHUNK(o1, o0, 0x00, o2, o3, o4, o5, g2, g3, g4, g5)
  569. MOVE_BIGALIGNCHUNK(o1, o0, 0x20, o2, o3, o4, o5, g2, g3, g4, g5)
  570. MOVE_BIGALIGNCHUNK(o1, o0, 0x40, o2, o3, o4, o5, g2, g3, g4, g5)
  571. MOVE_BIGALIGNCHUNK(o1, o0, 0x60, o2, o3, o4, o5, g2, g3, g4, g5)
  572. subcc %g7, 128, %g7
  573. add %o1, 128, %o1
  574. bne 82b
  575.  add %o0, 128, %o0
  576. #ifndef FASTER_ALIGNED
  577. andcc %g1, 0x70, %g7
  578. be 80b
  579.  andcc %g1, 8, %g0
  580. sethi %hi(80b), %o5
  581. srl %g7, 1, %o4
  582. add %g7, %o4, %o4
  583. add %o1, %g7, %o1
  584. sub %o5, %o4, %o5
  585. jmpl %o5 + %lo(80b), %g0
  586.  add %o0, %g7, %o0
  587. #else /* FASTER_ALIGNED */
  588. andcc %g1, 0x70, %g7
  589. be 84f
  590.  andcc %g1, 8, %g0
  591. sethi %hi(84f), %o5
  592. add %o1, %g7, %o1
  593. sub %o5, %g7, %o5
  594. jmpl %o5 + %lo(84f), %g0
  595.  add %o0, %g7, %o0
  596. 83: /* amemcpy_table */
  597. MOVE_LASTALIGNCHUNK(o1, o0, 0x60, g2, g3, g4, g5)
  598. MOVE_LASTALIGNCHUNK(o1, o0, 0x50, g2, g3, g4, g5)
  599. MOVE_LASTALIGNCHUNK(o1, o0, 0x40, g2, g3, g4, g5)
  600. MOVE_LASTALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5)
  601. MOVE_LASTALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5)
  602. MOVE_LASTALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5)
  603. MOVE_LASTALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5)
  604. 84: /* amemcpy_table_end */
  605. be 85f
  606.  andcc %g1, 4, %g0
  607. ldd [%o1], %g2
  608. add %o0, 8, %o0
  609. std %g2, [%o0 - 0x08]
  610. add %o1, 8, %o1
  611. 85: /* amemcpy_last7 */
  612. be 1f
  613.  andcc %g1, 2, %g0
  614. ld [%o1], %g2
  615. add %o1, 4, %o1
  616. st %g2, [%o0]
  617. add %o0, 4, %o0
  618. 1:
  619. be 1f
  620.  andcc %g1, 1, %g0
  621. lduh [%o1], %g2
  622. add %o1, 2, %o1
  623. sth %g2, [%o0]
  624. add %o0, 2, %o0
  625. 1:
  626. be 1f
  627.  nop
  628. ldub [%o1], %g2
  629. stb %g2, [%o0]
  630. 1:
  631. retl
  632.    RETL_INSN
  633. #endif /* FASTER_ALIGNED */
  634. 86: /* non_aligned */
  635. cmp %o2, 6
  636. bleu 88f
  637. #ifdef FASTER_NONALIGNED
  638.  cmp %o2, 256
  639. bcc 87f
  640. #endif /* FASTER_NONALIGNED */
  641.  andcc %o0, 3, %g0
  642. be 61f
  643.  andcc %o0, 1, %g0
  644. be 60f
  645.  andcc %o0, 2, %g0
  646. ldub [%o1], %g5
  647. add %o1, 1, %o1
  648. stb %g5, [%o0]
  649. sub %o2, 1, %o2
  650. bne 61f
  651.  add %o0, 1, %o0
  652. 60:
  653. ldub [%o1], %g3
  654. add %o1, 2, %o1
  655. stb %g3, [%o0]
  656. sub %o2, 2, %o2
  657. ldub [%o1 - 1], %g3
  658. add %o0, 2, %o0
  659. stb %g3, [%o0 - 1]
  660. 61:
  661. and %o1, 3, %g2
  662. and %o2, 0xc, %g3
  663. and %o1, -4, %o1
  664. cmp %g3, 4
  665. sll %g2, 3, %g4
  666. mov 32, %g2
  667. be 4f
  668.  sub %g2, %g4, %g7
  669. blu 3f
  670.  cmp %g3, 0x8
  671. be 2f
  672.  srl %o2, 2, %g3
  673. ld [%o1], %o3
  674. add %o0, -8, %o0
  675. ld [%o1 + 4], %o4
  676. b 8f
  677.  add %g3, 1, %g3
  678. 2:
  679. ld [%o1], %o4
  680. add %o0, -12, %o0
  681. ld [%o1 + 4], %o5
  682. add %g3, 2, %g3
  683. b 9f
  684.  add %o1, -4, %o1
  685. 3:
  686. ld [%o1], %g1
  687. add %o0, -4, %o0
  688. ld [%o1 + 4], %o3
  689. srl %o2, 2, %g3
  690. b 7f
  691.  add %o1, 4, %o1
  692. 4:
  693. ld [%o1], %o5
  694. cmp %o2, 7
  695. ld [%o1 + 4], %g1
  696. srl %o2, 2, %g3
  697. bleu 10f
  698.  add %o1, 8, %o1
  699. ld [%o1], %o3
  700. add %g3, -1, %g3
  701. 5:
  702. sll %o5, %g4, %g2
  703. srl %g1, %g7, %g5
  704. or %g2, %g5, %g2
  705. st %g2, [%o0]
  706. 7:
  707. ld [%o1 + 4], %o4
  708. sll %g1, %g4, %g2
  709. srl %o3, %g7, %g5
  710. or %g2, %g5, %g2
  711. st %g2, [%o0 + 4]
  712. 8:
  713. ld [%o1 + 8], %o5
  714. sll %o3, %g4, %g2
  715. srl %o4, %g7, %g5
  716. or %g2, %g5, %g2
  717. st %g2, [%o0 + 8]
  718. 9:
  719. ld [%o1 + 12], %g1
  720. sll %o4, %g4, %g2
  721. srl %o5, %g7, %g5
  722. addcc %g3, -4, %g3
  723. or %g2, %g5, %g2
  724. add %o1, 16, %o1
  725. st %g2, [%o0 + 12]
  726. add %o0, 16, %o0
  727. bne,a 5b
  728.  ld [%o1], %o3
  729. 10:
  730. sll %o5, %g4, %g2
  731. srl %g1, %g7, %g5
  732. srl %g7, 3, %g3
  733. or %g2, %g5, %g2
  734. sub %o1, %g3, %o1
  735. andcc %o2, 2, %g0
  736. st %g2, [%o0]
  737. be 1f
  738.  andcc %o2, 1, %g0
  739. ldub [%o1], %g2
  740. add %o1, 2, %o1
  741. stb %g2, [%o0 + 4]
  742. add %o0, 2, %o0
  743. ldub [%o1 - 1], %g2
  744. stb %g2, [%o0 + 3]
  745. 1:
  746. be 1f
  747.  nop
  748. ldub [%o1], %g2
  749. stb %g2, [%o0 + 4]
  750. 1:
  751. retl
  752.  RETL_INSN
  753. #ifdef FASTER_NONALIGNED
  754. 87: /* faster_nonaligned */
  755. andcc %o1, 3, %g0
  756. be 3f
  757.  andcc %o1, 1, %g0
  758. be 4f
  759.  andcc %o1, 2, %g0
  760. ldub [%o1], %g2
  761. add %o1, 1, %o1
  762. stb %g2, [%o0]
  763. sub %o2, 1, %o2
  764. bne 3f
  765.  add %o0, 1, %o0
  766. 4:
  767. lduh [%o1], %g2
  768. add %o1, 2, %o1
  769. srl %g2, 8, %g3
  770. sub %o2, 2, %o2
  771. stb %g3, [%o0]
  772. add %o0, 2, %o0
  773. stb %g2, [%o0 - 1]
  774. 3:
  775.  andcc %o1, 4, %g0
  776. bne 2f
  777.  cmp %o5, 1
  778. ld [%o1], %o4
  779. srl %o4, 24, %g2
  780. stb %g2, [%o0]
  781. srl %o4, 16, %g3
  782. stb %g3, [%o0 + 1]
  783. srl %o4, 8, %g2
  784. stb %g2, [%o0 + 2]
  785. sub %o2, 4, %o2
  786. stb %o4, [%o0 + 3]
  787. add %o1, 4, %o1
  788. add %o0, 4, %o0
  789. 2:
  790. be 33f
  791.  cmp %o5, 2
  792. be 32f
  793.  sub %o2, 4, %o2
  794. 31:
  795. ld [%o1], %g2
  796. add %o1, 4, %o1
  797. srl %g2, 24, %g3
  798. and %o0, 7, %g5
  799. stb %g3, [%o0]
  800. cmp %g5, 7
  801. sll %g2, 8, %g1
  802. add %o0, 4, %o0
  803. be 41f
  804.  and %o2, 0xffffffc0, %o3
  805. ld [%o0 - 7], %o4
  806. 4:
  807. SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
  808. SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
  809. SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
  810. SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
  811. subcc %o3, 64, %o3
  812. add %o1, 64, %o1
  813. bne 4b
  814.  add %o0, 64, %o0
  815. andcc %o2, 0x30, %o3
  816. be,a 1f
  817.  srl %g1, 16, %g2
  818. 4:
  819. SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
  820. subcc %o3, 16, %o3
  821. add %o1, 16, %o1
  822. bne 4b
  823.  add %o0, 16, %o0
  824. srl %g1, 16, %g2
  825. 1:
  826. st %o4, [%o0 - 7]
  827. sth %g2, [%o0 - 3]
  828. srl %g1, 8, %g4
  829. b 88f
  830.  stb %g4, [%o0 - 1]
  831. 32:
  832. ld [%o1], %g2
  833. add %o1, 4, %o1
  834. srl %g2, 16, %g3
  835. and %o0, 7, %g5
  836. sth %g3, [%o0]
  837. cmp %g5, 6
  838. sll %g2, 16, %g1
  839. add %o0, 4, %o0
  840. be 42f
  841.  and %o2, 0xffffffc0, %o3
  842. ld [%o0 - 6], %o4
  843. 4:
  844. SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
  845. SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
  846. SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
  847. SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
  848. subcc %o3, 64, %o3
  849. add %o1, 64, %o1
  850. bne 4b
  851.  add %o0, 64, %o0
  852. andcc %o2, 0x30, %o3
  853. be,a 1f
  854.  srl %g1, 16, %g2
  855. 4:
  856. SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
  857. subcc %o3, 16, %o3
  858. add %o1, 16, %o1
  859. bne 4b
  860.  add %o0, 16, %o0
  861. srl %g1, 16, %g2
  862. 1:
  863. st %o4, [%o0 - 6]
  864. b 88f
  865.  sth %g2, [%o0 - 2]
  866. 33:
  867. ld [%o1], %g2
  868. sub %o2, 4, %o2
  869. srl %g2, 24, %g3
  870. and %o0, 7, %g5
  871. stb %g3, [%o0]
  872. cmp %g5, 5
  873. srl %g2, 8, %g4
  874. sll %g2, 24, %g1
  875. sth %g4, [%o0 + 1]
  876. add %o1, 4, %o1
  877. be 43f
  878.  and %o2, 0xffffffc0, %o3
  879. ld [%o0 - 1], %o4
  880. add %o0, 4, %o0
  881. 4:
  882. SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
  883. SMOVE_CHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
  884. SMOVE_CHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
  885. SMOVE_CHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
  886. subcc %o3, 64, %o3
  887. add %o1, 64, %o1
  888. bne 4b
  889.  add %o0, 64, %o0
  890. andcc %o2, 0x30, %o3
  891. be,a 1f
  892.  srl %g1, 24, %g2
  893. 4:
  894. SMOVE_CHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, -1)
  895. subcc %o3, 16, %o3
  896. add %o1, 16, %o1
  897. bne 4b
  898.  add %o0, 16, %o0
  899. srl %g1, 24, %g2
  900. 1:
  901. st %o4, [%o0 - 5]
  902. b 88f
  903.  stb %g2, [%o0 - 1]
  904. 41:
  905. SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
  906. SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
  907. SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
  908. SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
  909. subcc %o3, 64, %o3
  910. add %o1, 64, %o1
  911. bne 41b
  912.  add %o0, 64, %o0
  913.  
  914. andcc %o2, 0x30, %o3
  915. be,a 1f
  916.  srl %g1, 16, %g2
  917. 4:
  918. SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 8, 24, -3)
  919. subcc %o3, 16, %o3
  920. add %o1, 16, %o1
  921. bne 4b
  922.  add %o0, 16, %o0
  923. srl %g1, 16, %g2
  924. 1:
  925. sth %g2, [%o0 - 3]
  926. srl %g1, 8, %g4
  927. b 88f
  928.  stb %g4, [%o0 - 1]
  929. 43:
  930. SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
  931. SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
  932. SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
  933. SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
  934. subcc %o3, 64, %o3
  935. add %o1, 64, %o1
  936. bne 43b
  937.  add %o0, 64, %o0
  938. andcc %o2, 0x30, %o3
  939. be,a 1f
  940.  srl %g1, 24, %g2
  941. 4:
  942. SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 24, 8, 3)
  943. subcc %o3, 16, %o3
  944. add %o1, 16, %o1
  945. bne 4b
  946.  add %o0, 16, %o0
  947. srl %g1, 24, %g2
  948. 1:
  949. stb %g2, [%o0 + 3]
  950. b 88f
  951.  add %o0, 4, %o0
  952. 42:
  953. SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
  954. SMOVE_ALIGNCHUNK(o1, o0, 0x10, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
  955. SMOVE_ALIGNCHUNK(o1, o0, 0x20, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
  956. SMOVE_ALIGNCHUNK(o1, o0, 0x30, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
  957. subcc %o3, 64, %o3
  958. add %o1, 64, %o1
  959. bne 42b
  960.  add %o0, 64, %o0
  961.  
  962. andcc %o2, 0x30, %o3
  963. be,a 1f
  964.  srl %g1, 16, %g2
  965. 4:
  966. SMOVE_ALIGNCHUNK(o1, o0, 0x00, g2, g3, g4, g5, o4, o5, g7, g1, 16, 16, -2)
  967. subcc %o3, 16, %o3
  968. add %o1, 16, %o1
  969. bne 4b
  970.  add %o0, 16, %o0
  971. srl %g1, 16, %g2
  972. 1:
  973. sth %g2, [%o0 - 2]
  974. /* Fall through */
  975.  
  976. #endif /* FASTER_NONALIGNED */
  977. 88: /* short_end */
  978. and %o2, 0xe, %o3
  979. 20:
  980. sethi %hi(89f), %o5
  981. sll %o3, 3, %o4
  982. add %o0, %o3, %o0
  983. sub %o5, %o4, %o5
  984. add %o1, %o3, %o1
  985. jmpl %o5 + %lo(89f), %g0
  986.  andcc %o2, 1, %g0
  987. MOVE_SHORTCHUNK(o1, o0, 0x0c, g2, g3)
  988. MOVE_SHORTCHUNK(o1, o0, 0x0a, g2, g3)
  989. MOVE_SHORTCHUNK(o1, o0, 0x08, g2, g3)
  990. MOVE_SHORTCHUNK(o1, o0, 0x06, g2, g3)
  991. MOVE_SHORTCHUNK(o1, o0, 0x04, g2, g3)
  992. MOVE_SHORTCHUNK(o1, o0, 0x02, g2, g3)
  993. MOVE_SHORTCHUNK(o1, o0, 0x00, g2, g3)
  994. 89: /* short_table_end */
  995. be 1f
  996.  nop
  997. ldub [%o1], %g2
  998. stb %g2, [%o0]
  999. 1:
  1000. retl
  1001.    RETL_INSN
  1002. 90: /* short_aligned_end */
  1003. bne 88b
  1004.  andcc %o2, 8, %g0
  1005. be 1f
  1006.  andcc %o2, 4, %g0
  1007. ld [%o1 + 0x00], %g2
  1008. ld [%o1 + 0x04], %g3
  1009. add %o1, 8, %o1
  1010. st %g2, [%o0 + 0x00]
  1011. st %g3, [%o0 + 0x04]
  1012. add %o0, 8, %o0
  1013. 1:
  1014. b 81b
  1015.  mov %o2, %g1