memcpy.S 3.6 KB

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