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