memcpy.S 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. /* $Id: memcpy.S,v 1.3 2001/07/27 11:50:52 gniibe Exp $
  2. *
  3. * "memcpy" implementation of SuperH
  4. *
  5. * Copyright (C) 1999 Niibe Yutaka
  6. *
  7. */
  8. /*
  9. * void *memcpy(void *dst, const void *src, size_t n);
  10. * No overlap between the memory of DST and of SRC are assumed.
  11. */
  12. #include <linux/linkage.h>
  13. ENTRY(memcpy)
  14. tst r6,r6
  15. bt/s 9f ! if n=0, do nothing
  16. mov r4,r0
  17. sub r4,r5 ! From here, r5 has the distance to r0
  18. add r6,r0 ! From here, r0 points the end of copying point
  19. mov #12,r1
  20. cmp/gt r6,r1
  21. bt/s 7f ! if it's too small, copy a byte at once
  22. add #-1,r5
  23. add #1,r5
  24. ! From here, r6 is free
  25. !
  26. ! r4 --> [ ... ] DST [ ... ] SRC
  27. ! [ ... ] [ ... ]
  28. ! : :
  29. ! r0 --> [ ... ] r0+r5 --> [ ... ]
  30. !
  31. !
  32. mov r5,r1
  33. mov #3,r2
  34. and r2,r1
  35. shll2 r1
  36. mov r0,r3 ! Save the value on R0 to R3
  37. mova jmptable,r0
  38. add r1,r0
  39. mov.l @r0,r1
  40. jmp @r1
  41. mov r3,r0 ! and back to R0
  42. .balign 4
  43. jmptable:
  44. .long case0
  45. .long case1
  46. .long case2
  47. .long case3
  48. ! copy a byte at once
  49. 7: mov r4,r2
  50. add #1,r2
  51. 8:
  52. cmp/hi r2,r0
  53. mov.b @(r0,r5),r1
  54. bt/s 8b ! while (r0>r2)
  55. mov.b r1,@-r0
  56. 9:
  57. rts
  58. nop
  59. case0:
  60. !
  61. ! GHIJ KLMN OPQR --> GHIJ KLMN OPQR
  62. !
  63. ! First, align to long word boundary
  64. mov r0,r3
  65. and r2,r3
  66. tst r3,r3
  67. bt/s 2f
  68. add #-4,r5
  69. add #3,r5
  70. 1: dt r3
  71. mov.b @(r0,r5),r1
  72. bf/s 1b
  73. mov.b r1,@-r0
  74. !
  75. add #-3,r5
  76. 2: ! Second, copy a long word at once
  77. mov r4,r2
  78. add #7,r2
  79. 3: mov.l @(r0,r5),r1
  80. cmp/hi r2,r0
  81. bt/s 3b
  82. mov.l r1,@-r0
  83. !
  84. ! Third, copy a byte at once, if necessary
  85. cmp/eq r4,r0
  86. bt/s 9b
  87. add #3,r5
  88. bra 8b
  89. add #-6,r2
  90. case1:
  91. !
  92. ! GHIJ KLMN OPQR --> ...G HIJK LMNO PQR.
  93. !
  94. ! First, align to long word boundary
  95. mov r0,r3
  96. and r2,r3
  97. tst r3,r3
  98. bt/s 2f
  99. add #-1,r5
  100. 1: dt r3
  101. mov.b @(r0,r5),r1
  102. bf/s 1b
  103. mov.b r1,@-r0
  104. !
  105. 2: ! Second, read a long word and write a long word at once
  106. mov.l @(r0,r5),r1
  107. add #-4,r5
  108. mov r4,r2
  109. add #7,r2
  110. !
  111. #ifdef __LITTLE_ENDIAN__
  112. 3: mov r1,r3 ! RQPO
  113. shll16 r3
  114. shll8 r3 ! Oxxx
  115. mov.l @(r0,r5),r1 ! NMLK
  116. mov r1,r6
  117. shlr8 r6 ! xNML
  118. or r6,r3 ! ONML
  119. cmp/hi r2,r0
  120. bt/s 3b
  121. mov.l r3,@-r0
  122. #else
  123. 3: mov r1,r3 ! OPQR
  124. shlr16 r3
  125. shlr8 r3 ! xxxO
  126. mov.l @(r0,r5),r1 ! KLMN
  127. mov r1,r6
  128. shll8 r6 ! LMNx
  129. or r6,r3 ! LMNO
  130. cmp/hi r2,r0
  131. bt/s 3b
  132. mov.l r3,@-r0
  133. #endif
  134. !
  135. ! Third, copy a byte at once, if necessary
  136. cmp/eq r4,r0
  137. bt/s 9b
  138. add #4,r5
  139. bra 8b
  140. add #-6,r2
  141. case2:
  142. !
  143. ! GHIJ KLMN OPQR --> ..GH IJKL MNOP QR..
  144. !
  145. ! First, align to word boundary
  146. tst #1,r0
  147. bt/s 2f
  148. add #-1,r5
  149. mov.b @(r0,r5),r1
  150. mov.b r1,@-r0
  151. !
  152. 2: ! Second, read a word and write a word at once
  153. add #-1,r5
  154. mov r4,r2
  155. add #3,r2
  156. !
  157. 3: mov.w @(r0,r5),r1
  158. cmp/hi r2,r0
  159. bt/s 3b
  160. mov.w r1,@-r0
  161. !
  162. ! Third, copy a byte at once, if necessary
  163. cmp/eq r4,r0
  164. bt/s 9b
  165. add #1,r5
  166. mov.b @(r0,r5),r1
  167. rts
  168. mov.b r1,@-r0
  169. case3:
  170. !
  171. ! GHIJ KLMN OPQR --> .GHI JKLM NOPQ R...
  172. !
  173. ! First, align to long word boundary
  174. mov r0,r3
  175. and r2,r3
  176. tst r3,r3
  177. bt/s 2f
  178. add #-1,r5
  179. 1: dt r3
  180. mov.b @(r0,r5),r1
  181. bf/s 1b
  182. mov.b r1,@-r0
  183. !
  184. 2: ! Second, read a long word and write a long word at once
  185. add #-2,r5
  186. mov.l @(r0,r5),r1
  187. add #-4,r5
  188. mov r4,r2
  189. add #7,r2
  190. !
  191. #ifdef __LITTLE_ENDIAN__
  192. 3: mov r1,r3 ! RQPO
  193. shll8 r3 ! QPOx
  194. mov.l @(r0,r5),r1 ! NMLK
  195. mov r1,r6
  196. shlr16 r6
  197. shlr8 r6 ! xxxN
  198. or r6,r3 ! QPON
  199. cmp/hi r2,r0
  200. bt/s 3b
  201. mov.l r3,@-r0
  202. #else
  203. 3: mov r1,r3 ! OPQR
  204. shlr8 r3 ! xOPQ
  205. mov.l @(r0,r5),r1 ! KLMN
  206. mov r1,r6
  207. shll16 r6
  208. shll8 r6 ! Nxxx
  209. or r6,r3 ! NOPQ
  210. cmp/hi r2,r0
  211. bt/s 3b
  212. mov.l r3,@-r0
  213. #endif
  214. !
  215. ! Third, copy a byte at once, if necessary
  216. cmp/eq r4,r0
  217. bt/s 9b
  218. add #6,r5
  219. bra 8b
  220. add #-6,r2