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