Commit | Line | Data |
---|---|---|
b2441318 | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
1da177e4 LT |
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> | |
16 | ENTRY(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 | |
24 | 2: .long memcpy | |
25 | 1: | |
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 | |
56 | jmptable: | |
57 | .long case0 | |
58 | .long case1 | |
59 | .long case2 | |
60 | .long case3 | |
61 | ||
62 | ! copy a byte at once | |
63 | 8: 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 | |
68 | 9: | |
69 | add r4,r0 | |
70 | rts | |
71 | sub r6,r0 | |
72 | ||
73 | case_none: | |
74 | bra 8b | |
75 | add #-1,r4 | |
76 | ||
77 | case0: | |
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 | |
89 | 1: dt r2 | |
90 | mov.b @r0+,r1 | |
91 | bf/s 1b | |
92 | mov.b r1,@(r0,r4) | |
93 | ! | |
94 | 2: ! Second, copy a long word at once | |
95 | add #-3,r4 | |
96 | add #-3,r5 | |
97 | 3: 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 | ||
110 | case3: | |
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 | |
122 | 1: dt r2 | |
123 | mov.b @r0+,r1 | |
124 | bf/s 1b | |
125 | mov.b r1,@(r0,r4) | |
126 | ! | |
127 | 2: ! 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 | |
135 | 3: 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 | |
147 | 3: 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 | ||
168 | case2: | |
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 | ! | |
179 | 2: ! Second, read a word and write a word at once | |
180 | add #-1,r4 | |
181 | add #-1,r5 | |
182 | ! | |
183 | 3: 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 | ||
198 | case1: | |
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 | |
210 | 1: dt r2 | |
211 | mov.b @r0+,r1 | |
212 | bf/s 1b | |
213 | mov.b r1,@(r0,r4) | |
214 | ! | |
215 | 2: ! 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 | |
223 | 3: 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 | |
236 | 3: 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 |