diff options
Diffstat (limited to 'arch/sh/lib/memcpy.S')
-rw-r--r-- | arch/sh/lib/memcpy.S | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/arch/sh/lib/memcpy.S b/arch/sh/lib/memcpy.S new file mode 100644 index 000000000000..232fab34c261 --- /dev/null +++ b/arch/sh/lib/memcpy.S | |||
@@ -0,0 +1,227 @@ | |||
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 | ||