188 vst1.16 { d28, d29 }, [r0] |
188 vst1.16 { d28, d29 }, [r0] |
189 |
189 |
190 bx lr |
190 bx lr |
191 |
191 |
192 .endfunc |
192 .endfunc |
|
193 |
|
194 /* void qt_rotate90_16_neon(quint16 *dst, const quint16 *src, int sstride, int dstride, int count) */ |
|
195 .func qt_rotate90_16_neon |
|
196 .global qt_rotate90_16_neon |
|
197 /* For ELF format also set function visibility to hidden */ |
|
198 #ifdef __ELF__ |
|
199 .hidden qt_rotate90_16_neon |
|
200 .type qt_rotate90_16_neon, %function |
|
201 #endif |
|
202 qt_rotate90_16_neon: |
|
203 push { r4-r11, lr } |
|
204 ldr r5, [sp, #(9*4)] |
|
205 |
|
206 /* The preloads are the key to getting good performance */ |
|
207 pld [r1] |
|
208 |
|
209 mov r4, r5, asr #2 |
|
210 add r6, r0, r3 |
|
211 add r7, r6, r3 |
|
212 |
|
213 add r8, r7, r3 |
|
214 add r9, r8, r3 |
|
215 |
|
216 pld [r1, r2] |
|
217 |
|
218 add r10, r9, r3 |
|
219 add r11, r10, r3 |
|
220 |
|
221 add r3, r3, r11 |
|
222 and r5, r5, #3 |
|
223 |
|
224 pld [r1, r2, lsl #1] |
|
225 |
|
226 cmp r4, #0 |
|
227 beq .rotate90_16_tail |
|
228 |
|
229 .rotate90_16_loop: |
|
230 vld1.16 { q8 }, [r1], r2 |
|
231 |
|
232 pld [r1, r2, lsl #1] |
|
233 |
|
234 vld1.16 { q9 }, [r1], r2 |
|
235 vld1.16 { q10 }, [r1], r2 |
|
236 vld1.16 { q11 }, [r1], r2 |
|
237 |
|
238 pld [r1] |
|
239 |
|
240 /* Could have used four quad-word zips instead, |
|
241 but those take three cycles as opposed to one. */ |
|
242 vzip.16 d16, d20 |
|
243 vzip.16 d17, d21 |
|
244 |
|
245 vzip.16 d18, d22 |
|
246 |
|
247 pld [r1, r2] |
|
248 |
|
249 vzip.16 d19, d23 |
|
250 |
|
251 vzip.16 d16, d18 |
|
252 vzip.16 d17, d19 |
|
253 |
|
254 pld [r1, r2, lsl #1] |
|
255 |
|
256 vzip.16 d20, d22 |
|
257 vzip.16 d21, d23 |
|
258 |
|
259 vst1.16 { d23 }, [r0]! |
|
260 vst1.16 { d21 }, [r6]! |
|
261 vst1.16 { d19 }, [r7]! |
|
262 vst1.16 { d17 }, [r8]! |
|
263 vst1.16 { d22 }, [r9]! |
|
264 vst1.16 { d20 }, [r10]! |
|
265 vst1.16 { d18 }, [r11]! |
|
266 vst1.16 { d16 }, [r3]! |
|
267 |
|
268 sub r4, r4, #1 |
|
269 cmp r4, #0 |
|
270 bne .rotate90_16_loop |
|
271 b .rotate90_16_tail |
|
272 |
|
273 .rotate90_16_tail_loop: |
|
274 sub r5, r5, #2 |
|
275 |
|
276 vld1.16 { q8 }, [r1], r2 |
|
277 vld1.16 { q9 }, [r1], r2 |
|
278 |
|
279 vzip.16 d16, d18 |
|
280 vzip.16 d17, d19 |
|
281 |
|
282 vst1.32 { d19[1] }, [r0]! |
|
283 vst1.32 { d19[0] }, [r6]! |
|
284 vst1.32 { d17[1] }, [r7]! |
|
285 vst1.32 { d17[0] }, [r8]! |
|
286 vst1.32 { d18[1] }, [r9]! |
|
287 vst1.32 { d18[0] }, [r10]! |
|
288 vst1.32 { d16[1] }, [r11]! |
|
289 vst1.32 { d16[0] }, [r3]! |
|
290 |
|
291 .rotate90_16_tail: |
|
292 cmp r5, #0 |
|
293 bgt .rotate90_16_tail_loop |
|
294 |
|
295 pop { r4-r11, pc } |
|
296 |
|
297 .endfunc |