1@/******************************************************************************
2@ *
3@ * Copyright (C) 2015 The Android Open Source Project
4@ *
5@ * Licensed under the Apache License, Version 2.0 (the "License");
6@ * you may not use this file except in compliance with the License.
7@ * You may obtain a copy of the License at:
8@ *
9@ * http://www.apache.org/licenses/LICENSE-2.0
10@ *
11@ * Unless required by applicable law or agreed to in writing, software
12@ * distributed under the License is distributed on an "AS IS" BASIS,
13@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14@ * See the License for the specific language governing permissions and
15@ * limitations under the License.
16@ *
17@ *****************************************************************************
18@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19@*/
20@**
21@******************************************************************************
22@* @file
23@*  ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q.s
24@*
25@* @brief
26@*  Contains function definitions for inter prediction  interpolation.
27@*
28@* @author
29@*  Mohit
30@*
31@* @par List of Functions:
32@*
33@*  - ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q()
34@*
35@* @remarks
36@*  None
37@*
38@*******************************************************************************
39@*
40
41@* All the functions here are replicated from ih264_inter_pred_filters.c
42@
43
44@**
45@**
46@**
47@*******************************************************************************
48@*
49@* @brief
50@*   This function implements a two stage cascaded six tap filter. It
51@*    applies the six tap filter in the horizontal direction on the
52@*    predictor values, followed by applying the same filter in the
53@*    vertical direction on the output of the first stage. It then averages
54@*    the output of the 1st stage and the output of the 2nd stage to obtain
55@*    the quarter pel values. The six tap filtering operation is described
56@*    in sec 8.4.2.2.1 titled "Luma sample interpolation process".
57@*
58@* @par Description:
59@*     This function is called to obtain pixels lying at the following
60@*    location (1/2,1/4) or (1/2,3/4). The function interpolates
61@*    the predictors first in the horizontal direction and then in the
62@*    vertical direction to output the (1/2,1/2). It then averages
63@*    the output of the 2nd stage and (1/2,1/2) value to obtain (1/2,1/4)
64@*    or (1/2,3/4) depending on the offset.
65@*
66@* @param[in] pu1_src
67@*  UWORD8 pointer to the source
68@*
69@* @param[out] pu1_dst
70@*  UWORD8 pointer to the destination
71@*
72@* @param[in] src_strd
73@*  integer source stride
74@*
75@* @param[in] dst_strd
76@*  integer destination stride
77@*
78@* @param[in] ht
79@*  integer height of the array
80@*
81@* @param[in] wd
82@*  integer width of the array
83@*
84@* @param[in] pu1_tmp: temporary buffer
85@*
86@* @param[in] dydx: x and y reference offset for qpel calculations
87@*
88@* @returns
89@*
90@* @remarks
91@*  None
92@*
93@*******************************************************************************
94@*;
95
96@void ih264_inter_pred_luma_horz_hpel_vert_qpel(UWORD8 *pu1_src,
97@                                UWORD8 *pu1_dst,
98@                                WORD32 src_strd,,
99@                                WORD32 dst_strd,
100@                                WORD32 ht,
101@                                WORD32 wd,
102@                                UWORD8* pu1_tmp,
103@                                UWORD32 dydx)
104
105@**************Variables Vs Registers*****************************************
106@   r0 => *pu1_src
107@   r1 => *pu1_dst
108@   r2 =>  src_strd
109@   r3 =>  dst_strd
110@   r4 =>  ht
111@   r5 =>  wd
112@   r7 =>  dydx
113@   r9 => *pu1_tmp
114
115.text
116.p2align 2
117
118    .global ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q
119
120ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q:
121
122    stmfd         sp!, {r4-r12, r14}    @ store register values to stack
123    vstmdb        sp!, {d8-d15}         @push neon registers to stack
124    ldr           r4, [sp, #104]        @ loads ht
125    sub           r0, r0, r2, lsl #1    @ pu1_src-2*src_strd
126    sub           r0, r0, #2            @ pu1_src-2
127    ldr           r5, [sp, #108]        @ loads wd
128    ldr           r7, [sp, #116]        @ loads dydx
129    lsr           r7, r7, #3            @ dydx >> 2 followed by dydx & 0x3 and dydx>>1 to obtain the deciding bit
130    ldr           r9, [sp, #112]        @ pu1_tmp
131    add           r7, r7, #2
132    mov           r6, #48
133    mla           r7, r7, r6, r9
134
135    subs          r12, r5, #4           @if wd=4 branch to loop_4
136    beq           loop_4_start
137
138    subs          r12, r5, #8           @if wd=8 branch to loop_8
139    beq           loop_8_start
140
141    @when  wd=16
142    vmov.u16      q11, #20              @ Filter coeff 0x14 into Q11
143    vmov.u16      q12, #5               @ Filter coeff 0x5  into Q12
144    add           r8, r0, #8
145    add           r14, r1, #8
146    add           r10, r9, #8
147    mov           r12, r4
148    add           r11, r7, #8
149
150loop_16_lowhalf_start:
151    vld1.32       {q0}, [r0], r2        @ row -2 load for horizontal filter
152    vext.8        d5, d0, d1, #5
153    vaddl.u8      q3, d0, d5
154
155    vext.8        d2, d0, d1, #2
156    vext.8        d3, d0, d1, #3
157    vaddl.u8      q4, d2, d3
158    vext.8        d4, d0, d1, #4
159    vmla.u16      q3, q4, q11
160    vext.8        d1, d0, d1, #1
161    vaddl.u8      q4, d1, d4
162    vld1.32       {q0}, [r0], r2        @ row -1 load for horizontal filter
163    vmls.u16      q3, q4, q12
164    vext.8        d5, d0, d1, #5
165    vaddl.u8      q4, d0, d5
166    vext.8        d2, d0, d1, #2
167    vext.8        d3, d0, d1, #3
168    vaddl.u8      q5, d2, d3
169
170    vst1.32       {q3}, [r9], r6        @ store temp buffer 0
171
172    vext.8        d4, d0, d1, #4
173    vmla.u16      q4, q5, q11
174    vext.8        d1, d0, d1, #1
175    vaddl.u8      q5, d1, d4
176    vld1.32       {q0}, [r0], r2        @ row 0 load for horizontal filter
177    vmls.u16      q4, q5, q12
178    vext.8        d5, d0, d1, #5
179    vaddl.u8      q5, d0, d5
180    vext.8        d2, d0, d1, #2
181    vext.8        d3, d0, d1, #3
182    vaddl.u8      q6, d2, d3
183
184    vst1.32       {q4}, [r9], r6        @ store temp buffer 1
185
186    vext.8        d4, d0, d1, #4
187    vmla.u16      q5, q6, q11
188    vext.8        d1, d0, d1, #1
189    vaddl.u8      q6, d1, d4
190    vld1.32       {q0}, [r0], r2        @ row 1 load for horizontal filter
191    vmls.u16      q5, q6, q12
192    vext.8        d5, d0, d1, #5
193    vaddl.u8      q6, d0, d5
194    vext.8        d2, d0, d1, #2
195    vext.8        d3, d0, d1, #3
196    vaddl.u8      q7, d2, d3
197
198    vst1.32       {q5}, [r9], r6        @ store temp buffer 2
199
200    vext.8        d4, d0, d1, #4
201    vmla.u16      q6, q7, q11
202    vext.8        d1, d0, d1, #1
203    vaddl.u8      q7, d1, d4
204    vld1.32       {q0}, [r0], r2        @ row 2 load for horizontal filter
205    vmls.u16      q6, q7, q12
206    vext.8        d5, d0, d1, #5
207    vaddl.u8      q7, d0, d5
208    vext.8        d2, d0, d1, #2
209    vext.8        d3, d0, d1, #3
210    vaddl.u8      q8, d2, d3
211
212    vst1.32       {q6}, [r9], r6        @ store temp buffer 3
213
214    vext.8        d4, d0, d1, #4
215    vmla.u16      q7, q8, q11
216    vext.8        d1, d0, d1, #1
217    vaddl.u8      q8, d1, d4
218
219    vmls.u16      q7, q8, q12
220loop_16_lowhalf:
221
222    vld1.32       {q0}, [r0], r2        @ row 3 load for horizontal filter
223    vext.8        d5, d0, d1, #5
224    vext.8        d2, d0, d1, #2
225    vext.8        d3, d0, d1, #3
226    vaddl.u8      q8, d0, d5
227
228    vst1.32       {q7}, [r9], r6        @ store temp buffer 4
229    vaddl.u8      q9, d2, d3
230    vext.8        d4, d0, d1, #4
231    vmla.u16      q8, q9, q11
232    vext.8        d1, d0, d1, #1
233    vadd.s16      q14, q4, q7
234    vaddl.u8      q9, d1, d4
235    vadd.s16      q15, q5, q6
236    vmls.u16      q8, q9, q12
237    vld1.32       {q0}, [r0], r2        @ row 4 load for hoorizontal filter
238    vext.8        d5, d0, d1, #5
239    vext.8        d2, d0, d1, #2
240    vext.8        d3, d0, d1, #3
241    vaddl.u8      q10, d0, d5
242
243    vst1.32       {q8}, [r9], r6        @ store temp buffer r5
244
245    vaddl.s16     q9, d6, d16
246
247    vld1.32       {q13}, [r7], r6       @ load from temp buffer 0
248
249    vaddl.s16     q3, d7, d17
250
251    vqrshrun.s16  d26, q13, #5
252
253    vmlal.s16     q9, d30, d22
254    vmlsl.s16     q9, d28, d24
255    vmlal.s16     q3, d31, d22
256    vmlsl.s16     q3, d29, d24
257    vaddl.u8      q1, d2, d3
258    vext.8        d4, d0, d1, #4
259    vmla.u16      q10, q1, q11
260    vqrshrun.s32  d18, q9, #10
261    vext.8        d1, d0, d1, #1
262    vqrshrun.s32  d19, q3, #10
263    vadd.s16      q14, q5, q8
264    vaddl.u8      q1, d1, d4
265    vadd.s16      q15, q6, q7
266    vmls.u16      q10, q1, q12
267    vqmovn.u16    d18, q9
268    vld1.32       {q0}, [r0], r2        @ row 5 load for horizontal filter
269
270    vrhadd.u8     d26, d18, d26
271
272    vext.8        d5, d0, d1, #5
273    vext.8        d2, d0, d1, #2
274
275    vst1.32       {q10}, [r9], r6       @ store temp buffer r6
276
277    vaddl.s16     q9, d8, d20
278
279    vaddl.s16     q3, d9, d21
280
281    vld1.32       {q4}, [r7], r6        @load from temp buffer 1
282
283
284    vst1.32       d26, [r1], r3         @ store row 0
285
286    vmlal.s16     q9, d30, d22
287    vmlsl.s16     q9, d28, d24
288
289    vqrshrun.s16  d28, q4, #5
290
291    vmlal.s16     q3, d31, d22
292    vmlsl.s16     q3, d29, d24
293    vext.8        d3, d0, d1, #3
294    vaddl.u8      q4, d0, d5
295    vaddl.u8      q1, d2, d3
296    vqrshrun.s32  d18, q9, #10
297    vext.8        d4, d0, d1, #4
298    vqrshrun.s32  d19, q3, #10
299    vmla.u16      q4, q1, q11
300    vext.8        d1, d0, d1, #1
301    vadd.s16      q13, q6, q10
302    vaddl.u8      q1, d1, d4
303    vqmovn.u16    d18, q9
304    vadd.s16      q15, q7, q8
305    vmls.u16      q4, q1, q12
306    vld1.32       {q0}, [r0], r2        @ row 6 load for horizontal filter
307
308    vrhadd.u8     d28, d28, d18
309
310    vext.8        d5, d0, d1, #5
311    vext.8        d2, d0, d1, #2
312    vext.8        d3, d0, d1, #3
313
314    vst1.32       d28, [r1], r3         @ store row 1
315
316    vaddl.u8      q14, d0, d5
317
318    vst1.32       {q4}, [r9], r6        @ store temp buffer r7
319
320    vaddl.s16     q9, d10, d8
321    vaddl.s16     q3, d11, d9
322
323    vld1.32       {q5}, [r7], r6        @ load from temp buffer 2
324
325    vmlal.s16     q9, d30, d22
326    vmlsl.s16     q9, d26, d24
327    vmlal.s16     q3, d31, d22
328
329    vqrshrun.s16  d26, q5, #5
330
331    vmlsl.s16     q3, d27, d24
332    vaddl.u8      q1, d2, d3
333    vext.8        d4, d0, d1, #4
334    vmla.u16      q14, q1, q11
335    vqrshrun.s32  d18, q9, #10
336    vext.8        d1, d0, d1, #1
337    vqrshrun.s32  d19, q3, #10
338    vadd.s16      q5, q7, q4
339    vaddl.u8      q1, d1, d4
340    vadd.s16      q15, q8, q10
341    vmls.u16      q14, q1, q12
342    vqmovn.u16    d27, q9
343
344    vaddl.s16     q9, d12, d28
345    vaddl.s16     q3, d13, d29
346
347    vrhadd.u8     d26, d26, d27
348
349    vmlal.s16     q9, d30, d22
350    vmlsl.s16     q9, d10, d24
351    vmlal.s16     q3, d31, d22
352    vmlsl.s16     q3, d11, d24
353
354    vst1.32       d26, [r1], r3         @ store row 2
355
356    vst1.32       {q14}, [r9]
357
358
359    vqrshrun.s32  d18, q9, #10
360    vmov          q5, q10
361    vld1.32       {q15}, [r7], r6       @ load from temp buffer 3
362
363    vqrshrun.s32  d19, q3, #10
364    subs          r4, r4, #4
365
366    vqrshrun.s16  d30, q15, #5
367
368    vqmovn.u16    d18, q9
369    vmov          q6, q4
370    vmov          q3, q7
371    vrhadd.u8     d30, d18, d30
372    vmov          q4, q8
373    vmov          q7, q14
374    vst1.32       d30, [r1], r3         @ store row 3
375
376    bgt           loop_16_lowhalf       @ looping if height =16
377
378
379loop_16_highhalf_start:
380    vld1.32       {q0}, [r8], r2
381    vext.8        d5, d0, d1, #5
382    vaddl.u8      q3, d0, d5
383    vext.8        d2, d0, d1, #2
384    vext.8        d3, d0, d1, #3
385    vaddl.u8      q4, d2, d3
386    vext.8        d4, d0, d1, #4
387    vmla.u16      q3, q4, q11
388    vext.8        d1, d0, d1, #1
389    vaddl.u8      q4, d1, d4
390    vld1.32       {q0}, [r8], r2
391    vmls.u16      q3, q4, q12
392    vext.8        d5, d0, d1, #5
393    vaddl.u8      q4, d0, d5
394    vext.8        d2, d0, d1, #2
395    vext.8        d3, d0, d1, #3
396    vaddl.u8      q5, d2, d3
397
398    vst1.32       {q3}, [r10], r6
399
400    vext.8        d4, d0, d1, #4
401    vmla.u16      q4, q5, q11
402    vext.8        d1, d0, d1, #1
403    vaddl.u8      q5, d1, d4
404    vld1.32       {q0}, [r8], r2
405    vmls.u16      q4, q5, q12
406    vext.8        d5, d0, d1, #5
407    vaddl.u8      q5, d0, d5
408    vext.8        d2, d0, d1, #2
409    vext.8        d3, d0, d1, #3
410    vaddl.u8      q6, d2, d3
411
412    vst1.32       {q4}, [r10], r6
413
414    vext.8        d4, d0, d1, #4
415    vmla.u16      q5, q6, q11
416    vext.8        d1, d0, d1, #1
417    vaddl.u8      q6, d1, d4
418    vld1.32       {q0}, [r8], r2
419    vmls.u16      q5, q6, q12
420    vext.8        d5, d0, d1, #5
421    vaddl.u8      q6, d0, d5
422    vext.8        d2, d0, d1, #2
423    vext.8        d3, d0, d1, #3
424    vaddl.u8      q7, d2, d3
425
426    vst1.32       {q5}, [r10], r6
427
428    vext.8        d4, d0, d1, #4
429    vmla.u16      q6, q7, q11
430    vext.8        d1, d0, d1, #1
431    vaddl.u8      q7, d1, d4
432    vld1.32       {q0}, [r8], r2
433    vmls.u16      q6, q7, q12
434    vext.8        d5, d0, d1, #5
435    vaddl.u8      q7, d0, d5
436    vext.8        d2, d0, d1, #2
437    vext.8        d3, d0, d1, #3
438    vaddl.u8      q8, d2, d3
439
440    vst1.32       {q6}, [r10], r6
441
442    vext.8        d4, d0, d1, #4
443    vmla.u16      q7, q8, q11
444    vext.8        d1, d0, d1, #1
445    vaddl.u8      q8, d1, d4
446
447    vmls.u16      q7, q8, q12
448
449loop_16_highhalf:
450
451    vld1.32       {q0}, [r8], r2
452    vext.8        d5, d0, d1, #5
453    vext.8        d2, d0, d1, #2
454    vext.8        d3, d0, d1, #3
455    vaddl.u8      q8, d0, d5
456
457    vst1.32       {q7}, [r10], r6
458
459    vaddl.u8      q9, d2, d3
460    vext.8        d4, d0, d1, #4
461    vmla.u16      q8, q9, q11
462    vext.8        d1, d0, d1, #1
463    vadd.s16      q14, q4, q7
464    vaddl.u8      q9, d1, d4
465    vadd.s16      q15, q5, q6
466    vmls.u16      q8, q9, q12
467    vld1.32       {q0}, [r8], r2
468    vext.8        d5, d0, d1, #5
469    vext.8        d2, d0, d1, #2
470    vext.8        d3, d0, d1, #3
471    vaddl.u8      q10, d0, d5
472
473    vst1.32       {q8}, [r10], r6
474
475    vaddl.s16     q9, d6, d16
476
477    vld1.32       {q13}, [r11], r6
478
479    vaddl.s16     q3, d7, d17
480
481    vqrshrun.s16  d26, q13, #5
482
483    vmlal.s16     q9, d30, d22
484    vmlsl.s16     q9, d28, d24
485    vmlal.s16     q3, d31, d22
486    vmlsl.s16     q3, d29, d24
487    vaddl.u8      q1, d2, d3
488    vext.8        d4, d0, d1, #4
489    vmla.u16      q10, q1, q11
490    vqrshrun.s32  d18, q9, #10
491    vext.8        d1, d0, d1, #1
492    vqrshrun.s32  d19, q3, #10
493    vadd.s16      q14, q5, q8
494    vaddl.u8      q1, d1, d4
495    vadd.s16      q15, q6, q7
496    vmls.u16      q10, q1, q12
497    vqmovn.u16    d18, q9
498    vld1.32       {q0}, [r8], r2
499
500    vrhadd.u8     d26, d18, d26
501
502    vext.8        d5, d0, d1, #5
503    vext.8        d2, d0, d1, #2
504
505    vst1.32       {q10}, [r10], r6
506
507    vaddl.s16     q9, d8, d20
508    vaddl.s16     q3, d9, d21
509
510    vld1.32       {q4}, [r11], r6
511
512
513    vst1.32       d26, [r14], r3        @store row 0
514
515    vmlal.s16     q9, d30, d22
516    vmlsl.s16     q9, d28, d24
517
518    vqrshrun.s16  d28, q4, #5
519
520    vmlal.s16     q3, d31, d22
521    vmlsl.s16     q3, d29, d24
522    vext.8        d3, d0, d1, #3
523    vaddl.u8      q4, d0, d5
524    vaddl.u8      q1, d2, d3
525    vqrshrun.s32  d18, q9, #10
526    vext.8        d4, d0, d1, #4
527    vqrshrun.s32  d19, q3, #10
528    vmla.u16      q4, q1, q11
529    vext.8        d1, d0, d1, #1
530    vadd.s16      q13, q6, q10
531    vaddl.u8      q1, d1, d4
532    vqmovn.u16    d18, q9
533    vadd.s16      q15, q7, q8
534    vmls.u16      q4, q1, q12
535    vld1.32       {q0}, [r8], r2
536
537    vrhadd.u8     d28, d28, d18
538
539    vext.8        d5, d0, d1, #5
540    vext.8        d2, d0, d1, #2
541    vext.8        d3, d0, d1, #3
542
543    vst1.32       d28, [r14], r3        @store row 1
544
545    vaddl.u8      q14, d0, d5
546
547    vst1.32       {q4}, [r10], r6
548
549    vaddl.s16     q9, d10, d8
550    vaddl.s16     q3, d11, d9
551
552    vld1.32       {q5}, [r11], r6
553
554    vmlal.s16     q9, d30, d22
555    vmlsl.s16     q9, d26, d24
556    vmlal.s16     q3, d31, d22
557
558    vqrshrun.s16  d26, q5, #5
559
560    vmlsl.s16     q3, d27, d24
561    vaddl.u8      q1, d2, d3
562    vext.8        d4, d0, d1, #4
563    vmla.u16      q14, q1, q11
564    vqrshrun.s32  d18, q9, #10
565    vext.8        d1, d0, d1, #1
566    vqrshrun.s32  d19, q3, #10
567    vadd.s16      q5, q7, q4
568    vaddl.u8      q1, d1, d4
569    vadd.s16      q15, q8, q10
570    vmls.u16      q14, q1, q12
571    vqmovn.u16    d27, q9
572
573
574    vaddl.s16     q9, d12, d28
575    vaddl.s16     q3, d13, d29
576
577    vrhadd.u8     d26, d26, d27
578
579    vmlal.s16     q9, d30, d22
580    vmlsl.s16     q9, d10, d24
581    vmlal.s16     q3, d31, d22
582    vmlsl.s16     q3, d11, d24
583
584    vst1.32       d26, [r14], r3        @ store row 2
585
586    vst1.32       {q14}, [r10]
587
588    vqrshrun.s32  d18, q9, #10
589    vmov          q5, q10
590    vld1.32       {q15}, [r11], r6
591
592    vqrshrun.s32  d19, q3, #10
593    subs          r12, r12, #4
594
595    vqrshrun.s16  d30, q15, #5
596
597    vqmovn.u16    d18, q9
598    vmov          q6, q4
599    vmov          q3, q7
600    vrhadd.u8     d30, d18, d30
601    vmov          q4, q8
602    vmov          q7, q14
603    vst1.32       d30, [r14], r3        @ store row 3
604
605    bgt           loop_16_highhalf      @ looping if height = 8 or 16
606    b             end_func
607
608loop_8_start:
609
610    vmov.u16      q11, #20              @ Filter coeff 20 into Q11
611    vmov.u16      q12, #5               @ Filter coeff 5  into Q12
612    vld1.32       {q0}, [r0], r2        @ row -2 load for horizontal filter
613    vext.8        d5, d0, d1, #5
614    vaddl.u8      q3, d0, d5
615
616    vext.8        d2, d0, d1, #2
617    vext.8        d3, d0, d1, #3
618    vaddl.u8      q4, d2, d3
619    vext.8        d4, d0, d1, #4
620    vmla.u16      q3, q4, q11
621    vext.8        d1, d0, d1, #1
622    vaddl.u8      q4, d1, d4
623    vld1.32       {q0}, [r0], r2        @ row -1 load for horizontal filter
624    vmls.u16      q3, q4, q12
625    vext.8        d5, d0, d1, #5
626    vaddl.u8      q4, d0, d5
627    vext.8        d2, d0, d1, #2
628    vext.8        d3, d0, d1, #3
629    vaddl.u8      q5, d2, d3
630
631    vst1.32       {q3}, [r9], r6        @ store temp buffer 0
632
633    vext.8        d4, d0, d1, #4
634    vmla.u16      q4, q5, q11
635    vext.8        d1, d0, d1, #1
636    vaddl.u8      q5, d1, d4
637    vld1.32       {q0}, [r0], r2        @ row 0 load for horizontal filter
638    vmls.u16      q4, q5, q12
639    vext.8        d5, d0, d1, #5
640    vaddl.u8      q5, d0, d5
641    vext.8        d2, d0, d1, #2
642    vext.8        d3, d0, d1, #3
643    vaddl.u8      q6, d2, d3
644
645    vst1.32       {q4}, [r9], r6        @ store temp buffer 1
646
647    vext.8        d4, d0, d1, #4
648    vmla.u16      q5, q6, q11
649    vext.8        d1, d0, d1, #1
650    vaddl.u8      q6, d1, d4
651    vld1.32       {q0}, [r0], r2        @ row 1 load for horizontal filter
652    vmls.u16      q5, q6, q12
653    vext.8        d5, d0, d1, #5
654    vaddl.u8      q6, d0, d5
655    vext.8        d2, d0, d1, #2
656    vext.8        d3, d0, d1, #3
657    vaddl.u8      q7, d2, d3
658
659    vst1.32       {q5}, [r9], r6        @ store temp buffer 2
660
661    vext.8        d4, d0, d1, #4
662    vmla.u16      q6, q7, q11
663    vext.8        d1, d0, d1, #1
664    vaddl.u8      q7, d1, d4
665    vld1.32       {q0}, [r0], r2        @ row 2 load for horizontal filter
666    vmls.u16      q6, q7, q12
667    vext.8        d5, d0, d1, #5
668    vaddl.u8      q7, d0, d5
669    vext.8        d2, d0, d1, #2
670    vext.8        d3, d0, d1, #3
671    vaddl.u8      q8, d2, d3
672
673    vst1.32       {q6}, [r9], r6        @ store temp buffer 3
674
675    vext.8        d4, d0, d1, #4
676    vmla.u16      q7, q8, q11
677    vext.8        d1, d0, d1, #1
678    vaddl.u8      q8, d1, d4
679
680    vmls.u16      q7, q8, q12
681loop_8:
682
683    vld1.32       {q0}, [r0], r2        @ row 3 load for horizontal filter
684    vext.8        d5, d0, d1, #5
685    vext.8        d2, d0, d1, #2
686    vext.8        d3, d0, d1, #3
687    vaddl.u8      q8, d0, d5
688
689    vst1.32       {q7}, [r9], r6        @ store temp buffer 4
690
691    vaddl.u8      q9, d2, d3
692    vext.8        d4, d0, d1, #4
693    vmla.u16      q8, q9, q11
694    vext.8        d1, d0, d1, #1
695    vadd.s16      q14, q4, q7
696    vaddl.u8      q9, d1, d4
697    vadd.s16      q15, q5, q6
698    vmls.u16      q8, q9, q12
699    vld1.32       {q0}, [r0], r2        @ row 4 load for hoorizontal filter
700    vext.8        d5, d0, d1, #5
701    vext.8        d2, d0, d1, #2
702    vext.8        d3, d0, d1, #3
703    vaddl.u8      q10, d0, d5
704
705    vst1.32       {q8}, [r9], r6        @ store temp buffer r5
706
707    vaddl.s16     q9, d6, d16
708
709    vld1.32       {q13}, [r7], r6       @ load from temp buffer 0
710
711    vaddl.s16     q3, d7, d17
712
713    vqrshrun.s16  d26, q13, #5
714
715    vmlal.s16     q9, d30, d22
716    vmlsl.s16     q9, d28, d24
717    vmlal.s16     q3, d31, d22
718    vmlsl.s16     q3, d29, d24
719    vaddl.u8      q1, d2, d3
720    vext.8        d4, d0, d1, #4
721    vmla.u16      q10, q1, q11
722    vqrshrun.s32  d18, q9, #10
723    vext.8        d1, d0, d1, #1
724    vqrshrun.s32  d19, q3, #10
725    vadd.s16      q14, q5, q8
726    vaddl.u8      q1, d1, d4
727    vadd.s16      q15, q6, q7
728    vmls.u16      q10, q1, q12
729    vqmovn.u16    d18, q9
730    vld1.32       {q0}, [r0], r2        @ row 5 load for horizontal filter
731
732    vrhadd.u8     d26, d18, d26
733
734    vext.8        d5, d0, d1, #5
735    vext.8        d2, d0, d1, #2
736
737    vst1.32       {q10}, [r9], r6       @ store temp buffer r6
738
739    vaddl.s16     q9, d8, d20
740
741    vaddl.s16     q3, d9, d21
742
743    vld1.32       {q4}, [r7], r6        @load from temp buffer 1
744
745
746    vst1.32       d26, [r1], r3         @ store row 0
747
748    vmlal.s16     q9, d30, d22
749    vmlsl.s16     q9, d28, d24
750
751    vqrshrun.s16  d28, q4, #5
752
753    vmlal.s16     q3, d31, d22
754    vmlsl.s16     q3, d29, d24
755    vext.8        d3, d0, d1, #3
756    vaddl.u8      q4, d0, d5
757    vaddl.u8      q1, d2, d3
758    vqrshrun.s32  d18, q9, #10
759    vext.8        d4, d0, d1, #4
760    vqrshrun.s32  d19, q3, #10
761    vmla.u16      q4, q1, q11
762    vext.8        d1, d0, d1, #1
763    vadd.s16      q13, q6, q10
764    vaddl.u8      q1, d1, d4
765    vqmovn.u16    d18, q9
766    vadd.s16      q15, q7, q8
767    vmls.u16      q4, q1, q12
768    vld1.32       {q0}, [r0], r2        @ row 6 load for horizontal filter
769
770    vrhadd.u8     d28, d28, d18
771
772    vext.8        d5, d0, d1, #5
773    vext.8        d2, d0, d1, #2
774    vext.8        d3, d0, d1, #3
775
776    vst1.32       d28, [r1], r3         @ store row 1
777
778    vaddl.u8      q14, d0, d5
779
780    vst1.32       {q4}, [r9], r6        @ store temp buffer r7
781
782    vaddl.s16     q9, d10, d8
783    vaddl.s16     q3, d11, d9
784
785    vld1.32       {q5}, [r7], r6        @ load from temp buffer 2
786
787    vmlal.s16     q9, d30, d22
788    vmlsl.s16     q9, d26, d24
789    vmlal.s16     q3, d31, d22
790
791    vqrshrun.s16  d26, q5, #5
792
793    vmlsl.s16     q3, d27, d24
794    vaddl.u8      q1, d2, d3
795    vext.8        d4, d0, d1, #4
796    vmla.u16      q14, q1, q11
797    vqrshrun.s32  d18, q9, #10
798    vext.8        d1, d0, d1, #1
799    vqrshrun.s32  d19, q3, #10
800    vadd.s16      q5, q7, q4
801    vaddl.u8      q1, d1, d4
802    vadd.s16      q15, q8, q10
803    vmls.u16      q14, q1, q12
804    vqmovn.u16    d27, q9
805
806    vaddl.s16     q9, d12, d28
807    vaddl.s16     q3, d13, d29
808
809    vrhadd.u8     d26, d26, d27
810
811    vmlal.s16     q9, d30, d22
812    vmlsl.s16     q9, d10, d24
813    vmlal.s16     q3, d31, d22
814    vmlsl.s16     q3, d11, d24
815
816    vst1.32       d26, [r1], r3         @ store row 2
817
818    vst1.32       {q14}, [r9]
819
820
821    vqrshrun.s32  d18, q9, #10
822    vmov          q5, q10
823    vld1.32       {q15}, [r7], r6       @ load from temp buffer 3
824
825    vqrshrun.s32  d19, q3, #10
826    subs          r4, r4, #4
827
828    vqrshrun.s16  d30, q15, #5
829
830    vqmovn.u16    d18, q9
831    vmov          q6, q4
832    vmov          q3, q7
833    vrhadd.u8     d30, d18, d30
834    vmov          q4, q8
835    vmov          q7, q14
836    vst1.32       d30, [r1], r3         @ store row 3
837
838    bgt           loop_8                @if height =8 or 16  loop
839    b             end_func
840
841loop_4_start:
842    vmov.u16      d22, #20              @ Filter coeff 20 into D22
843    vmov.u16      d23, #5               @ Filter coeff 5  into D23
844
845    vld1.32       {q0}, [r0], r2        @row -2 load
846    vext.8        d5, d0, d1, #5
847    vaddl.u8      q3, d0, d5
848    vext.8        d2, d0, d1, #2
849    vext.8        d3, d0, d1, #3
850    vaddl.u8      q4, d2, d3
851    vext.8        d4, d0, d1, #4
852    vmla.u16      d6, d8, d22
853    vext.8        d1, d0, d1, #1
854    vaddl.u8      q4, d1, d4
855    vld1.32       {q0}, [r0], r2        @ row -1 load
856    vmls.u16      d6, d8, d23
857    vext.8        d5, d0, d1, #5
858    vaddl.u8      q4, d0, d5
859    vext.8        d2, d0, d1, #2
860    vext.8        d3, d0, d1, #3
861    vaddl.u8      q5, d2, d3
862
863    vst1.32       d6, [r9], r6          @ store temp buffer 0
864
865    vext.8        d4, d0, d1, #4
866    vmla.u16      d8, d10, d22
867    vext.8        d1, d0, d1, #1
868    vaddl.u8      q5, d1, d4
869    vld1.32       {q0}, [r0], r2        @ row 0 load
870    vmls.u16      d8, d10, d23
871    vext.8        d5, d0, d1, #5
872    vaddl.u8      q5, d0, d5
873    vext.8        d2, d0, d1, #2
874    vext.8        d3, d0, d1, #3
875    vaddl.u8      q6, d2, d3
876
877    vst1.32       d8, [r9], r6          @ store temp buffer 1
878
879    vext.8        d4, d0, d1, #4
880    vmla.u16      d10, d12, d22
881    vext.8        d1, d0, d1, #1
882    vaddl.u8      q6, d1, d4
883    vld1.32       {q0}, [r0], r2        @ row 1 load
884    vmls.u16      d10, d12, d23
885    vext.8        d5, d0, d1, #5
886    vaddl.u8      q6, d0, d5
887    vext.8        d2, d0, d1, #2
888    vext.8        d3, d0, d1, #3
889    vaddl.u8      q7, d2, d3
890
891    vst1.32       d10, [r9], r6         @ store temp buffer 2
892
893    vext.8        d4, d0, d1, #4
894    vmla.u16      d12, d14, d22
895    vext.8        d1, d0, d1, #1
896    vaddl.u8      q7, d1, d4
897    vld1.32       {q0}, [r0], r2        @ row 2 load
898    vmls.u16      d12, d14, d23
899    vext.8        d5, d0, d1, #5
900    vaddl.u8      q7, d0, d5
901    vext.8        d2, d0, d1, #2
902    vext.8        d3, d0, d1, #3
903    vaddl.u8      q8, d2, d3
904    vext.8        d4, d0, d1, #4
905    vmla.u16      d14, d16, d22
906    vext.8        d1, d0, d1, #1
907    vaddl.u8      q8, d1, d4
908
909    vst1.32       d12, [r9], r6         @ store temp buffer 3
910
911    vmls.u16      d14, d16, d23
912
913loop_4:
914
915    vld1.32       {q0}, [r0], r2        @ row 3 load
916    vext.8        d5, d0, d1, #5
917    vaddl.u8      q8, d0, d5
918    vext.8        d2, d0, d1, #2
919    vext.8        d3, d0, d1, #3
920    vaddl.u8      q9, d2, d3
921    vst1.32       d14, [r9], r6         @ store temp buffer 4
922    vext.8        d4, d0, d1, #4
923    vmla.u16      d16, d18, d22
924    vext.8        d1, d0, d1, #1
925    vaddl.u8      q9, d1, d4
926    vadd.s16      d2, d10, d12
927    vmls.u16      d16, d18, d23
928    vadd.s16      d3, d8, d14
929    vld1.32       {q9}, [r0], r2        @ row 4 load
930    vext.8        d25, d18, d19, #5
931    vaddl.u8      q13, d18, d25
932    vext.8        d20, d18, d19, #2
933
934    vst1.32       d16, [r9], r6         @ store temp buffer 5
935
936    vaddl.s16     q0, d6, d16
937    vmlal.s16     q0, d2, d22
938    vext.8        d21, d18, d19, #3
939    vaddl.u8      q14, d20, d21
940    vext.8        d24, d18, d19, #4
941    vmlsl.s16     q0, d3, d23
942    vmla.u16      d26, d28, d22
943    vext.8        d19, d18, d19, #1
944    vaddl.u8      q14, d19, d24
945    vadd.s16      d2, d12, d14
946    vmls.u16      d26, d28, d23
947    vqrshrun.s32  d0, q0, #0xa
948    vadd.s16      d3, d10, d16
949    vld1.32       {q9}, [r0], r2        @ row 5 load
950    vext.8        d25, d18, d19, #5
951    vqmovn.u16    d11, q0
952    vaddl.u8      q14, d18, d25
953
954    vst1.32       d26, [r9], r6         @ store temp buffer 6
955
956    @Q3 available here
957    vld1.32       d6, [r7], r6          @ load from temp buffer 0
958    vld1.32       d7, [r7], r6          @ load from temp buffer 1
959    vqrshrun.s16  d9, q3, #5
960
961    vext.8        d20, d18, d19, #2
962
963    vaddl.s16     q0, d8, d26
964    vmlal.s16     q0, d2, d22
965    vext.8        d21, d18, d19, #3
966    vaddl.u8      q3, d20, d21
967    vext.8        d24, d18, d19, #4
968    vmlsl.s16     q0, d3, d23
969    vmla.u16      d28, d6, d22
970    vext.8        d19, d18, d19, #1
971    vaddl.u8      q3, d19, d24
972    vadd.s16      d2, d14, d16
973    vmls.u16      d28, d6, d23
974    vqrshrun.s32  d0, q0, #0xa
975    vadd.s16      d3, d12, d26
976    vld1.32       {q9}, [r0], r2        @ row 6 load
977    vext.8        d25, d18, d19, #5
978    vqmovn.u16    d13, q0
979
980    vtrn.32       d11, d13
981    vaddl.s16     q0, d10, d28
982    vrhadd.u8     d9, d9, d11
983
984    vst1.32       d28, [r9], r6         @ store temp buffer 7
985
986    vmlal.s16     q0, d2, d22
987    vaddl.u8      q15, d18, d25
988
989    vst1.32       d9[0], [r1], r3       @ store row 0
990
991    vext.8        d20, d18, d19, #2
992
993    vst1.32       d9[1], [r1], r3       @ store row 1
994
995    vext.8        d21, d18, d19, #3
996    vmlsl.s16     q0, d3, d23
997    vaddl.u8      q4, d20, d21
998    vext.8        d24, d18, d19, #4
999    vmla.u16      d30, d8, d22
1000    vext.8        d19, d18, d19, #1
1001    vaddl.u8      q4, d19, d24
1002    vqrshrun.s32  d0, q0, #0xa
1003    vadd.s16      d2, d16, d26
1004    vmls.u16      d30, d8, d23
1005    vqmovn.u16    d4, q0
1006
1007    vadd.s16      d3, d14, d28
1008
1009
1010    vaddl.s16     q0, d12, d30
1011
1012    vst1.32       d30, [r9]
1013
1014    vmlal.s16     q0, d2, d22
1015
1016    vld1.32       d8, [r7], r6          @ load from temp buffer 2
1017    vld1.32       d9, [r7], r6          @ load from temp buffer 3
1018    vmlsl.s16     q0, d3, d23
1019    subs          r4, r4, #4
1020    vqrshrun.s16  d10, q4, #5
1021
1022    vmov          d12, d28
1023
1024    vqrshrun.s32  d0, q0, #0xa
1025    vmov          d6, d14
1026    vmov          d8, d16
1027
1028    vqmovn.u16    d5, q0
1029
1030    vtrn.32       d4, d5
1031    vrhadd.u8     d4, d4, d10
1032    vmov          d10, d26
1033    vmov          d14, d30
1034
1035    vst1.32       d4[0], [r1], r3       @ store row 2
1036    vst1.32       d4[1], [r1], r3       @ store row 3
1037
1038    bgt           loop_4
1039
1040end_func:
1041    vldmia        sp!, {d8-d15}         @ Restore neon registers that were saved
1042    ldmfd         sp!, {r4-r12, pc}     @Restoring registers from stack
1043
1044
1045