memmove.S 3.9 KB

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