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

source code of linux/arch/sh/lib/memmove.S