]> git.ipfire.org Git - thirdparty/kernel/linux.git/blame - arch/metag/lib/memmove.S
License cleanup: add SPDX GPL-2.0 license identifier to files with no license
[thirdparty/kernel/linux.git] / arch / metag / lib / memmove.S
CommitLineData
b2441318 1! SPDX-License-Identifier: GPL-2.0
086e9dc0
JH
2! Copyright (C) 2008-2012 Imagination Technologies Ltd.
3
4 .text
5 .global _memmove
6 .type _memmove,function
7! D1Ar1 dst
8! D0Ar2 src
9! D1Ar3 cnt
10! D0Re0 dst
11_memmove:
12 CMP D1Ar3, #0
13 MOV D0Re0, D1Ar1
14 BZ $LEND2
15 MSETL [A0StP], D0.5, D0.6, D0.7
16 MOV D1Ar5, D0Ar2
17 CMP D1Ar1, D1Ar5
18 BLT $Lforwards_copy
19 SUB D0Ar4, D1Ar1, D1Ar3
20 ADD D0Ar4, D0Ar4, #1
21 CMP D0Ar2, D0Ar4
22 BLT $Lforwards_copy
23 ! should copy backwards
24 MOV D1Re0, D0Ar2
25 ! adjust pointer to the end of mem
26 ADD D0Ar2, D1Re0, D1Ar3
27 ADD D1Ar1, D1Ar1, D1Ar3
28
29 MOV A1.2, D0Ar2
30 MOV A0.2, D1Ar1
31 CMP D1Ar3, #8
32 BLT $Lbbyte_loop
33
34 MOV D0Ar4, D0Ar2
35 MOV D1Ar5, D1Ar1
36
37 ! test 8 byte alignment
38 ANDS D1Ar5, D1Ar5, #7
39 BNE $Lbdest_unaligned
40
41 ANDS D0Ar4, D0Ar4, #7
42 BNE $Lbsrc_unaligned
43
44 LSR D1Ar5, D1Ar3, #3
45
46$Lbaligned_loop:
47 GETL D0Re0, D1Re0, [--A1.2]
48 SETL [--A0.2], D0Re0, D1Re0
49 SUBS D1Ar5, D1Ar5, #1
50 BNE $Lbaligned_loop
51
52 ANDS D1Ar3, D1Ar3, #7
53 BZ $Lbbyte_loop_exit
54$Lbbyte_loop:
55 GETB D1Re0, [--A1.2]
56 SETB [--A0.2], D1Re0
57 SUBS D1Ar3, D1Ar3, #1
58 BNE $Lbbyte_loop
59$Lbbyte_loop_exit:
60 MOV D0Re0, A0.2
61$LEND:
62 SUB A0.2, A0StP, #24
63 MGETL D0.5, D0.6, D0.7, [A0.2]
64 SUB A0StP, A0StP, #24
65$LEND2:
66 MOV PC, D1RtP
67
68$Lbdest_unaligned:
69 GETB D0Re0, [--A1.2]
70 SETB [--A0.2], D0Re0
71 SUBS D1Ar5, D1Ar5, #1
72 SUB D1Ar3, D1Ar3, #1
73 BNE $Lbdest_unaligned
74 CMP D1Ar3, #8
75 BLT $Lbbyte_loop
76$Lbsrc_unaligned:
77 LSR D1Ar5, D1Ar3, #3
78 ! adjust A1.2
79 MOV D0Ar4, A1.2
80 ! save original address
81 MOV D0Ar6, A1.2
82
83 ADD D0Ar4, D0Ar4, #7
84 ANDMB D0Ar4, D0Ar4, #0xfff8
85 ! new address is the 8-byte aligned one above the original
86 MOV A1.2, D0Ar4
87
88 ! A0.2 dst 64-bit is aligned
89 ! measure the gap size
90 SUB D0Ar6, D0Ar4, D0Ar6
91 MOVS D0Ar4, D0Ar6
92 ! keep this information for the later adjustment
93 ! both aligned
94 BZ $Lbaligned_loop
95
96 ! prefetch
97 GETL D0Re0, D1Re0, [--A1.2]
98
99 CMP D0Ar6, #4
100 BLT $Lbunaligned_1_2_3
101 ! 32-bit aligned
102 BZ $Lbaligned_4
103
104 SUB D0Ar6, D0Ar6, #4
105 ! D1.6 stores the gap size in bits
106 MULW D1.6, D0Ar6, #8
107 MOV D0.6, #32
108 ! D0.6 stores the complement of the gap size
109 SUB D0.6, D0.6, D1.6
110
111$Lbunaligned_5_6_7:
112 GETL D0.7, D1.7, [--A1.2]
113 ! form 64-bit data in D0Re0, D1Re0
114 MOV D1Re0, D0Re0
115 ! D1Re0 << gap-size
116 LSL D1Re0, D1Re0, D1.6
117 MOV D0Re0, D1.7
118 ! D0Re0 >> complement
119 LSR D0Re0, D0Re0, D0.6
120 MOV D1.5, D0Re0
121 ! combine the both
122 ADD D1Re0, D1Re0, D1.5
123
124 MOV D1.5, D1.7
125 LSL D1.5, D1.5, D1.6
126 MOV D0Re0, D0.7
127 LSR D0Re0, D0Re0, D0.6
128 MOV D0.5, D1.5
129 ADD D0Re0, D0Re0, D0.5
130
131 SETL [--A0.2], D0Re0, D1Re0
132 MOV D0Re0, D0.7
133 MOV D1Re0, D1.7
134 SUBS D1Ar5, D1Ar5, #1
135 BNE $Lbunaligned_5_6_7
136
137 ANDS D1Ar3, D1Ar3, #7
138 BZ $Lbbyte_loop_exit
139 ! Adjust A1.2
140 ! A1.2 <- A1.2 +8 - gapsize
141 ADD A1.2, A1.2, #8
142 SUB A1.2, A1.2, D0Ar4
143 B $Lbbyte_loop
144
145$Lbunaligned_1_2_3:
146 MULW D1.6, D0Ar6, #8
147 MOV D0.6, #32
148 SUB D0.6, D0.6, D1.6
149
150$Lbunaligned_1_2_3_loop:
151 GETL D0.7, D1.7, [--A1.2]
152 ! form 64-bit data in D0Re0, D1Re0
153 LSL D1Re0, D1Re0, D1.6
154 ! save D0Re0 for later use
155 MOV D0.5, D0Re0
156 LSR D0Re0, D0Re0, D0.6
157 MOV D1.5, D0Re0
158 ADD D1Re0, D1Re0, D1.5
159
160 ! orignal data in D0Re0
161 MOV D1.5, D0.5
162 LSL D1.5, D1.5, D1.6
163 MOV D0Re0, D1.7
164 LSR D0Re0, D0Re0, D0.6
165 MOV D0.5, D1.5
166 ADD D0Re0, D0Re0, D0.5
167
168 SETL [--A0.2], D0Re0, D1Re0
169 MOV D0Re0, D0.7
170 MOV D1Re0, D1.7
171 SUBS D1Ar5, D1Ar5, #1
172 BNE $Lbunaligned_1_2_3_loop
173
174 ANDS D1Ar3, D1Ar3, #7
175 BZ $Lbbyte_loop_exit
176 ! Adjust A1.2
177 ADD A1.2, A1.2, #8
178 SUB A1.2, A1.2, D0Ar4
179 B $Lbbyte_loop
180
181$Lbaligned_4:
182 GETL D0.7, D1.7, [--A1.2]
183 MOV D1Re0, D0Re0
184 MOV D0Re0, D1.7
185 SETL [--A0.2], D0Re0, D1Re0
186 MOV D0Re0, D0.7
187 MOV D1Re0, D1.7
188 SUBS D1Ar5, D1Ar5, #1
189 BNE $Lbaligned_4
190 ANDS D1Ar3, D1Ar3, #7
191 BZ $Lbbyte_loop_exit
192 ! Adjust A1.2
193 ADD A1.2, A1.2, #8
194 SUB A1.2, A1.2, D0Ar4
195 B $Lbbyte_loop
196
197$Lforwards_copy:
198 MOV A1.2, D0Ar2
199 MOV A0.2, D1Ar1
200 CMP D1Ar3, #8
201 BLT $Lfbyte_loop
202
203 MOV D0Ar4, D0Ar2
204 MOV D1Ar5, D1Ar1
205
206 ANDS D1Ar5, D1Ar5, #7
207 BNE $Lfdest_unaligned
208
209 ANDS D0Ar4, D0Ar4, #7
210 BNE $Lfsrc_unaligned
211
212 LSR D1Ar5, D1Ar3, #3
213
214$Lfaligned_loop:
215 GETL D0Re0, D1Re0, [A1.2++]
216 SUBS D1Ar5, D1Ar5, #1
217 SETL [A0.2++], D0Re0, D1Re0
218 BNE $Lfaligned_loop
219
220 ANDS D1Ar3, D1Ar3, #7
221 BZ $Lfbyte_loop_exit
222$Lfbyte_loop:
223 GETB D1Re0, [A1.2++]
224 SETB [A0.2++], D1Re0
225 SUBS D1Ar3, D1Ar3, #1
226 BNE $Lfbyte_loop
227$Lfbyte_loop_exit:
228 MOV D0Re0, D1Ar1
229 B $LEND
230
231$Lfdest_unaligned:
232 GETB D0Re0, [A1.2++]
233 ADD D1Ar5, D1Ar5, #1
234 SUB D1Ar3, D1Ar3, #1
235 SETB [A0.2++], D0Re0
236 CMP D1Ar5, #8
237 BNE $Lfdest_unaligned
238 CMP D1Ar3, #8
239 BLT $Lfbyte_loop
240$Lfsrc_unaligned:
241 ! adjust A1.2
242 LSR D1Ar5, D1Ar3, #3
243
244 MOV D0Ar4, A1.2
245 MOV D0Ar6, A1.2
246 ANDMB D0Ar4, D0Ar4, #0xfff8
247 MOV A1.2, D0Ar4
248
249 ! A0.2 dst 64-bit is aligned
250 SUB D0Ar6, D0Ar6, D0Ar4
251 ! keep the information for the later adjustment
252 MOVS D0Ar4, D0Ar6
253
254 ! both aligned
255 BZ $Lfaligned_loop
256
257 ! prefetch
258 GETL D0Re0, D1Re0, [A1.2]
259
260 CMP D0Ar6, #4
261 BLT $Lfunaligned_1_2_3
262 BZ $Lfaligned_4
263
264 SUB D0Ar6, D0Ar6, #4
265 MULW D0.6, D0Ar6, #8
266 MOV D1.6, #32
267 SUB D1.6, D1.6, D0.6
268
269$Lfunaligned_5_6_7:
270 GETL D0.7, D1.7, [++A1.2]
271 ! form 64-bit data in D0Re0, D1Re0
272 MOV D0Re0, D1Re0
273 LSR D0Re0, D0Re0, D0.6
274 MOV D1Re0, D0.7
275 LSL D1Re0, D1Re0, D1.6
276 MOV D0.5, D1Re0
277 ADD D0Re0, D0Re0, D0.5
278
279 MOV D0.5, D0.7
280 LSR D0.5, D0.5, D0.6
281 MOV D1Re0, D1.7
282 LSL D1Re0, D1Re0, D1.6
283 MOV D1.5, D0.5
284 ADD D1Re0, D1Re0, D1.5
285
286 SETL [A0.2++], D0Re0, D1Re0
287 MOV D0Re0, D0.7
288 MOV D1Re0, D1.7
289 SUBS D1Ar5, D1Ar5, #1
290 BNE $Lfunaligned_5_6_7
291
292 ANDS D1Ar3, D1Ar3, #7
293 BZ $Lfbyte_loop_exit
294 ! Adjust A1.2
295 ADD A1.2, A1.2, D0Ar4
296 B $Lfbyte_loop
297
298$Lfunaligned_1_2_3:
299 MULW D0.6, D0Ar6, #8
300 MOV D1.6, #32
301 SUB D1.6, D1.6, D0.6
302
303$Lfunaligned_1_2_3_loop:
304 GETL D0.7, D1.7, [++A1.2]
305 ! form 64-bit data in D0Re0, D1Re0
306 LSR D0Re0, D0Re0, D0.6
307 MOV D1.5, D1Re0
308 LSL D1Re0, D1Re0, D1.6
309 MOV D0.5, D1Re0
310 ADD D0Re0, D0Re0, D0.5
311
312 MOV D0.5, D1.5
313 LSR D0.5, D0.5, D0.6
314 MOV D1Re0, D0.7
315 LSL D1Re0, D1Re0, D1.6
316 MOV D1.5, D0.5
317 ADD D1Re0, D1Re0, D1.5
318
319 SETL [A0.2++], D0Re0, D1Re0
320 MOV D0Re0, D0.7
321 MOV D1Re0, D1.7
322 SUBS D1Ar5, D1Ar5, #1
323 BNE $Lfunaligned_1_2_3_loop
324
325 ANDS D1Ar3, D1Ar3, #7
326 BZ $Lfbyte_loop_exit
327 ! Adjust A1.2
328 ADD A1.2, A1.2, D0Ar4
329 B $Lfbyte_loop
330
331$Lfaligned_4:
332 GETL D0.7, D1.7, [++A1.2]
333 MOV D0Re0, D1Re0
334 MOV D1Re0, D0.7
335 SETL [A0.2++], D0Re0, D1Re0
336 MOV D0Re0, D0.7
337 MOV D1Re0, D1.7
338 SUBS D1Ar5, D1Ar5, #1
339 BNE $Lfaligned_4
340 ANDS D1Ar3, D1Ar3, #7
341 BZ $Lfbyte_loop_exit
342 ! Adjust A1.2
343 ADD A1.2, A1.2, D0Ar4
344 B $Lfbyte_loop
345
346 .size _memmove,.-_memmove