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