• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*!
2 * \copy
3 *     Copyright (c)  2013, Cisco Systems
4 *     All rights reserved.
5 *
6 *     Redistribution and use in source and binary forms, with or without
7 *     modification, are permitted provided that the following conditions
8 *     are met:
9 *
10 *        * Redistributions of source code must retain the above copyright
11 *          notice, this list of conditions and the following disclaimer.
12 *
13 *        * Redistributions in binary form must reproduce the above copyright
14 *          notice, this list of conditions and the following disclaimer in
15 *          the documentation and/or other materials provided with the
16 *          distribution.
17 *
18 *     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 *     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 *     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21 *     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22 *     COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23 *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
24 *     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 *     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 *     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 *     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
28 *     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 *     POSSIBILITY OF SUCH DAMAGE.
30 *
31 */
32
33#ifdef HAVE_NEON
34#include "arm_arch_common_macro.S"
35
36.macro AVERAGE_TWO_8BITS arg0, arg1, arg2
37//  {   // input:dst_d, src_d A and B; working: q13
38    vaddl.u8    q13, \arg2, \arg1
39    vrshrn.u16      \arg0, q13, #1
40//  }
41.endm
42
43.macro FILTER_6TAG_8BITS arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
44//  {   // input:src[-2], src[-1], src[0], src[1], src[2], src[3], dst_d, multiplier a/b; working: q12, q13
45    vaddl.u8    q12, \arg0, \arg5   //q12=src[-2]+src[3]
46    vaddl.u8    q13, \arg2, \arg3   //src[0]+src[1]
47    vmla.u16    q12, q13, \arg7 //q12 += 20*(src[0]+src[1]), 2 cycles
48    vaddl.u8    q13, \arg1, \arg4   //src[-1]+src[2]
49    vmls.s16    q12, q13, \arg8 //q12 -= 5*(src[-1]+src[2]), 2 cycles
50    vqrshrun.s16        \arg6, q12, #5
51//  }
52.endm
53
54.macro FILTER_SINGLE_TAG_8BITS arg0, arg1,arg2, arg3, arg4     // when width=17/9, used
55//  {   // input: src_d{Y[0][1][2][3][4][5]X, the even of working_q2}
56    vrev64.8    \arg2, \arg0                // X[5][4][3][2][1][0]O
57    vaddl.u8    \arg3, \arg0, \arg2         // each 16bits, *[50][41][32][23][14][05]*
58    vmul.s16    \arg0, \arg2, \arg1         // 0+1*[50]-5*[41]+20[32]
59    vpadd.s16   \arg0, \arg0, \arg0
60    vpadd.s16   \arg0, \arg0, \arg0
61    vqrshrun.s16    \arg0, \arg4, #5
62//  }
63.endm
64
65.macro FILTER_6TAG_8BITS_AVERAGE_WITH_0 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
66//  {   // input:src[-2], src[-1], src[0], src[1], src[2], src[3], dst_d, multiplier a/b; working: q12, q13
67    vaddl.u8    q12, \arg0, \arg5   //q12=src[-2]+src[3]
68    vaddl.u8    q13, \arg2, \arg3   //src[0]+src[1]
69    vmla.u16    q12, q13, \arg7 //q12 += 20*(src[0]+src[1]), 2 cycles
70    vaddl.u8    q13, \arg1, \arg4   //src[-1]+src[2]
71    vmls.s16    q12, q13, \arg8 //q12 -= 5*(src[-1]+src[2]), 2 cycles
72    vqrshrun.s16        \arg6, q12, #5
73    vaddl.u8    q13, \arg2, \arg6
74    vrshrn.u16      \arg6, q13, #1
75//  }
76.endm
77
78.macro FILTER_6TAG_8BITS_AVERAGE_WITH_1 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
79//  {   // input:src[-2], src[-1], src[0], src[1], src[2], src[3], dst_d, multiplier a/b; working: q12, q13
80    vaddl.u8    q12, \arg0, \arg5   //q12=src[-2]+src[3]
81    vaddl.u8    q13, \arg2, \arg3   //src[0]+src[1]
82    vmla.u16    q12, q13, \arg7 //q12 += 20*(src[0]+src[1]), 2 cycles
83    vaddl.u8    q13, \arg1, \arg4   //src[-1]+src[2]
84    vmls.s16    q12, q13, \arg8 //q12 -= 5*(src[-1]+src[2]), 2 cycles
85    vqrshrun.s16        \arg6, q12, #5
86    vaddl.u8    q13, \arg3, \arg6
87    vrshrn.u16      \arg6, q13, #1
88//  }
89.endm
90
91.macro FILTER_6TAG_8BITS_TO_16BITS arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8
92//  {   // input:d_src[-2], d_src[-1], d_src[0], d_src[1], d_src[2], d_src[3], dst_q, multiplier a/b; working:q13
93    vaddl.u8    \arg6, \arg0, \arg5     //dst_q=src[-2]+src[3]
94    vaddl.u8    q13, \arg2, \arg3   //src[0]+src[1]
95    vmla.u16    \arg6, q13, \arg7   //dst_q += 20*(src[0]+src[1]), 2 cycles
96    vaddl.u8    q13, \arg1, \arg4   //src[-1]+src[2]
97    vmls.s16    \arg6, q13, \arg8   //dst_q -= 5*(src[-1]+src[2]), 2 cycles
98//  }
99.endm
100
101.macro FILTER_3_IN_16BITS_TO_8BITS arg0, arg1, arg2, arg3
102//  {   // input:a, b, c, dst_d;
103    vsub.s16    \arg0, \arg0, \arg1         //a-b
104    vshr.s16    \arg0, \arg0, #2            //(a-b)/4
105    vsub.s16    \arg0, \arg0, \arg1         //(a-b)/4-b
106    vadd.s16    \arg0, \arg0, \arg2         //(a-b)/4-b+c
107    vshr.s16    \arg0, \arg0, #2            //((a-b)/4-b+c)/4
108    vadd.s16    \arg0, \arg0, \arg2         //((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16
109    vqrshrun.s16    \arg3, \arg0, #6        //(+32)>>6
110//  }
111.endm
112
113.macro UNPACK_2_16BITS_TO_ABC arg0, arg1, arg2, arg3, arg4
114//  {   // input:q_src[-2:5], q_src[6:13](avail 8+5)/q_src[6:**](avail 4+5), dst_a, dst_b, dst_c;
115    vext.16 \arg4, \arg0, \arg1, #2     //src[0]
116    vext.16 \arg3, \arg0, \arg1, #3     //src[1]
117    vadd.s16    \arg4, \arg3                    //c=src[0]+src[1]
118
119    vext.16 \arg3, \arg0, \arg1, #1     //src[-1]
120    vext.16 \arg2, \arg0, \arg1, #4     //src[2]
121    vadd.s16    \arg3,\arg2                 //b=src[-1]+src[2]
122
123    vext.16 \arg2, \arg0, \arg1, #5     //src[3]
124    vadd.s16    \arg2, \arg0                    //a=src[-2]+src[3]
125//  }
126.endm
127
128.macro UNPACK_1_IN_8x16BITS_TO_8BITS arg0, arg1,arg2, arg3
129//  {   // each 16bits; input: d_dst, d_src[0:3] (even), d_src[4:5]+%% (odd)
130    vext.16 \arg3, \arg3, \arg3, #7 // 0x????, [0][1][2][3][4][5]
131    vrev64.16   \arg1, \arg1
132    vadd.u16    \arg2, \arg1                // C[2+3],B[1+4],A[0+5]
133    vshr.s64    \arg1, \arg2, #16
134    vshr.s64    \arg0, \arg2, #32       // Output: C \arg2, B \arg1, A \arg0
135
136    vsub.s16    \arg0, \arg0, \arg1         //a-b
137    vshr.s16    \arg0, \arg0, #2            //(a-b)/4
138    vsub.s16    \arg0, \arg0, \arg1         //(a-b)/4-b
139    vadd.s16    \arg0, \arg0, \arg2         //(a-b)/4-b+c
140    vshr.s16    \arg0, \arg0, #2            //((a-b)/4-b+c)/4
141    vadd.s16    \arg1, \arg0, \arg2         //((a-b)/4-b+c)/4+c = (a-5*b+20*c)/16
142    vqrshrun.s16    \arg0, \arg3, #6        //(+32)>>6
143//  }
144.endm
145
146WELS_ASM_FUNC_BEGIN McHorVer20WidthEq16_neon
147    push        {r4}
148    ldr         r4, [sp, #4]
149
150    sub         r0, #2
151    vmov.u16    q14, #0x0014                // 20
152    vshr.u16    q15, q14, #2                // 5
153
154w16_h_mc_luma_loop:
155    vld1.u8 {d0,d1,d2}, [r0], r1    //only use 21(16+5); q0=src[-2]
156    pld         [r0]
157    pld         [r0, #16]
158
159    vext.8      q2, q0, q1, #1      //q2=src[-1]
160    vext.8      q3, q0, q1, #2      //q3=src[0]
161    vext.8      q8, q0, q1, #3      //q8=src[1]
162    vext.8      q9, q0, q1, #4      //q9=src[2]
163    vext.8      q10, q0, q1, #5     //q10=src[3]
164
165    FILTER_6TAG_8BITS   d0, d4, d6, d16, d18, d20, d2, q14, q15
166
167    FILTER_6TAG_8BITS   d1, d5, d7, d17, d19, d21, d3, q14, q15
168
169    sub     r4, #1
170    vst1.u8 {d2, d3}, [r2], r3      //write 16Byte
171
172    cmp     r4, #0
173    bne     w16_h_mc_luma_loop
174    pop     {r4}
175WELS_ASM_FUNC_END
176
177
178WELS_ASM_FUNC_BEGIN McHorVer20WidthEq8_neon
179    push        {r4}
180    ldr         r4, [sp, #4]
181
182    sub         r0, #2
183    vmov.u16    q14, #0x0014                // 20
184    vshr.u16    q15, q14, #2                // 5
185
186w8_h_mc_luma_loop:
187    vld1.u8 {d0,d1}, [r0], r1   //only use 13(8+5); q0=src[-2]
188    pld         [r0]
189
190    vext.8      d2, d0, d1, #1      //d2=src[-1]
191    vext.8      d3, d0, d1, #2      //d3=src[0]
192    vext.8      d4, d0, d1, #3      //d4=src[1]
193    vext.8      d5, d0, d1, #4      //d5=src[2]
194    vext.8      d6, d0, d1, #5      //d6=src[3]
195
196    FILTER_6TAG_8BITS   d0, d2, d3, d4, d5, d6, d1, q14, q15
197
198    sub     r4, #1
199    vst1.u8 {d1}, [r2], r3
200
201    cmp     r4, #0
202    bne     w8_h_mc_luma_loop
203    pop     {r4}
204WELS_ASM_FUNC_END
205
206
207WELS_ASM_FUNC_BEGIN McHorVer20WidthEq4_neon
208    push        {r4, r5, r6}
209    ldr         r6, [sp, #12]
210
211    sub         r0, #2
212    vmov.u16    q14, #0x0014                // 20
213    vshr.u16    q15, q14, #2                // 5
214
215w4_h_mc_luma_loop:
216    vld1.u8 {d0, d1}, [r0], r1  //only use 9(4+5);d0: 1st row src[-2:5]
217    pld         [r0]
218    vld1.u8 {d2, d3}, [r0], r1  //d2: 2nd row src[-2:5]
219    pld         [r0]
220
221    vext.8      d4, d0, d1, #1      //d4: 1st row src[-1:6]
222    vext.8      d5, d2, d3, #1      //d5: 2nd row src[-1:6]
223    vext.8      q3, q2, q2, #1      //src[0:6 *]
224    vext.8      q8, q2, q2, #2      //src[1:6 * *]
225
226    vtrn.32 q3, q8                  //q3::d6:1st row [0:3]+[1:4]; d7:2nd row [0:3]+[1:4]
227    vtrn.32 d6, d7                  //d6:[0:3]; d7[1:4]
228    vtrn.32     d0, d2              //d0:[-2:1]; d2[2:5]
229    vtrn.32     d4, d5              //d4:[-1:2]; d5[3:6]
230
231    FILTER_6TAG_8BITS   d0, d4, d6, d7, d2, d5, d1, q14, q15
232
233    vmov        r4, r5, d1
234    str r4, [r2], r3
235    str r5, [r2], r3
236
237    sub     r6, #2
238    cmp     r6, #0
239    bne     w4_h_mc_luma_loop
240
241    pop     {r4, r5, r6}
242WELS_ASM_FUNC_END
243
244
245WELS_ASM_FUNC_BEGIN McHorVer10WidthEq16_neon
246    push        {r4}
247    ldr         r4, [sp, #4]
248
249    sub         r0, #2
250    vmov.u16    q14, #0x0014                // 20
251    vshr.u16    q15, q14, #2                // 5
252
253w16_xy_10_mc_luma_loop:
254    vld1.u8 {d0,d1,d2}, [r0], r1    //only use 21(16+5); q0=src[-2]
255    pld         [r0]
256    pld         [r0, #16]
257
258    vext.8      q2, q0, q1, #1      //q2=src[-1]
259    vext.8      q3, q0, q1, #2      //q3=src[0]
260    vext.8      q8, q0, q1, #3      //q8=src[1]
261    vext.8      q9, q0, q1, #4      //q9=src[2]
262    vext.8      q10, q0, q1, #5     //q10=src[3]
263
264    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d0, d4, d6, d16, d18, d20, d2, q14, q15
265
266    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d1, d5, d7, d17, d19, d21, d3, q14, q15
267
268    sub     r4, #1
269    vst1.u8 {d2, d3}, [r2], r3      //write 16Byte
270
271    cmp     r4, #0
272    bne     w16_xy_10_mc_luma_loop
273    pop     {r4}
274WELS_ASM_FUNC_END
275
276
277WELS_ASM_FUNC_BEGIN McHorVer10WidthEq8_neon
278    push        {r4}
279    ldr         r4, [sp, #4]
280
281    sub         r0, #2
282    vmov.u16    q14, #0x0014                // 20
283    vshr.u16    q15, q14, #2                // 5
284
285w8_xy_10_mc_luma_loop:
286    vld1.u8 {d0,d1}, [r0], r1   //only use 13(8+5); q0=src[-2]
287    pld         [r0]
288
289    vext.8      d2, d0, d1, #1      //d2=src[-1]
290    vext.8      d3, d0, d1, #2      //d3=src[0]
291    vext.8      d4, d0, d1, #3      //d4=src[1]
292    vext.8      d5, d0, d1, #4      //d5=src[2]
293    vext.8      d6, d0, d1, #5      //d6=src[3]
294
295    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d0, d2, d3, d4, d5, d6, d1, q14, q15
296
297    sub     r4, #1
298    vst1.u8 {d1}, [r2], r3
299
300    cmp     r4, #0
301    bne     w8_xy_10_mc_luma_loop
302    pop     {r4}
303WELS_ASM_FUNC_END
304
305
306WELS_ASM_FUNC_BEGIN McHorVer10WidthEq4_neon
307    push        {r4, r5, r6}
308    ldr         r6, [sp, #12]
309
310    sub         r0, #2
311    vmov.u16    q14, #0x0014                // 20
312    vshr.u16    q15, q14, #2                // 5
313
314w4_xy_10_mc_luma_loop:
315    vld1.u8 {d0, d1}, [r0], r1  //only use 9(4+5);d0: 1st row src[-2:5]
316    pld         [r0]
317    vld1.u8 {d2, d3}, [r0], r1  //d2: 2nd row src[-2:5]
318    pld         [r0]
319
320    vext.8      d4, d0, d1, #1      //d4: 1st row src[-1:6]
321    vext.8      d5, d2, d3, #1      //d5: 2nd row src[-1:6]
322    vext.8      q3, q2, q2, #1      //src[0:6 *]
323    vext.8      q8, q2, q2, #2      //src[1:6 * *]
324
325    vtrn.32 q3, q8                  //q3::d6:1st row [0:3]+[1:4]; d7:2nd row [0:3]+[1:4]
326    vtrn.32 d6, d7                  //d6:[0:3]; d7[1:4]
327    vtrn.32     d0, d2              //d0:[-2:1]; d2[2:5]
328    vtrn.32     d4, d5              //d4:[-1:2]; d5[3:6]
329
330    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d0, d4, d6, d7, d2, d5, d1, q14, q15
331
332    vmov        r4, r5, d1
333    str r4, [r2], r3
334    str r5, [r2], r3
335
336    sub     r6, #2
337    cmp     r6, #0
338    bne     w4_xy_10_mc_luma_loop
339
340    pop     {r4, r5, r6}
341WELS_ASM_FUNC_END
342
343
344WELS_ASM_FUNC_BEGIN McHorVer30WidthEq16_neon
345    push        {r4}
346    ldr         r4, [sp, #4]
347
348    sub         r0, #2
349    vmov.u16    q14, #0x0014                // 20
350    vshr.u16    q15, q14, #2                // 5
351
352w16_xy_30_mc_luma_loop:
353    vld1.u8 {d0,d1,d2}, [r0], r1    //only use 21(16+5); q0=src[-2]
354    pld         [r0]
355    pld         [r0, #16]
356
357    vext.8      q2, q0, q1, #1      //q2=src[-1]
358    vext.8      q3, q0, q1, #2      //q3=src[0]
359    vext.8      q8, q0, q1, #3      //q8=src[1]
360    vext.8      q9, q0, q1, #4      //q9=src[2]
361    vext.8      q10, q0, q1, #5     //q10=src[3]
362
363    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d0, d4, d6, d16, d18, d20, d2, q14, q15
364
365    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d1, d5, d7, d17, d19, d21, d3, q14, q15
366
367    sub     r4, #1
368    vst1.u8 {d2, d3}, [r2], r3      //write 16Byte
369
370    cmp     r4, #0
371    bne     w16_xy_30_mc_luma_loop
372    pop     {r4}
373WELS_ASM_FUNC_END
374
375
376WELS_ASM_FUNC_BEGIN McHorVer30WidthEq8_neon
377    push        {r4}
378    ldr         r4, [sp, #4]
379
380    sub         r0, #2
381    vmov.u16    q14, #0x0014                // 20
382    vshr.u16    q15, q14, #2                // 5
383
384w8_xy_30_mc_luma_loop:
385    vld1.u8 {d0,d1}, [r0], r1   //only use 13(8+5); q0=src[-2]
386    pld         [r0]
387
388    vext.8      d2, d0, d1, #1      //d2=src[-1]
389    vext.8      d3, d0, d1, #2      //d3=src[0]
390    vext.8      d4, d0, d1, #3      //d4=src[1]
391    vext.8      d5, d0, d1, #4      //d5=src[2]
392    vext.8      d6, d0, d1, #5      //d6=src[3]
393
394    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d0, d2, d3, d4, d5, d6, d1, q14, q15
395
396    sub     r4, #1
397    vst1.u8 {d1}, [r2], r3
398
399    cmp     r4, #0
400    bne     w8_xy_30_mc_luma_loop
401    pop     {r4}
402WELS_ASM_FUNC_END
403
404
405WELS_ASM_FUNC_BEGIN McHorVer30WidthEq4_neon
406    push        {r4, r5, r6}
407    ldr         r6, [sp, #12]
408
409    sub         r0, #2
410    vmov.u16    q14, #0x0014                // 20
411    vshr.u16    q15, q14, #2                // 5
412
413w4_xy_30_mc_luma_loop:
414    vld1.u8 {d0, d1}, [r0], r1  //only use 9(4+5);d0: 1st row src[-2:5]
415    pld         [r0]
416    vld1.u8 {d2, d3}, [r0], r1  //d2: 2nd row src[-2:5]
417    pld         [r0]
418
419    vext.8      d4, d0, d1, #1      //d4: 1st row src[-1:6]
420    vext.8      d5, d2, d3, #1      //d5: 2nd row src[-1:6]
421    vext.8      q3, q2, q2, #1      //src[0:6 *]
422    vext.8      q8, q2, q2, #2      //src[1:6 * *]
423
424    vtrn.32 q3, q8                  //q3::d6:1st row [0:3]+[1:4]; d7:2nd row [0:3]+[1:4]
425    vtrn.32 d6, d7                  //d6:[0:3]; d7[1:4]
426    vtrn.32     d0, d2              //d0:[-2:1]; d2[2:5]
427    vtrn.32     d4, d5              //d4:[-1:2]; d5[3:6]
428
429    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d0, d4, d6, d7, d2, d5, d1, q14, q15
430
431    vmov        r4, r5, d1
432    str r4, [r2], r3
433    str r5, [r2], r3
434
435    sub     r6, #2
436    cmp     r6, #0
437    bne     w4_xy_30_mc_luma_loop
438
439    pop     {r4, r5, r6}
440WELS_ASM_FUNC_END
441
442
443WELS_ASM_FUNC_BEGIN McHorVer01WidthEq16_neon
444    push        {r4}
445    ldr         r4, [sp, #4]
446
447    sub         r0, r0, r1, lsl #1      //src[-2*src_stride]
448    pld         [r0]
449    pld         [r0, r1]
450    vmov.u16    q14, #0x0014            // 20
451    vld1.u8 {q0}, [r0], r1      //q0=src[-2]
452    vld1.u8 {q1}, [r0], r1      //q1=src[-1]
453
454    pld         [r0]
455    pld         [r0, r1]
456    vshr.u16    q15, q14, #2            // 5
457    vld1.u8 {q2}, [r0], r1      //q2=src[0]
458    vld1.u8 {q3}, [r0], r1      //q3=src[1]
459    vld1.u8 {q8}, [r0], r1      //q8=src[2]
460
461w16_xy_01_luma_loop:
462
463    vld1.u8 {q9}, [r0], r1      //q9=src[3]
464
465    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d0, d2, d4, d6, d16, d18, d20, q14, q15
466    pld         [r0]
467    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d1, d3, d5, d7, d17, d19, d21, q14, q15
468    vld1.u8 {q0}, [r0], r1      //read 2nd row
469    vst1.u8 {q10}, [r2], r3         //write 1st 16Byte
470
471    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d2, d4, d6, d16, d18, d0, d20, q14, q15
472    pld         [r0]
473    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d3, d5, d7, d17, d19, d1, d21, q14, q15
474    vld1.u8 {q1}, [r0], r1      //read 3rd row
475    vst1.u8 {q10}, [r2], r3         //write 2nd 16Byte
476
477    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d4, d6, d16, d18, d0, d2, d20, q14, q15
478    pld         [r0]
479    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d5, d7, d17, d19, d1, d3, d21, q14, q15
480    vld1.u8 {q2}, [r0], r1      //read 4th row
481    vst1.u8 {q10}, [r2], r3         //write 3rd 16Byte
482
483    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d6, d16, d18, d0, d2, d4, d20, q14, q15
484    pld         [r0]
485    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d7, d17, d19, d1, d3, d5, d21, q14, q15
486    vld1.u8 {q3}, [r0], r1      //read 5th row
487    vst1.u8 {q10}, [r2], r3         //write 4th 16Byte
488
489    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d16, d18, d0, d2, d4, d6, d20, q14, q15
490    pld         [r0]
491    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d17, d19, d1, d3, d5, d7, d21, q14, q15
492    vld1.u8 {q8}, [r0], r1      //read 6th row
493    vst1.u8 {q10}, [r2], r3         //write 5th 16Byte
494
495    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d18, d0, d2, d4, d6, d16, d20, q14, q15
496    pld         [r0]
497    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d19, d1, d3, d5, d7, d17, d21, q14, q15
498    vld1.u8 {q9}, [r0], r1      //read 7th row
499    vst1.u8 {q10}, [r2], r3         //write 6th 16Byte
500
501    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d0, d2, d4, d6, d16, d18, d20, q14, q15
502    pld         [r0]
503    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d1, d3, d5, d7, d17, d19, d21, q14, q15
504    vld1.u8 {q0}, [r0], r1      //read 8th row
505    vst1.u8 {q10}, [r2], r3         //write 7th 16Byte
506
507    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d2, d4, d6, d16, d18, d0, d20, q14, q15
508    pld         [r0]
509    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d3, d5, d7, d17, d19, d1, d21, q14, q15
510    vst1.u8 {q10}, [r2], r3         //write 8th 16Byte
511
512    //q2, q3, q4, q5, q0 --> q0~q4
513    vswp    q0, q8
514    vswp    q0, q2
515    vmov    q1, q3
516    vmov    q3, q9                      //q0~q4
517
518    sub     r4, #8
519    cmp     r4, #0
520    bne     w16_xy_01_luma_loop
521    pop     {r4}
522WELS_ASM_FUNC_END
523
524
525WELS_ASM_FUNC_BEGIN McHorVer01WidthEq8_neon
526    push        {r4}
527    ldr         r4, [sp, #4]
528
529    sub         r0, r0, r1, lsl #1      //src[-2*src_stride]
530    pld         [r0]
531    pld         [r0, r1]
532    vmov.u16    q14, #0x0014            // 20
533    vld1.u8 {d0}, [r0], r1      //d0=src[-2]
534    vld1.u8 {d1}, [r0], r1      //d1=src[-1]
535
536    pld         [r0]
537    pld         [r0, r1]
538    vshr.u16    q15, q14, #2            // 5
539    vld1.u8 {d2}, [r0], r1      //d2=src[0]
540    vld1.u8 {d3}, [r0], r1      //d3=src[1]
541
542    vld1.u8 {d4}, [r0], r1      //d4=src[2]
543    vld1.u8 {d5}, [r0], r1      //d5=src[3]
544
545w8_xy_01_mc_luma_loop:
546
547    pld         [r0]
548    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d0, d1, d2, d3, d4, d5, d16, q14, q15
549    vld1.u8 {d0}, [r0], r1      //read 2nd row
550    vst1.u8 {d16}, [r2], r3     //write 1st 8Byte
551
552    pld         [r0]
553    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d1, d2, d3, d4, d5, d0, d16, q14, q15
554    vld1.u8 {d1}, [r0], r1      //read 3rd row
555    vst1.u8 {d16}, [r2], r3     //write 2nd 8Byte
556
557    pld         [r0]
558    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d2, d3, d4, d5, d0, d1, d16, q14, q15
559    vld1.u8 {d2}, [r0], r1      //read 4th row
560    vst1.u8 {d16}, [r2], r3     //write 3rd 8Byte
561
562    pld         [r0]
563    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d3, d4, d5, d0, d1, d2, d16, q14, q15
564    vld1.u8 {d3}, [r0], r1      //read 5th row
565    vst1.u8 {d16}, [r2], r3     //write 4th 8Byte
566
567    //d4, d5, d0, d1, d2, d3 --> d0, d1, d2, d3, d4, d5
568    vswp    q0, q2
569    vswp    q1, q2
570
571    sub     r4, #4
572    cmp     r4, #0
573    bne     w8_xy_01_mc_luma_loop
574
575    pop     {r4}
576WELS_ASM_FUNC_END
577
578
579WELS_ASM_FUNC_BEGIN McHorVer01WidthEq4_neon
580    push        {r4, r5, r6, r7}
581    sub         r0, r0, r1, lsl #1      //src[-2*src_stride]
582    pld         [r0]
583    pld         [r0, r1]
584    vmov.u16    q14, #0x0014            // 20
585    ldr     r4, [r0], r1        //r4=src[-2]
586    ldr     r5, [r0], r1        //r5=src[-1]
587
588    pld         [r0]
589    pld         [r0, r1]
590    vshr.u16    q15, q14, #2            // 5
591    ldr     r6, [r0], r1        //r6=src[0]
592    ldr     r7, [r0], r1        //r7=src[1]
593
594    vmov        d0, r4, r5
595    vmov        d1, r5, r6
596    vmov        d2, r6, r7
597
598    ldr     r4, [r0], r1        //r4=src[2]
599    vmov        d3, r7, r4
600    ldr         r7, [sp, #16]
601
602w4_xy_01_mc_luma_loop:
603
604//  pld         [r0]
605    //using reserving r4
606    ldr     r5, [r0], r1        //r5=src[3]
607    ldr     r6, [r0], r1        //r6=src[0]
608    vmov        d4, r4, r5
609    vmov        d5, r5, r6          //reserved r6
610
611    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d0, d1, d2, d3, d4, d5, d16, q14, q15
612    vmov        r4, r5, d16
613    str r4, [r2], r3            //write 1st 4Byte
614    str r5, [r2], r3            //write 2nd 4Byte
615
616    ldr     r5, [r0], r1        //r5=src[1]
617    ldr     r4, [r0], r1        //r4=src[2]
618    vmov        d0, r6, r5
619    vmov        d1, r5, r4          //reserved r4
620
621    FILTER_6TAG_8BITS_AVERAGE_WITH_0    d2, d3, d4, d5, d0, d1, d16, q14, q15
622    vmov        r5, r6, d16
623    str r5, [r2], r3            //write 3rd 4Byte
624    str r6, [r2], r3            //write 4th 4Byte
625
626    //d4, d5, d0, d1 --> d0, d1, d2, d3
627    vmov    q1, q0
628    vmov    q0, q2
629
630    sub     r7, #4
631    cmp     r7, #0
632    bne     w4_xy_01_mc_luma_loop
633
634    pop     {r4, r5, r6, r7}
635WELS_ASM_FUNC_END
636
637
638WELS_ASM_FUNC_BEGIN McHorVer03WidthEq16_neon
639    push        {r4}
640    ldr         r4, [sp, #4]
641
642    sub         r0, r0, r1, lsl #1      //src[-2*src_stride]
643    pld         [r0]
644    pld         [r0, r1]
645    vmov.u16    q14, #0x0014            // 20
646    vld1.u8 {q0}, [r0], r1      //q0=src[-2]
647    vld1.u8 {q1}, [r0], r1      //q1=src[-1]
648
649    pld         [r0]
650    pld         [r0, r1]
651    vshr.u16    q15, q14, #2            // 5
652    vld1.u8 {q2}, [r0], r1      //q2=src[0]
653    vld1.u8 {q3}, [r0], r1      //q3=src[1]
654    vld1.u8 {q8}, [r0], r1      //q8=src[2]
655
656w16_xy_03_luma_loop:
657
658    vld1.u8 {q9}, [r0], r1      //q9=src[3]
659
660    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d0, d2, d4, d6, d16, d18, d20, q14, q15
661    pld         [r0]
662    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d1, d3, d5, d7, d17, d19, d21, q14, q15
663    vld1.u8 {q0}, [r0], r1      //read 2nd row
664    vst1.u8 {q10}, [r2], r3         //write 1st 16Byte
665
666    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d2, d4, d6, d16, d18, d0, d20, q14, q15
667    pld         [r0]
668    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d3, d5, d7, d17, d19, d1, d21, q14, q15
669    vld1.u8 {q1}, [r0], r1      //read 3rd row
670    vst1.u8 {q10}, [r2], r3         //write 2nd 16Byte
671
672    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d4, d6, d16, d18, d0, d2, d20, q14, q15
673    pld         [r0]
674    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d5, d7, d17, d19, d1, d3, d21, q14, q15
675    vld1.u8 {q2}, [r0], r1      //read 4th row
676    vst1.u8 {q10}, [r2], r3         //write 3rd 16Byte
677
678    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d6, d16, d18, d0, d2, d4, d20, q14, q15
679    pld         [r0]
680    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d7, d17, d19, d1, d3, d5, d21, q14, q15
681    vld1.u8 {q3}, [r0], r1      //read 5th row
682    vst1.u8 {q10}, [r2], r3         //write 4th 16Byte
683
684    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d16, d18, d0, d2, d4, d6, d20, q14, q15
685    pld         [r0]
686    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d17, d19, d1, d3, d5, d7, d21, q14, q15
687    vld1.u8 {q8}, [r0], r1      //read 6th row
688    vst1.u8 {q10}, [r2], r3         //write 5th 16Byte
689
690    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d18, d0, d2, d4, d6, d16, d20, q14, q15
691    pld         [r0]
692    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d19, d1, d3, d5, d7, d17, d21, q14, q15
693    vld1.u8 {q9}, [r0], r1      //read 7th row
694    vst1.u8 {q10}, [r2], r3         //write 6th 16Byte
695
696    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d0, d2, d4, d6, d16, d18, d20, q14, q15
697    pld         [r0]
698    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d1, d3, d5, d7, d17, d19, d21, q14, q15
699    vld1.u8 {q0}, [r0], r1      //read 8th row
700    vst1.u8 {q10}, [r2], r3         //write 7th 16Byte
701
702    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d2, d4, d6, d16, d18, d0, d20, q14, q15
703    pld         [r0]
704    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d3, d5, d7, d17, d19, d1, d21, q14, q15
705    vst1.u8 {q10}, [r2], r3         //write 8th 16Byte
706
707    //q2, q3, q8, q9, q0 --> q0~q8
708    vswp    q0, q8
709    vswp    q0, q2
710    vmov    q1, q3
711    vmov    q3, q9                      //q0~q8
712
713    sub     r4, #8
714    cmp     r4, #0
715    bne     w16_xy_03_luma_loop
716    pop     {r4}
717WELS_ASM_FUNC_END
718
719
720WELS_ASM_FUNC_BEGIN McHorVer03WidthEq8_neon
721    push        {r4}
722    ldr         r4, [sp, #4]
723
724    sub         r0, r0, r1, lsl #1      //src[-2*src_stride]
725    pld         [r0]
726    pld         [r0, r1]
727    vmov.u16    q14, #0x0014            // 20
728    vld1.u8 {d0}, [r0], r1      //d0=src[-2]
729    vld1.u8 {d1}, [r0], r1      //d1=src[-1]
730
731    pld         [r0]
732    pld         [r0, r1]
733    vshr.u16    q15, q14, #2            // 5
734    vld1.u8 {d2}, [r0], r1      //d2=src[0]
735    vld1.u8 {d3}, [r0], r1      //d3=src[1]
736
737    vld1.u8 {d4}, [r0], r1      //d4=src[2]
738    vld1.u8 {d5}, [r0], r1      //d5=src[3]
739
740w8_xy_03_mc_luma_loop:
741
742    pld         [r0]
743    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d0, d1, d2, d3, d4, d5, d16, q14, q15
744    vld1.u8 {d0}, [r0], r1      //read 2nd row
745    vst1.u8 {d16}, [r2], r3     //write 1st 8Byte
746
747    pld         [r0]
748    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d1, d2, d3, d4, d5, d0, d16, q14, q15
749    vld1.u8 {d1}, [r0], r1      //read 3rd row
750    vst1.u8 {d16}, [r2], r3     //write 2nd 8Byte
751
752    pld         [r0]
753    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d2, d3, d4, d5, d0, d1, d16, q14, q15
754    vld1.u8 {d2}, [r0], r1      //read 4th row
755    vst1.u8 {d16}, [r2], r3     //write 3rd 8Byte
756
757    pld         [r0]
758    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d3, d4, d5, d0, d1, d2, d16, q14, q15
759    vld1.u8 {d3}, [r0], r1      //read 5th row
760    vst1.u8 {d16}, [r2], r3     //write 4th 8Byte
761
762    //d4, d5, d0, d1, d2, d3 --> d0, d1, d2, d3, d4, d5
763    vswp    q0, q2
764    vswp    q1, q2
765
766    sub     r4, #4
767    cmp     r4, #0
768    bne     w8_xy_03_mc_luma_loop
769
770    pop     {r4}
771WELS_ASM_FUNC_END
772
773
774WELS_ASM_FUNC_BEGIN McHorVer03WidthEq4_neon
775    push        {r4, r5, r6, r7}
776    sub         r0, r0, r1, lsl #1      //src[-2*src_stride]
777    pld         [r0]
778    pld         [r0, r1]
779    vmov.u16    q14, #0x0014            // 20
780    ldr     r4, [r0], r1        //r4=src[-2]
781    ldr     r5, [r0], r1        //r5=src[-1]
782
783    pld         [r0]
784    pld         [r0, r1]
785    vshr.u16    q15, q14, #2            // 5
786    ldr     r6, [r0], r1        //r6=src[0]
787    ldr     r7, [r0], r1        //r7=src[1]
788
789    vmov        d0, r4, r5
790    vmov        d1, r5, r6
791    vmov        d2, r6, r7
792
793    ldr     r4, [r0], r1        //r4=src[2]
794    vmov        d3, r7, r4
795    ldr         r7, [sp, #16]
796
797w4_xy_03_mc_luma_loop:
798
799//  pld         [r0]
800    //using reserving r4
801    ldr     r5, [r0], r1        //r5=src[3]
802    ldr     r6, [r0], r1        //r6=src[0]
803    vmov        d4, r4, r5
804    vmov        d5, r5, r6          //reserved r6
805
806    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d0, d1, d2, d3, d4, d5, d16, q14, q15
807    vmov        r4, r5, d16
808    str r4, [r2], r3            //write 1st 4Byte
809    str r5, [r2], r3            //write 2nd 4Byte
810
811    ldr     r5, [r0], r1        //r5=src[1]
812    ldr     r4, [r0], r1        //r4=src[2]
813    vmov        d0, r6, r5
814    vmov        d1, r5, r4          //reserved r4
815
816    FILTER_6TAG_8BITS_AVERAGE_WITH_1    d2, d3, d4, d5, d0, d1, d16, q14, q15
817    vmov        r5, r6, d16
818    str r5, [r2], r3            //write 3rd 4Byte
819    str r6, [r2], r3            //write 4th 4Byte
820
821    //d4, d5, d0, d1 --> d0, d1, d2, d3
822    vmov    q1, q0
823    vmov    q0, q2
824
825    sub     r7, #4
826    cmp     r7, #0
827    bne     w4_xy_03_mc_luma_loop
828
829    pop     {r4, r5, r6, r7}
830WELS_ASM_FUNC_END
831
832
833WELS_ASM_FUNC_BEGIN McHorVer02WidthEq16_neon
834    push        {r4}
835    ldr         r4, [sp, #4]
836
837    sub         r0, r0, r1, lsl #1      //src[-2*src_stride]
838    pld         [r0]
839    pld         [r0, r1]
840    vmov.u16    q14, #0x0014            // 20
841    vld1.u8 {q0}, [r0], r1      //q0=src[-2]
842    vld1.u8 {q1}, [r0], r1      //q1=src[-1]
843
844    pld         [r0]
845    pld         [r0, r1]
846    vshr.u16    q15, q14, #2            // 5
847    vld1.u8 {q2}, [r0], r1      //q2=src[0]
848    vld1.u8 {q3}, [r0], r1      //q3=src[1]
849    vld1.u8 {q8}, [r0], r1      //q8=src[2]
850
851w16_v_mc_luma_loop:
852
853    vld1.u8 {q9}, [r0], r1      //q9=src[3]
854
855    FILTER_6TAG_8BITS   d0, d2, d4, d6, d16, d18, d20, q14, q15
856    pld         [r0]
857    FILTER_6TAG_8BITS   d1, d3, d5, d7, d17, d19, d21, q14, q15
858    vld1.u8 {q0}, [r0], r1      //read 2nd row
859    vst1.u8 {q10}, [r2], r3         //write 1st 16Byte
860
861    FILTER_6TAG_8BITS   d2, d4, d6, d16, d18, d0, d20, q14, q15
862    pld         [r0]
863    FILTER_6TAG_8BITS   d3, d5, d7, d17, d19, d1, d21, q14, q15
864    vld1.u8 {q1}, [r0], r1      //read 3rd row
865    vst1.u8 {q10}, [r2], r3         //write 2nd 16Byte
866
867    FILTER_6TAG_8BITS   d4, d6, d16, d18, d0, d2, d20, q14, q15
868    pld         [r0]
869    FILTER_6TAG_8BITS   d5, d7, d17, d19, d1, d3, d21, q14, q15
870    vld1.u8 {q2}, [r0], r1      //read 4th row
871    vst1.u8 {q10}, [r2], r3         //write 3rd 16Byte
872
873    FILTER_6TAG_8BITS   d6, d16, d18, d0, d2, d4, d20, q14, q15
874    pld         [r0]
875    FILTER_6TAG_8BITS   d7, d17, d19, d1, d3, d5, d21, q14, q15
876    vld1.u8 {q3}, [r0], r1      //read 5th row
877    vst1.u8 {q10}, [r2], r3         //write 4th 16Byte
878
879    FILTER_6TAG_8BITS   d16, d18, d0, d2, d4, d6, d20, q14, q15
880    pld         [r0]
881    FILTER_6TAG_8BITS   d17, d19, d1, d3, d5, d7, d21, q14, q15
882    vld1.u8 {q8}, [r0], r1      //read 6th row
883    vst1.u8 {q10}, [r2], r3         //write 5th 16Byte
884
885    FILTER_6TAG_8BITS   d18, d0, d2, d4, d6, d16, d20, q14, q15
886    pld         [r0]
887    FILTER_6TAG_8BITS   d19, d1, d3, d5, d7, d17, d21, q14, q15
888    vld1.u8 {q9}, [r0], r1      //read 7th row
889    vst1.u8 {q10}, [r2], r3         //write 6th 16Byte
890
891    FILTER_6TAG_8BITS   d0, d2, d4, d6, d16, d18, d20, q14, q15
892    pld         [r0]
893    FILTER_6TAG_8BITS   d1, d3, d5, d7, d17, d19, d21, q14, q15
894    vld1.u8 {q0}, [r0], r1      //read 8th row
895    vst1.u8 {q10}, [r2], r3         //write 7th 16Byte
896
897    FILTER_6TAG_8BITS   d2, d4, d6, d16, d18, d0, d20, q14, q15
898    pld         [r0]
899    FILTER_6TAG_8BITS   d3, d5, d7, d17, d19, d1, d21, q14, q15
900    vst1.u8 {q10}, [r2], r3         //write 8th 16Byte
901
902    //q2, q3, q8, q9, q0 --> q0~q8
903    vswp    q0, q8
904    vswp    q0, q2
905    vmov    q1, q3
906    vmov    q3, q9                      //q0~q8
907
908    sub     r4, #8
909    cmp     r4, #0
910    bne     w16_v_mc_luma_loop
911    pop     {r4}
912WELS_ASM_FUNC_END
913
914
915WELS_ASM_FUNC_BEGIN McHorVer02WidthEq8_neon
916    push        {r4}
917    ldr         r4, [sp, #4]
918
919    sub         r0, r0, r1, lsl #1      //src[-2*src_stride]
920    pld         [r0]
921    pld         [r0, r1]
922    vmov.u16    q14, #0x0014            // 20
923    vld1.u8 {d0}, [r0], r1      //d0=src[-2]
924    vld1.u8 {d1}, [r0], r1      //d1=src[-1]
925
926    pld         [r0]
927    pld         [r0, r1]
928    vshr.u16    q15, q14, #2            // 5
929    vld1.u8 {d2}, [r0], r1      //d2=src[0]
930    vld1.u8 {d3}, [r0], r1      //d3=src[1]
931
932    vld1.u8 {d4}, [r0], r1      //d4=src[2]
933    vld1.u8 {d5}, [r0], r1      //d5=src[3]
934
935w8_v_mc_luma_loop:
936
937    pld         [r0]
938    FILTER_6TAG_8BITS   d0, d1, d2, d3, d4, d5, d16, q14, q15
939    vld1.u8 {d0}, [r0], r1      //read 2nd row
940    vst1.u8 {d16}, [r2], r3     //write 1st 8Byte
941
942    pld         [r0]
943    FILTER_6TAG_8BITS   d1, d2, d3, d4, d5, d0, d16, q14, q15
944    vld1.u8 {d1}, [r0], r1      //read 3rd row
945    vst1.u8 {d16}, [r2], r3     //write 2nd 8Byte
946
947    pld         [r0]
948    FILTER_6TAG_8BITS   d2, d3, d4, d5, d0, d1, d16, q14, q15
949    vld1.u8 {d2}, [r0], r1      //read 4th row
950    vst1.u8 {d16}, [r2], r3     //write 3rd 8Byte
951
952    pld         [r0]
953    FILTER_6TAG_8BITS   d3, d4, d5, d0, d1, d2, d16, q14, q15
954    vld1.u8 {d3}, [r0], r1      //read 5th row
955    vst1.u8 {d16}, [r2], r3     //write 4th 8Byte
956
957    //d4, d5, d0, d1, d2, d3 --> d0, d1, d2, d3, d4, d5
958    vswp    q0, q2
959    vswp    q1, q2
960
961    sub     r4, #4
962    cmp     r4, #0
963    bne     w8_v_mc_luma_loop
964
965    pop     {r4}
966WELS_ASM_FUNC_END
967
968
969WELS_ASM_FUNC_BEGIN McHorVer02WidthEq4_neon
970    push        {r4, r5, r6, r7}
971    sub         r0, r0, r1, lsl #1      //src[-2*src_stride]
972    pld         [r0]
973    pld         [r0, r1]
974    vmov.u16    q14, #0x0014            // 20
975    ldr     r4, [r0], r1        //r4=src[-2]
976    ldr     r5, [r0], r1        //r5=src[-1]
977
978    pld         [r0]
979    pld         [r0, r1]
980    vshr.u16    q15, q14, #2            // 5
981    ldr     r6, [r0], r1        //r6=src[0]
982    ldr     r7, [r0], r1        //r7=src[1]
983
984    vmov        d0, r4, r5
985    vmov        d1, r5, r6
986    vmov        d2, r6, r7
987
988    ldr     r4, [r0], r1        //r4=src[2]
989    vmov        d3, r7, r4
990    ldr         r7, [sp, #16]
991
992w4_v_mc_luma_loop:
993
994//  pld         [r0]
995    //using reserving r4
996    ldr     r5, [r0], r1        //r5=src[3]
997    ldr     r6, [r0], r1        //r6=src[0]
998    vmov        d4, r4, r5
999    vmov        d5, r5, r6          //reserved r6
1000
1001    FILTER_6TAG_8BITS   d0, d1, d2, d3, d4, d5, d16, q14, q15
1002    vmov        r4, r5, d16
1003    str r4, [r2], r3            //write 1st 4Byte
1004    str r5, [r2], r3            //write 2nd 4Byte
1005
1006    ldr     r5, [r0], r1        //r5=src[1]
1007    ldr     r4, [r0], r1        //r4=src[2]
1008    vmov        d0, r6, r5
1009    vmov        d1, r5, r4          //reserved r4
1010
1011    FILTER_6TAG_8BITS   d2, d3, d4, d5, d0, d1, d16, q14, q15
1012    vmov        r5, r6, d16
1013    str r5, [r2], r3            //write 3rd 4Byte
1014    str r6, [r2], r3            //write 4th 4Byte
1015
1016    //d4, d5, d0, d1 --> d0, d1, d2, d3
1017    vmov    q1, q0
1018    vmov    q0, q2
1019
1020    sub     r7, #4
1021    cmp     r7, #0
1022    bne     w4_v_mc_luma_loop
1023
1024    pop     {r4, r5, r6, r7}
1025WELS_ASM_FUNC_END
1026
1027
1028WELS_ASM_FUNC_BEGIN McHorVer22WidthEq16_neon
1029    push        {r4}
1030    vpush       {q4-q7}
1031    ldr         r4, [sp, #68]
1032
1033    sub         r0, #2                  //src[-2]
1034    sub         r0, r0, r1, lsl #1      //src[-2*src_stride-2]
1035    pld         [r0]
1036    pld         [r0, r1]
1037
1038    vmov.u16    q14, #0x0014            // 20
1039    vld1.u8 {d0-d2}, [r0], r1       //use 21(16+5), =src[-2]
1040    vld1.u8 {d3-d5}, [r0], r1       //use 21(16+5), =src[-1]
1041
1042    pld         [r0]
1043    pld         [r0, r1]
1044    vshr.u16    q15, q14, #2            // 5
1045
1046    vld1.u8 {d6-d8}, [r0], r1       //use 21(16+5), =src[0]
1047    vld1.u8 {d9-d11}, [r0], r1  //use 21(16+5), =src[1]
1048    pld         [r0]
1049    pld         [r0, r1]
1050    vld1.u8 {d12-d14}, [r0], r1 //use 21(16+5), =src[2]
1051
1052w16_hv_mc_luma_loop:
1053
1054    vld1.u8 {d15-d17}, [r0], r1 //use 21(16+5), =src[3]
1055    //the 1st row
1056    pld         [r0]
1057    // vertical filtered into q9/q10
1058    FILTER_6TAG_8BITS_TO_16BITS     d0, d3, d6, d9, d12, d15, q9, q14, q15  // 8 avail
1059    FILTER_6TAG_8BITS_TO_16BITS     d1, d4, d7,d10, d13, d16,q10, q14, q15  // 8 avail
1060    // horizon filtered
1061    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
1062    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d0   //output to q0[0]
1063
1064    // vertical filtered into q10/q11
1065    FILTER_6TAG_8BITS_TO_16BITS     d2, d5, d8,d11, d14, d17,q11, q14, q15  // only 5 avail
1066    // horizon filtered
1067    UNPACK_2_16BITS_TO_ABC  q10, q11, q9, q12, q13
1068    FILTER_3_IN_16BITS_TO_8BITS q9, q12, q13, d1    //output to q0[1]
1069    vst1.u8 {q0}, [r2], r3      //write 16Byte
1070
1071
1072    vld1.u8 {d0-d2}, [r0], r1       //read 2nd row
1073    //the 2nd row
1074    pld         [r0]
1075    // vertical filtered into q9/q10
1076    FILTER_6TAG_8BITS_TO_16BITS     d3, d6, d9, d12, d15, d0, q9, q14, q15  // 8 avail
1077    FILTER_6TAG_8BITS_TO_16BITS     d4, d7,d10, d13, d16, d1,q10, q14, q15  // 8 avail
1078    // horizon filtered
1079    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
1080    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d3   //output to d3
1081
1082    // vertical filtered into q10/q11
1083    FILTER_6TAG_8BITS_TO_16BITS     d5, d8,d11, d14, d17, d2,q11, q14, q15  // only 5 avail
1084    // horizon filtered
1085    UNPACK_2_16BITS_TO_ABC  q10, q11, q9, q12, q13
1086    FILTER_3_IN_16BITS_TO_8BITS q9, q12, q13, d4    //output to d4
1087
1088    vst1.u8 {d3, d4}, [r2], r3      //write 16Byte
1089
1090    vld1.u8 {d3-d5}, [r0], r1       //read 3rd row
1091    //the 3rd row
1092    pld         [r0]
1093    // vertical filtered into q9/q10
1094    FILTER_6TAG_8BITS_TO_16BITS     d6, d9, d12, d15, d0, d3, q9, q14, q15  // 8 avail
1095    FILTER_6TAG_8BITS_TO_16BITS     d7,d10, d13, d16, d1, d4,q10, q14, q15  // 8 avail
1096    // horizon filtered
1097    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
1098    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d6   //output to d6
1099
1100    // vertical filtered into q10/q11
1101    FILTER_6TAG_8BITS_TO_16BITS     d8,d11, d14, d17, d2, d5,q11, q14, q15  // only 5 avail
1102    // horizon filtered
1103    UNPACK_2_16BITS_TO_ABC  q10, q11, q9, q12, q13
1104    FILTER_3_IN_16BITS_TO_8BITS q9, q12, q13, d7    //output to d7
1105    vst1.u8 {d6, d7}, [r2], r3      //write 16Byte
1106
1107    vld1.u8 {d6-d8}, [r0], r1       //read 4th row
1108    //the 4th row
1109    pld         [r0]
1110    // vertical filtered into q9/q10
1111    FILTER_6TAG_8BITS_TO_16BITS      d9, d12, d15, d0, d3, d6, q9, q14, q15 // 8 avail
1112    FILTER_6TAG_8BITS_TO_16BITS     d10, d13, d16, d1, d4, d7,q10, q14, q15 // 8 avail
1113    // horizon filtered
1114    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
1115    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d9   //output to d9
1116    // vertical filtered into q10/q11
1117    FILTER_6TAG_8BITS_TO_16BITS     d11, d14, d17, d2, d5, d8,q11, q14, q15 // only 5 avail
1118    // horizon filtered
1119    UNPACK_2_16BITS_TO_ABC  q10, q11, q9, q12, q13
1120    FILTER_3_IN_16BITS_TO_8BITS q9, q12, q13, d10   //output to d10
1121    vst1.u8 {d9, d10}, [r2], r3     //write 16Byte
1122
1123    //d12~d17(q6~q8), d0~d8(q0~q3+d8), --> d0~d14
1124    vswp    q0, q6
1125    vswp    q6, q3
1126    vmov    q5, q2
1127    vmov    q2, q8
1128
1129    vmov    d20,d8
1130    vmov    q4, q1
1131    vmov    q1, q7
1132    vmov    d14,d20
1133
1134    sub     r4, #4
1135    cmp     r4, #0
1136    bne     w16_hv_mc_luma_loop
1137    vpop        {q4-q7}
1138    pop     {r4}
1139WELS_ASM_FUNC_END
1140
1141
1142WELS_ASM_FUNC_BEGIN McHorVer22WidthEq8_neon
1143    push        {r4}
1144    vpush       {q4}
1145    ldr         r4, [sp, #20]
1146
1147    sub         r0, #2              //src[-2]
1148    sub         r0, r0, r1, lsl #1  //src[-2*src_stride-2]
1149    pld         [r0]
1150    pld         [r0, r1]
1151
1152    vmov.u16    q14, #0x0014        // 20
1153    vld1.u8 {q0}, [r0], r1  //use 13(8+5), =src[-2]
1154    vld1.u8 {q1}, [r0], r1  //use 13(8+5), =src[-1]
1155
1156    pld         [r0]
1157    pld         [r0, r1]
1158    vshr.u16    q15, q14, #2        // 5
1159
1160    vld1.u8 {q2}, [r0], r1  //use 13(8+5), =src[0]
1161    vld1.u8 {q3}, [r0], r1  //use 13(8+5), =src[1]
1162    pld         [r0]
1163    pld         [r0, r1]
1164    vld1.u8 {q4}, [r0], r1  //use 13(8+5), =src[2]
1165
1166w8_hv_mc_luma_loop:
1167
1168    vld1.u8 {q8}, [r0], r1  //use 13(8+5), =src[3]
1169    //the 1st row
1170    pld         [r0]
1171    // vertical filtered into q9/q10
1172    FILTER_6TAG_8BITS_TO_16BITS     d0, d2, d4, d6, d8, d16, q9, q14, q15   // 8 avail
1173    FILTER_6TAG_8BITS_TO_16BITS     d1, d3, d5, d7, d9, d17, q10, q14, q15  // 5 avail
1174    // horizon filtered
1175    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
1176    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18  //output to q9[0]
1177    vst1.u8 d18, [r2], r3           //write 8Byte
1178
1179    vld1.u8 {q0}, [r0], r1      //read 2nd row
1180    //the 2nd row
1181    pld         [r0]
1182    // vertical filtered into q9/q10
1183    FILTER_6TAG_8BITS_TO_16BITS     d2, d4, d6, d8, d16, d0, q9, q14, q15   // 8 avail
1184    FILTER_6TAG_8BITS_TO_16BITS     d3, d5, d7, d9, d17, d1, q10, q14, q15  // 5 avail
1185    // horizon filtered
1186    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
1187    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18  //output to q9[0]
1188    vst1.u8 d18, [r2], r3       //write 8Byte
1189
1190    vld1.u8 {q1}, [r0], r1      //read 3rd row
1191    //the 3rd row
1192    pld         [r0]
1193    // vertical filtered into q9/q10
1194    FILTER_6TAG_8BITS_TO_16BITS     d4, d6, d8, d16, d0, d2, q9, q14, q15   // 8 avail
1195    FILTER_6TAG_8BITS_TO_16BITS     d5, d7, d9, d17, d1, d3, q10, q14, q15  // 5 avail
1196    // horizon filtered
1197    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
1198    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18  //output to q9[0]
1199    vst1.u8 d18, [r2], r3           //write 8Byte
1200
1201    vld1.u8 {q2}, [r0], r1      //read 4th row
1202    //the 4th row
1203    pld         [r0]
1204    // vertical filtered into q9/q10
1205    FILTER_6TAG_8BITS_TO_16BITS     d6, d8, d16, d0, d2, d4, q9, q14, q15   // 8 avail
1206    FILTER_6TAG_8BITS_TO_16BITS     d7, d9, d17, d1, d3, d5, q10, q14, q15  // 5 avail
1207    // horizon filtered
1208    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
1209    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18  //output to q9[0]
1210    vst1.u8 d18, [r2], r3           //write 8Byte
1211
1212    //q4~q5, q0~q2, --> q0~q4
1213    vswp    q0, q4
1214    vswp    q2, q4
1215    vmov    q3, q1
1216    vmov    q1, q8
1217
1218    sub     r4, #4
1219    cmp     r4, #0
1220    bne     w8_hv_mc_luma_loop
1221    vpop        {q4}
1222    pop     {r4}
1223WELS_ASM_FUNC_END
1224
1225
1226WELS_ASM_FUNC_BEGIN McHorVer22WidthEq4_neon
1227    push        {r4 ,r5, r6}
1228    vpush       {q4-q7}
1229    ldr         r6, [sp, #76]
1230
1231    sub         r0, #2              //src[-2]
1232    sub         r0, r0, r1, lsl #1  //src[-2*src_stride-2]
1233    pld         [r0]
1234    pld         [r0, r1]
1235
1236    vmov.u16    q14, #0x0014        // 20
1237    vld1.u8 {q0}, [r0], r1  //use 9(4+5), =src[-2]
1238    vld1.u8 {q1}, [r0], r1  //use 9(4+5), =src[-1]
1239
1240    pld         [r0]
1241    pld         [r0, r1]
1242    vshr.u16    q15, q14, #2        // 5
1243
1244    vld1.u8 {q2}, [r0], r1  //use 9(4+5), =src[0]
1245    vld1.u8 {q3}, [r0], r1  //use 9(4+5), =src[1]
1246    pld         [r0]
1247    pld         [r0, r1]
1248    vld1.u8 {q4}, [r0], r1  //use 9(4+5), =src[2]
1249
1250w4_hv_mc_luma_loop:
1251
1252    vld1.u8 {q5}, [r0], r1  //use 9(4+5), =src[3]
1253    vld1.u8 {q6}, [r0], r1  //use 9(4+5), =src[4]
1254
1255    //the 1st&2nd row
1256    pld         [r0]
1257    pld         [r0, r1]
1258    // vertical filtered
1259    FILTER_6TAG_8BITS_TO_16BITS     d0, d2, d4, d6, d8, d10, q7, q14, q15   // 8 avail
1260    FILTER_6TAG_8BITS_TO_16BITS     d1, d3, d5, d7, d9, d11, q8, q14, q15   // 1 avail
1261
1262    FILTER_6TAG_8BITS_TO_16BITS     d2, d4, d6, d8,d10, d12, q9, q14, q15   // 8 avail
1263    FILTER_6TAG_8BITS_TO_16BITS     d3, d5, d7, d9,d11, d13,q10, q14, q15   // 1 avail
1264    // horizon filtered
1265    UNPACK_2_16BITS_TO_ABC  q7, q8, q11, q12, q13   //4 avail
1266    UNPACK_2_16BITS_TO_ABC  q9,q10, q0, q7, q8      //4 avail
1267
1268    vmov    d23, d0
1269    vmov    d25, d14
1270    vmov    d27, d16
1271
1272    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d22  //output to q11[0]
1273    vmov        r4 ,r5, d22
1274    str     r4, [r2], r3                //write 4Byte
1275    str     r5, [r2], r3                //write 4Byte
1276
1277    //the 3rd&4th row
1278    vld1.u8 {q0}, [r0], r1  //use 9(4+5), =src[3]
1279    vld1.u8 {q1}, [r0], r1  //use 9(4+5), =src[4]
1280    pld         [r0]
1281    pld         [r0, r1]
1282    // vertical filtered
1283    FILTER_6TAG_8BITS_TO_16BITS     d4, d6, d8, d10, d12, d0, q7, q14, q15  // 8 avail
1284    FILTER_6TAG_8BITS_TO_16BITS     d5, d7, d9, d11, d13, d1, q8, q14, q15  // 1 avail
1285
1286    FILTER_6TAG_8BITS_TO_16BITS     d6, d8,d10, d12, d0, d2, q9, q14, q15   // 8 avail
1287    FILTER_6TAG_8BITS_TO_16BITS     d7, d9,d11, d13, d1, d3,q10, q14, q15   // 1 avail
1288    // horizon filtered
1289    UNPACK_2_16BITS_TO_ABC  q7, q8, q11, q12, q13   //4 avail
1290    UNPACK_2_16BITS_TO_ABC  q9,q10, q2, q7, q8      //4 avail
1291
1292    vmov    d23, d4
1293    vmov    d25, d14
1294    vmov    d27, d16
1295
1296    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d22  //output to q11[0]
1297    vmov        r4 ,r5, d22
1298    str     r4, [r2], r3                //write 4Byte
1299    str     r5, [r2], r3                //write 4Byte
1300
1301    //q4~q6, q0~q1, --> q0~q4
1302    vswp    q4, q0
1303    vmov    q3, q4
1304    vmov    q4, q1
1305    vmov    q1, q5
1306    vmov    q2, q6
1307
1308    sub     r6, #4
1309    cmp     r6, #0
1310    bne     w4_hv_mc_luma_loop
1311
1312    vpop        {q4-q7}
1313    pop     {r4, r5, r6}
1314WELS_ASM_FUNC_END
1315
1316
1317WELS_ASM_FUNC_BEGIN McCopyWidthEq16_neon
1318    push        {r4}
1319    ldr         r4, [sp, #4]
1320w16_copy_loop:
1321    vld1.u8     {q0}, [r0], r1
1322    sub         r4, #2
1323    vld1.u8     {q1}, [r0], r1
1324    vst1.u8     {q0}, [r2], r3
1325    cmp         r4, #0
1326    vst1.u8     {q1}, [r2], r3
1327    bne         w16_copy_loop
1328
1329    pop     {r4}
1330WELS_ASM_FUNC_END
1331
1332
1333WELS_ASM_FUNC_BEGIN McCopyWidthEq8_neon
1334    push        {r4}
1335    ldr         r4, [sp, #4]
1336w8_copy_loop:
1337    vld1.u8     {d0}, [r0], r1
1338    vld1.u8     {d1}, [r0], r1
1339    vst1.u8     {d0}, [r2], r3
1340    vst1.u8     {d1}, [r2], r3
1341    sub         r4, #2
1342    cmp         r4, #0
1343    bne         w8_copy_loop
1344
1345    pop     {r4}
1346WELS_ASM_FUNC_END
1347
1348
1349WELS_ASM_FUNC_BEGIN McCopyWidthEq4_neon
1350    push        {r4, r5, r6}
1351    ldr         r4, [sp, #12]
1352w4_copy_loop:
1353    ldr     r5, [r0], r1
1354    ldr     r6, [r0], r1
1355    str     r5, [r2], r3
1356    str     r6, [r2], r3
1357
1358    sub         r4, #2
1359    cmp         r4, #0
1360    bne         w4_copy_loop
1361
1362    pop     {r4, r5, r6}
1363WELS_ASM_FUNC_END
1364
1365
1366WELS_ASM_FUNC_BEGIN PixelAvgWidthEq16_neon
1367    push        {r4}
1368    ldr         r4, [sp, #4]
1369w16_pix_avg_loop:
1370    vld1.u8     {q0}, [r2]!
1371    vld1.u8     {q1}, [r3]!
1372    vld1.u8     {q2}, [r2]!
1373    vld1.u8     {q3}, [r3]!
1374
1375    vld1.u8     {q8}, [r2]!
1376    vld1.u8     {q9}, [r3]!
1377    vld1.u8     {q10}, [r2]!
1378    vld1.u8     {q11}, [r3]!
1379
1380    AVERAGE_TWO_8BITS       d0, d0, d2
1381    AVERAGE_TWO_8BITS       d1, d1, d3
1382    vst1.u8     {q0}, [r0], r1
1383
1384    AVERAGE_TWO_8BITS       d4, d4, d6
1385    AVERAGE_TWO_8BITS       d5, d5, d7
1386    vst1.u8     {q2}, [r0], r1
1387
1388    AVERAGE_TWO_8BITS       d16, d16, d18
1389    AVERAGE_TWO_8BITS       d17, d17, d19
1390    vst1.u8     {q8}, [r0], r1
1391
1392    AVERAGE_TWO_8BITS       d20, d20, d22
1393    AVERAGE_TWO_8BITS       d21, d21, d23
1394    vst1.u8     {q10}, [r0], r1
1395
1396    sub         r4, #4
1397    cmp         r4, #0
1398    bne         w16_pix_avg_loop
1399
1400    pop     {r4}
1401WELS_ASM_FUNC_END
1402
1403
1404WELS_ASM_FUNC_BEGIN PixelAvgWidthEq8_neon
1405    push        {r4, r5}
1406    ldr         r4, [sp, #8]
1407    mov         r5, #16
1408w8_pix_avg_loop:
1409
1410    vld1.u8     {d0}, [r2], r5
1411    vld1.u8     {d2}, [r3], r5
1412    vld1.u8     {d1}, [r2], r5
1413    vld1.u8     {d3}, [r3], r5
1414
1415    AVERAGE_TWO_8BITS       d0, d0, d2
1416    AVERAGE_TWO_8BITS       d1, d1, d3
1417    vst1.u8     {d0}, [r0], r1
1418    vst1.u8     {d1}, [r0], r1
1419
1420    vld1.u8     {d4}, [r2], r5
1421    vld1.u8     {d6}, [r3], r5
1422    vld1.u8     {d5}, [r2], r5
1423    vld1.u8     {d7}, [r3], r5
1424
1425    AVERAGE_TWO_8BITS       d4, d4, d6
1426    AVERAGE_TWO_8BITS       d5, d5, d7
1427    vst1.u8     {d4}, [r0], r1
1428    vst1.u8     {d5}, [r0], r1
1429
1430    sub         r4, #4
1431    cmp         r4, #0
1432    bne         w8_pix_avg_loop
1433
1434    pop     {r4, r5}
1435WELS_ASM_FUNC_END
1436
1437
1438WELS_ASM_FUNC_BEGIN PixelAvgWidthEq4_neon
1439    push        {r4-r8}
1440    ldr         r4, [sp, #20]
1441w4_pix_avg_loop:
1442
1443    ldr     r5, [r2]
1444    ldr     r6, [r2, #16]
1445    ldr     r7, [r3]
1446    ldr     r8, [r3, #16]
1447    add     r2, #32
1448    add     r3, #32
1449
1450    vmov        d0, r5, r6
1451    vmov        d1, r7, r8
1452    AVERAGE_TWO_8BITS       d0, d0, d1
1453    vmov        r5, r6, d0
1454
1455    str     r5, [r0], r1
1456    str     r6, [r0], r1
1457
1458    sub         r4, #2
1459    cmp         r4, #0
1460    bne         w4_pix_avg_loop
1461
1462    pop     {r4-r8}
1463WELS_ASM_FUNC_END
1464
1465WELS_ASM_FUNC_BEGIN McChromaWidthEq8_neon
1466    push        {r4, r5}
1467    ldr         r4, [sp, #8]
1468    ldr         r5, [sp, #12]
1469//  normal case: {cA*src[x]  + cB*src[x+1]} + {cC*src[x+stride] + cD*srcp[x+stride+1]}
1470//  we can opti it by adding vert only/ hori only cases, to be continue
1471    vld1.u8 {d31}, [r4]     //load A/B/C/D
1472    vld1.u8     {q0}, [r0], r1  //src[x]
1473
1474    vdup.u8 d28, d31[0]         //A
1475    vdup.u8 d29, d31[1]         //B
1476    vdup.u8 d30, d31[2]         //C
1477    vdup.u8 d31, d31[3]         //D
1478
1479    vext.u8     d1, d0, d1, #1      //src[x+1]
1480
1481w8_mc_chroma_loop:  // each two pxl row
1482    vld1.u8     {q1}, [r0], r1  //src[x+stride]
1483    vld1.u8     {q2}, [r0], r1  //src[x+2*stride]
1484    vext.u8     d3, d2, d3, #1      //src[x+stride+1]
1485    vext.u8     d5, d4, d5, #1      //src[x+2*stride+1]
1486
1487    vmull.u8        q3, d0, d28         //(src[x] * A)
1488    vmlal.u8        q3, d1, d29         //+=(src[x+1] * B)
1489    vmlal.u8        q3, d2, d30         //+=(src[x+stride] * C)
1490    vmlal.u8        q3, d3, d31         //+=(src[x+stride+1] * D)
1491    vrshrn.u16      d6, q3, #6
1492    vst1.u8 d6, [r2], r3
1493
1494    vmull.u8        q3, d2, d28         //(src[x] * A)
1495    vmlal.u8        q3, d3, d29         //+=(src[x+1] * B)
1496    vmlal.u8        q3, d4, d30         //+=(src[x+stride] * C)
1497    vmlal.u8        q3, d5, d31         //+=(src[x+stride+1] * D)
1498    vrshrn.u16      d6, q3, #6
1499    vst1.u8 d6, [r2], r3
1500
1501    vmov        q0, q2
1502    sub         r5, #2
1503    cmp         r5, #0
1504    bne         w8_mc_chroma_loop
1505
1506    pop     {r4, r5}
1507WELS_ASM_FUNC_END
1508
1509
1510WELS_ASM_FUNC_BEGIN McChromaWidthEq4_neon
1511
1512    push        {r4, r5, r6}
1513    ldr         r4, [sp, #12]
1514    ldr         r6, [sp, #16]
1515//  normal case: {cA*src[x]  + cB*src[x+1]} + {cC*src[x+stride] + cD*srcp[x+stride+1]}
1516//  we can opti it by adding vert only/ hori only cases, to be continue
1517    vld1.u8 {d31}, [r4]     //load A/B/C/D
1518
1519    vdup.u8 d28, d31[0]         //A
1520    vdup.u8 d29, d31[1]         //B
1521    vdup.u8 d30, d31[2]         //C
1522    vdup.u8 d31, d31[3]         //D
1523
1524w4_mc_chroma_loop:  // each two pxl row
1525    vld1.u8     {d0}, [r0], r1  //a::src[x]
1526    vld1.u8     {d2}, [r0], r1  //b::src[x+stride]
1527    vld1.u8     {d4}, [r0]          //c::src[x+2*stride]
1528
1529    vshr.u64        d1, d0, #8
1530    vshr.u64        d3, d2, #8
1531    vshr.u64        d5, d4, #8
1532
1533    vmov            q3, q1              //b::[0:7]+b::[1~8]
1534    vtrn.32     q0, q1              //d0{a::[0:3]+b::[0:3]}; d1{a::[1:4]+b::[1:4]}
1535    vtrn.32     q3, q2              //d6{b::[0:3]+c::[0:3]}; d7{b::[1:4]+c::[1:4]}
1536
1537    vmull.u8        q1, d0, d28         //(src[x] * A)
1538    vmlal.u8        q1, d1, d29         //+=(src[x+1] * B)
1539    vmlal.u8        q1, d6, d30         //+=(src[x+stride] * C)
1540    vmlal.u8        q1, d7, d31         //+=(src[x+stride+1] * D)
1541
1542    vrshrn.u16      d2, q1, #6
1543    vmov        r4, r5, d2
1544    str r4, [r2], r3
1545    str r5, [r2], r3
1546
1547    sub         r6, #2
1548    cmp         r6, #0
1549    bne         w4_mc_chroma_loop
1550
1551    pop     {r4, r5, r6}
1552WELS_ASM_FUNC_END
1553
1554WELS_ASM_FUNC_BEGIN McHorVer20Width17_neon
1555    push        {r4-r5}
1556    mov         r4, #20
1557    mov         r5, #1
1558    sub         r4, r4, r4, lsl #(16-2)
1559    lsl         r5, #16
1560    ror         r4, #16
1561    vmov        d3, r5, r4                  // 0x0014FFFB00010000
1562
1563    sub         r3, #16
1564    ldr         r4, [sp, #8]
1565
1566    sub         r0, #2
1567    vmov.u16    q14, #0x0014                // 20
1568    vshr.u16    q15, q14, #2                // 5
1569
1570w17_h_mc_luma_loop:
1571    vld1.u8 {d0,d1,d2}, [r0], r1    //only use 22(17+5); q0=src[-2]
1572
1573    vext.8      q2, q0, q1, #1      //q2=src[-1]
1574    vext.8      q3, q0, q1, #2      //q3=src[0]
1575    vext.8      q8, q0, q1, #3      //q8=src[1]
1576    vext.8      q9, q0, q1, #4      //q9=src[2]
1577    vext.8      q10, q0, q1, #5     //q10=src[3]
1578
1579    FILTER_6TAG_8BITS   d0, d4, d6, d16, d18, d20, d22, q14, q15
1580
1581    FILTER_6TAG_8BITS   d1, d5, d7, d17, d19, d21, d23, q14, q15
1582
1583    vst1.u8 {d22, d23}, [r2]!       //write [0:15] Byte
1584
1585    vsli.64 d2, d2, #8              // [0][1][2][3][4][5]XO-->O[0][1][2][3][4][5]X
1586    FILTER_SINGLE_TAG_8BITS d2, d3, d22, q11, q1
1587
1588    vst1.u8 {d2[0]}, [r2], r3       //write 16th Byte
1589
1590    sub     r4, #1
1591    cmp     r4, #0
1592    bne     w17_h_mc_luma_loop
1593    pop     {r4-r5}
1594WELS_ASM_FUNC_END
1595
1596
1597WELS_ASM_FUNC_BEGIN McHorVer20Width9_neon
1598    push        {r4-r5}
1599    mov         r4, #20
1600    mov         r5, #1
1601    sub         r4, r4, r4, lsl #(16-2)
1602    lsl         r5, #16
1603    ror         r4, #16
1604    vmov        d7, r5, r4                  // 0x0014FFFB00010000
1605
1606    sub         r3, #8
1607    ldr         r4, [sp, #8]
1608
1609    sub         r0, #2
1610    vmov.u16    q14, #0x0014                // 20
1611    vshr.u16    q15, q14, #2                // 5
1612
1613w9_h_mc_luma_loop:
1614    vld1.u8 {d0,d1}, [r0], r1   //only use 14(9+5); q0=src[-2]
1615    pld         [r0]
1616
1617    vext.8      d2, d0, d1, #1      //d2=src[-1]
1618    vext.8      d3, d0, d1, #2      //d3=src[0]
1619    vext.8      d4, d0, d1, #3      //d4=src[1]
1620    vext.8      d5, d0, d1, #4      //d5=src[2]
1621    vext.8      d6, d0, d1, #5      //d6=src[3]
1622
1623    FILTER_6TAG_8BITS   d0, d2, d3, d4, d5, d6, d16, q14, q15
1624
1625    sub     r4, #1
1626    vst1.u8 {d16}, [r2]!        //write [0:7] Byte
1627
1628    vsli.64 d2, d1, #8              // [0][1][2][3][4][5]XO-->O[0][1][2][3][4][5]X
1629    FILTER_SINGLE_TAG_8BITS d2, d7, d18, q9, q1
1630    vst1.u8 {d2[0]}, [r2], r3       //write 8th Byte
1631
1632    cmp     r4, #0
1633    bne     w9_h_mc_luma_loop
1634    pop     {r4-r5}
1635WELS_ASM_FUNC_END
1636
1637
1638WELS_ASM_FUNC_BEGIN McHorVer20Width5_neon
1639    push        {r4}
1640    sub         r3, #4
1641    sub         r0, #2
1642    ldr         r4, [sp, #4]
1643    vmov.u16    q14, #0x0014                // 20
1644    vshr.u16    q15, q14, #2                // 5
1645
1646w5_h_mc_luma_loop:
1647    vld1.u8 {d0,d1}, [r0], r1   //only use 10(5+5); q0=src[-2]
1648    pld         [r0]
1649
1650    vext.8      d2, d0, d1, #1      //d2=src[-1]
1651    vext.8      d3, d0, d1, #2      //d3=src[0]
1652    vext.8      d4, d0, d1, #3      //d4=src[1]
1653    vext.8      d5, d0, d1, #4      //d5=src[2]
1654    vext.8      d6, d0, d1, #5      //d6=src[3]
1655
1656    FILTER_6TAG_8BITS   d0, d2, d3, d4, d5, d6, d16, q14, q15
1657
1658    sub     r4, #1
1659    vst1.u32 {d16[0]}, [r2]!        //write [0:3] Byte
1660    vst1.u8 {d16[4]}, [r2], r3       //write 5th Byte
1661
1662    cmp     r4, #0
1663    bne     w5_h_mc_luma_loop
1664    pop     {r4}
1665WELS_ASM_FUNC_END
1666
1667
1668WELS_ASM_FUNC_BEGIN McHorVer02Height17_neon
1669    push        {r4}
1670    ldr         r4, [sp, #4]
1671
1672    sub         r0, r0, r1, lsl #1      //src[-2*src_stride]
1673    pld         [r0]
1674    pld         [r0, r1]
1675    vmov.u16    q14, #0x0014            // 20
1676    vld1.u8 {q0}, [r0], r1      //q0=src[-2]
1677    vld1.u8 {q1}, [r0], r1      //q1=src[-1]
1678
1679    pld         [r0]
1680    pld         [r0, r1]
1681    vshr.u16    q15, q14, #2            // 5
1682    vld1.u8 {q2}, [r0], r1      //q2=src[0]
1683    vld1.u8 {q3}, [r0], r1      //q3=src[1]
1684    vld1.u8 {q8}, [r0], r1      //q8=src[2]
1685
1686w17_v_mc_luma_loop:
1687
1688    vld1.u8 {q9}, [r0], r1      //q9=src[3]
1689
1690    FILTER_6TAG_8BITS   d0, d2, d4, d6, d16, d18, d20, q14, q15
1691    pld         [r0]
1692    FILTER_6TAG_8BITS   d1, d3, d5, d7, d17, d19, d21, q14, q15
1693    vld1.u8 {q0}, [r0], r1      //read 2nd row
1694    vst1.u8 {q10}, [r2], r3         //write 1st 16Byte
1695
1696    FILTER_6TAG_8BITS   d2, d4, d6, d16, d18, d0, d20, q14, q15
1697    pld         [r0]
1698    FILTER_6TAG_8BITS   d3, d5, d7, d17, d19, d1, d21, q14, q15
1699    vld1.u8 {q1}, [r0], r1      //read 3rd row
1700    vst1.u8 {q10}, [r2], r3         //write 2nd 16Byte
1701
1702    FILTER_6TAG_8BITS   d4, d6, d16, d18, d0, d2, d20, q14, q15
1703    pld         [r0]
1704    FILTER_6TAG_8BITS   d5, d7, d17, d19, d1, d3, d21, q14, q15
1705    vld1.u8 {q2}, [r0], r1      //read 4th row
1706    vst1.u8 {q10}, [r2], r3         //write 3rd 16Byte
1707
1708    FILTER_6TAG_8BITS   d6, d16, d18, d0, d2, d4, d20, q14, q15
1709    pld         [r0]
1710    FILTER_6TAG_8BITS   d7, d17, d19, d1, d3, d5, d21, q14, q15
1711    vld1.u8 {q3}, [r0], r1      //read 5th row
1712    vst1.u8 {q10}, [r2], r3         //write 4th 16Byte
1713
1714    FILTER_6TAG_8BITS   d16, d18, d0, d2, d4, d6, d20, q14, q15
1715    pld         [r0]
1716    FILTER_6TAG_8BITS   d17, d19, d1, d3, d5, d7, d21, q14, q15
1717    vld1.u8 {q8}, [r0], r1      //read 6th row
1718    vst1.u8 {q10}, [r2], r3         //write 5th 16Byte
1719
1720    FILTER_6TAG_8BITS   d18, d0, d2, d4, d6, d16, d20, q14, q15
1721    pld         [r0]
1722    FILTER_6TAG_8BITS   d19, d1, d3, d5, d7, d17, d21, q14, q15
1723    vld1.u8 {q9}, [r0], r1      //read 7th row
1724    vst1.u8 {q10}, [r2], r3         //write 6th 16Byte
1725
1726    FILTER_6TAG_8BITS   d0, d2, d4, d6, d16, d18, d20, q14, q15
1727    pld         [r0]
1728    FILTER_6TAG_8BITS   d1, d3, d5, d7, d17, d19, d21, q14, q15
1729    vld1.u8 {q0}, [r0], r1      //read 8th row
1730    vst1.u8 {q10}, [r2], r3         //write 7th 16Byte
1731
1732    FILTER_6TAG_8BITS   d2, d4, d6, d16, d18, d0, d20, q14, q15
1733    pld         [r0]
1734    FILTER_6TAG_8BITS   d3, d5, d7, d17, d19, d1, d21, q14, q15
1735    vst1.u8 {q10}, [r2], r3         //write 8th 16Byte
1736
1737    //q2, q3, q8, q9, q0 --> q0~q8
1738    vswp    q0, q8
1739    vswp    q0, q2
1740    vmov    q1, q3
1741    vmov    q3, q9                      //q0~q8
1742
1743    sub     r4, #8
1744    cmp     r4, #1
1745    bne     w17_v_mc_luma_loop
1746    // the last 16Bytes
1747    vld1.u8 {q9}, [r0], r1      //q9=src[3]
1748    FILTER_6TAG_8BITS   d0, d2, d4, d6, d16, d18, d20, q14, q15
1749    FILTER_6TAG_8BITS   d1, d3, d5, d7, d17, d19, d21, q14, q15
1750    vst1.u8 {q10}, [r2], r3         //write 1st 16Byte
1751
1752    pop     {r4}
1753WELS_ASM_FUNC_END
1754
1755
1756WELS_ASM_FUNC_BEGIN McHorVer02Height9_neon
1757    push        {r4}
1758    ldr         r4, [sp, #4]
1759
1760    sub         r0, r0, r1, lsl #1      //src[-2*src_stride]
1761    pld         [r0]
1762    pld         [r0, r1]
1763    vmov.u16    q14, #0x0014            // 20
1764    vld1.u8 {d0}, [r0], r1      //d0=src[-2]
1765    vld1.u8 {d1}, [r0], r1      //d1=src[-1]
1766
1767    pld         [r0]
1768    pld         [r0, r1]
1769    vshr.u16    q15, q14, #2            // 5
1770    vld1.u8 {d2}, [r0], r1      //d2=src[0]
1771    vld1.u8 {d3}, [r0], r1      //d3=src[1]
1772
1773    vld1.u8 {d4}, [r0], r1      //d4=src[2]
1774    vld1.u8 {d5}, [r0], r1      //d5=src[3]
1775
1776w9_v_mc_luma_loop:
1777
1778    pld         [r0]
1779    FILTER_6TAG_8BITS   d0, d1, d2, d3, d4, d5, d16, q14, q15
1780    vld1.u8 {d0}, [r0], r1      //read 2nd row
1781    vst1.u8 {d16}, [r2], r3     //write 1st 8Byte
1782
1783    pld         [r0]
1784    FILTER_6TAG_8BITS   d1, d2, d3, d4, d5, d0, d16, q14, q15
1785    vld1.u8 {d1}, [r0], r1      //read 3rd row
1786    vst1.u8 {d16}, [r2], r3     //write 2nd 8Byte
1787
1788    pld         [r0]
1789    FILTER_6TAG_8BITS   d2, d3, d4, d5, d0, d1, d16, q14, q15
1790    vld1.u8 {d2}, [r0], r1      //read 4th row
1791    vst1.u8 {d16}, [r2], r3     //write 3rd 8Byte
1792
1793    pld         [r0]
1794    FILTER_6TAG_8BITS   d3, d4, d5, d0, d1, d2, d16, q14, q15
1795    vld1.u8 {d3}, [r0], r1      //read 5th row
1796    vst1.u8 {d16}, [r2], r3     //write 4th 8Byte
1797
1798    //d4, d5, d0, d1, d2, d3 --> d0, d1, d2, d3, d4, d5
1799    vswp    q0, q2
1800    vswp    q1, q2
1801
1802    sub     r4, #4
1803    cmp     r4, #1
1804    bne     w9_v_mc_luma_loop
1805
1806    FILTER_6TAG_8BITS   d0, d1, d2, d3, d4, d5, d16, q14, q15
1807    vst1.u8 {d16}, [r2], r3     //write last 8Byte
1808
1809    pop     {r4}
1810WELS_ASM_FUNC_END
1811
1812
1813WELS_ASM_FUNC_BEGIN McHorVer02Height5_neon
1814    push        {r4}
1815    ldr         r4, [sp, #4]
1816
1817    sub         r0, r0, r1, lsl #1      //src[-2*src_stride]
1818    pld         [r0]
1819    pld         [r0, r1]
1820    vmov.u16    q14, #0x0014            // 20
1821    vld1.u8 {d0}, [r0], r1      //d0=src[-2]
1822    vld1.u8 {d1}, [r0], r1      //d1=src[-1]
1823
1824    pld         [r0]
1825    pld         [r0, r1]
1826    vshr.u16    q15, q14, #2            // 5
1827    vld1.u8 {d2}, [r0], r1      //d2=src[0]
1828    vld1.u8 {d3}, [r0], r1      //d3=src[1]
1829
1830    vld1.u8 {d4}, [r0], r1      //d4=src[2]
1831    vld1.u8 {d5}, [r0], r1      //d5=src[3]
1832
1833w5_v_mc_luma_loop:
1834
1835    pld         [r0]
1836    FILTER_6TAG_8BITS   d0, d1, d2, d3, d4, d5, d16, q14, q15
1837    vld1.u8 {d0}, [r0], r1      //read 2nd row
1838    vst1.u32 {d16[0]}, [r2], r3     //write 1st 4Byte
1839
1840    pld         [r0]
1841    FILTER_6TAG_8BITS   d1, d2, d3, d4, d5, d0, d16, q14, q15
1842    vld1.u8 {d1}, [r0], r1      //read 3rd row
1843    vst1.u32 {d16[0]}, [r2], r3     //write 2nd 4Byte
1844
1845    pld         [r0]
1846    FILTER_6TAG_8BITS   d2, d3, d4, d5, d0, d1, d16, q14, q15
1847    vld1.u8 {d2}, [r0], r1      //read 4th row
1848    vst1.u32 {d16[0]}, [r2], r3     //write 3rd 4Byte
1849
1850    pld         [r0]
1851    FILTER_6TAG_8BITS   d3, d4, d5, d0, d1, d2, d16, q14, q15
1852    vld1.u8 {d3}, [r0], r1      //read 5th row
1853    vst1.u32 {d16[0]}, [r2], r3     //write 4th 8Byte
1854
1855    //d4, d5, d0, d1, d2, d3 --> d0, d1, d2, d3, d4, d5
1856    vswp    q0, q2
1857    vswp    q1, q2
1858
1859    sub     r4, #4
1860    cmp     r4, #1
1861    bne     w5_v_mc_luma_loop
1862
1863    FILTER_6TAG_8BITS   d0, d1, d2, d3, d4, d5, d16, q14, q15
1864    vst1.u32 {d16[0]}, [r2], r3     //write last 4Byte
1865
1866    pop     {r4}
1867WELS_ASM_FUNC_END
1868
1869
1870WELS_ASM_FUNC_BEGIN McHorVer22Width17_neon
1871    push        {r4}
1872    vpush       {q4-q7}
1873    ldr         r4, [sp, #68]
1874
1875    sub         r0, #2                  //src[-2]
1876    sub         r0, r0, r1, lsl #1      //src[-2*src_stride-2]
1877    pld         [r0]
1878    pld         [r0, r1]
1879
1880    vmov.u16    q14, #0x0014            // 20
1881    vld1.u8 {d0-d2}, [r0], r1       //use 21(17+5), =src[-2]
1882    vld1.u8 {d3-d5}, [r0], r1       //use 21(17+5), =src[-1]
1883
1884    pld         [r0]
1885    pld         [r0, r1]
1886    vshr.u16    q15, q14, #2            // 5
1887
1888    vld1.u8 {d6-d8}, [r0], r1       //use 21(17+5), =src[0]
1889    vld1.u8 {d9-d11}, [r0], r1  //use 21(17+5), =src[1]
1890    pld         [r0]
1891    pld         [r0, r1]
1892    vld1.u8 {d12-d14}, [r0], r1 //use 21(17+5), =src[2]
1893    sub         r3, #16
1894
1895w17_hv_mc_luma_loop:
1896
1897    vld1.u8 {d15-d17}, [r0], r1 //use 21(17+5), =src[3]
1898    //the 1st row
1899    pld         [r0]
1900    // vertical filtered into q9/q10
1901    FILTER_6TAG_8BITS_TO_16BITS     d0, d3, d6, d9, d12, d15, q9, q14, q15  // 8 avail
1902    FILTER_6TAG_8BITS_TO_16BITS     d1, d4, d7,d10, d13, d16,q10, q14, q15  // 8 avail
1903    // horizon filtered
1904    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
1905    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d0   //output to q0[0]
1906    // vertical filtered into q10/q11
1907    FILTER_6TAG_8BITS_TO_16BITS     d2, d5, d8,d11, d14, d17,q11, q14, q15  // only 6 avail
1908    // horizon filtered
1909    UNPACK_2_16BITS_TO_ABC  q10, q11, q9, q12, q13
1910    FILTER_3_IN_16BITS_TO_8BITS q9, q12, q13, d1    //output to q0[1]
1911    vst1.u8 {d0, d1}, [r2]!         //write 16Byte
1912    UNPACK_1_IN_8x16BITS_TO_8BITS   d2, d22, d23, q11 //output to d2[0]
1913    vst1.u8 {d2[0]}, [r2], r3       //write 16th Byte
1914
1915    vld1.u8 {d0-d2}, [r0], r1       //read 2nd row
1916    //the 2nd row
1917    pld         [r0]
1918    // vertical filtered into q9/q10
1919    FILTER_6TAG_8BITS_TO_16BITS     d3, d6, d9, d12, d15, d0, q9, q14, q15  // 8 avail
1920    FILTER_6TAG_8BITS_TO_16BITS     d4, d7,d10, d13, d16, d1,q10, q14, q15  // 8 avail
1921    // horizon filtered
1922    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
1923    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d3   //output to d3
1924    // vertical filtered into q10/q11
1925    FILTER_6TAG_8BITS_TO_16BITS     d5, d8,d11, d14, d17, d2,q11, q14, q15  // only 6 avail
1926    // horizon filtered
1927    UNPACK_2_16BITS_TO_ABC  q10, q11, q9, q12, q13
1928    FILTER_3_IN_16BITS_TO_8BITS q9, q12, q13, d4    //output to d4
1929    vst1.u8 {d3, d4}, [r2]!     //write 16Byte
1930    UNPACK_1_IN_8x16BITS_TO_8BITS   d5, d22, d23, q11 //output to d5[0]
1931    vst1.u8 {d5[0]}, [r2], r3       //write 16th Byte
1932
1933    vld1.u8 {d3-d5}, [r0], r1       //read 3rd row
1934    //the 3rd row
1935    pld         [r0]
1936    // vertical filtered into q9/q10
1937    FILTER_6TAG_8BITS_TO_16BITS     d6, d9, d12, d15, d0, d3, q9, q14, q15  // 8 avail
1938    FILTER_6TAG_8BITS_TO_16BITS     d7,d10, d13, d16, d1, d4,q10, q14, q15  // 8 avail
1939    // horizon filtered
1940    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
1941    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d6   //output to d6
1942    // vertical filtered into q10/q11
1943    FILTER_6TAG_8BITS_TO_16BITS     d8,d11, d14, d17, d2, d5,q11, q14, q15  // only 6 avail
1944    // horizon filtered
1945    UNPACK_2_16BITS_TO_ABC  q10, q11, q9, q12, q13
1946    FILTER_3_IN_16BITS_TO_8BITS q9, q12, q13, d7    //output to d7
1947    vst1.u8 {d6, d7}, [r2]!     //write 16Byte
1948    UNPACK_1_IN_8x16BITS_TO_8BITS   d8, d22, d23, q11 //output to d8[0]
1949    vst1.u8 {d8[0]}, [r2], r3       //write 16th Byte
1950
1951    vld1.u8 {d6-d8}, [r0], r1       //read 4th row
1952    //the 4th row
1953    pld         [r0]
1954    // vertical filtered into q9/q10
1955    FILTER_6TAG_8BITS_TO_16BITS      d9, d12, d15, d0, d3, d6, q9, q14, q15 // 8 avail
1956    FILTER_6TAG_8BITS_TO_16BITS     d10, d13, d16, d1, d4, d7,q10, q14, q15 // 8 avail
1957    // horizon filtered
1958    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
1959    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d9   //output to d9
1960    // vertical filtered into q10/q11
1961    FILTER_6TAG_8BITS_TO_16BITS     d11, d14, d17, d2, d5, d8,q11, q14, q15 // only 6 avail
1962    // horizon filtered
1963    UNPACK_2_16BITS_TO_ABC  q10, q11, q9, q12, q13
1964    FILTER_3_IN_16BITS_TO_8BITS q9, q12, q13, d10   //output to d10
1965    vst1.u8 {d9, d10}, [r2]!        //write 16Byte
1966    UNPACK_1_IN_8x16BITS_TO_8BITS   d11, d22, d23, q11 //output to d11[0]
1967    vst1.u8 {d11[0]}, [r2], r3      //write 16th Byte
1968
1969    //d12~d17(q6~q8), d0~d8(q0~q3+d8), --> d0~d14
1970    vswp    q0, q6
1971    vswp    q6, q3
1972    vmov    q5, q2
1973    vmov    q2, q8
1974
1975    vmov    d20,d8
1976    vmov    q4, q1
1977    vmov    q1, q7
1978    vmov    d14,d20
1979
1980    sub     r4, #4
1981    cmp     r4, #1
1982    bne     w17_hv_mc_luma_loop
1983    //the last row
1984    vld1.u8 {d15-d17}, [r0], r1 //use 21(17+5), =src[3]
1985    // vertical filtered into q9/q10
1986    FILTER_6TAG_8BITS_TO_16BITS     d0, d3, d6, d9, d12, d15, q9, q14, q15  // 8 avail
1987    FILTER_6TAG_8BITS_TO_16BITS     d1, d4, d7,d10, d13, d16,q10, q14, q15  // 8 avail
1988    // horizon filtered
1989    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
1990    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d0   //output to q0[0]
1991    // vertical filtered into q10/q11
1992    FILTER_6TAG_8BITS_TO_16BITS     d2, d5, d8,d11, d14, d17,q11, q14, q15  // only 6 avail
1993    // horizon filtered
1994    UNPACK_2_16BITS_TO_ABC  q10, q11, q9, q12, q13
1995    FILTER_3_IN_16BITS_TO_8BITS q9, q12, q13, d1    //output to q0[1]
1996    vst1.u8 {q0}, [r2]!         //write 16Byte
1997    UNPACK_1_IN_8x16BITS_TO_8BITS   d2, d22, d23, q11 //output to d2[0]
1998    vst1.u8 {d2[0]}, [r2], r3       //write 16th Byte
1999
2000    vpop        {q4-q7}
2001    pop     {r4}
2002WELS_ASM_FUNC_END
2003
2004
2005WELS_ASM_FUNC_BEGIN McHorVer22Width9_neon
2006    push        {r4}
2007    vpush       {q4}
2008    ldr         r4, [sp, #20]
2009
2010    sub         r0, #2              //src[-2]
2011    sub         r0, r0, r1, lsl #1  //src[-2*src_stride-2]
2012    pld         [r0]
2013    pld         [r0, r1]
2014
2015    vmov.u16    q14, #0x0014        // 20
2016    vld1.u8 {q0}, [r0], r1  //use 14(9+5), =src[-2]
2017    vld1.u8 {q1}, [r0], r1  //use 14(9+5), =src[-1]
2018
2019    pld         [r0]
2020    pld         [r0, r1]
2021    vshr.u16    q15, q14, #2        // 5
2022
2023    vld1.u8 {q2}, [r0], r1  //use 14(9+5), =src[0]
2024    vld1.u8 {q3}, [r0], r1  //use 14(9+5), =src[1]
2025    pld         [r0]
2026    pld         [r0, r1]
2027    vld1.u8 {q4}, [r0], r1  //use 14(9+5), =src[2]
2028    sub         r3, #8
2029
2030w9_hv_mc_luma_loop:
2031
2032    vld1.u8 {q8}, [r0], r1  //use 14(9+5), =src[3]
2033    //the 1st row
2034    pld         [r0]
2035    // vertical filtered into q9/q10
2036    FILTER_6TAG_8BITS_TO_16BITS     d0, d2, d4, d6, d8, d16, q9, q14, q15   // 8 avail
2037    FILTER_6TAG_8BITS_TO_16BITS     d1, d3, d5, d7, d9, d17, q10, q14, q15  // 6 avail
2038    // horizon filtered
2039    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
2040    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18  //output to q9[0]
2041    vst1.u8 d18, [r2]!              //write 8Byte
2042    UNPACK_1_IN_8x16BITS_TO_8BITS   d19, d20, d21, q10 //output to d19[0]
2043    vst1.u8 {d19[0]}, [r2], r3  //write 8th Byte
2044
2045    vld1.u8 {q0}, [r0], r1      //read 2nd row
2046    //the 2nd row
2047    pld         [r0]
2048    // vertical filtered into q9/q10
2049    FILTER_6TAG_8BITS_TO_16BITS     d2, d4, d6, d8, d16, d0, q9, q14, q15   // 8 avail
2050    FILTER_6TAG_8BITS_TO_16BITS     d3, d5, d7, d9, d17, d1, q10, q14, q15  // 6 avail
2051    // horizon filtered
2052    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
2053    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18  //output to q9[0]
2054    vst1.u8 d18, [r2]!              //write 8Byte
2055    UNPACK_1_IN_8x16BITS_TO_8BITS   d19, d20, d21, q10 //output to d19[0]
2056    vst1.u8 {d19[0]}, [r2], r3  //write 8th Byte
2057
2058    vld1.u8 {q1}, [r0], r1      //read 3rd row
2059    //the 3rd row
2060    pld         [r0]
2061    // vertical filtered into q9/q10
2062    FILTER_6TAG_8BITS_TO_16BITS     d4, d6, d8, d16, d0, d2, q9, q14, q15   // 8 avail
2063    FILTER_6TAG_8BITS_TO_16BITS     d5, d7, d9, d17, d1, d3, q10, q14, q15  // 6 avail
2064    // horizon filtered
2065    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
2066    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18  //output to q9[0]
2067    vst1.u8 d18, [r2]!              //write 8Byte
2068    UNPACK_1_IN_8x16BITS_TO_8BITS   d19, d20, d21, q10 //output to d19[0]
2069    vst1.u8 {d19[0]}, [r2], r3  //write 8th Byte
2070
2071    vld1.u8 {q2}, [r0], r1      //read 4th row
2072    //the 4th row
2073    pld         [r0]
2074    // vertical filtered into q9/q10
2075    FILTER_6TAG_8BITS_TO_16BITS     d6, d8, d16, d0, d2, d4, q9, q14, q15   // 8 avail
2076    FILTER_6TAG_8BITS_TO_16BITS     d7, d9, d17, d1, d3, d5, q10, q14, q15  // 6 avail
2077    // horizon filtered
2078    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
2079    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18  //output to q9[0]
2080    vst1.u8 d18, [r2]!          //write 8Byte
2081    UNPACK_1_IN_8x16BITS_TO_8BITS   d19, d20, d21, q10 //output to d19[0]
2082    vst1.u8 {d19[0]}, [r2], r3  //write 8th Byte
2083
2084    //q4~q8, q0~q2, --> q0~q4
2085    vswp    q0, q4
2086    vswp    q2, q4
2087    vmov    q3, q1
2088    vmov    q1, q8
2089
2090    sub     r4, #4
2091    cmp     r4, #1
2092    bne     w9_hv_mc_luma_loop
2093    //the last row
2094    vld1.u8 {q8}, [r0], r1  //use 14(9+5), =src[3]
2095    // vertical filtered into q9/q10
2096    FILTER_6TAG_8BITS_TO_16BITS     d0, d2, d4, d6, d8, d16, q9, q14, q15   // 8 avail
2097    FILTER_6TAG_8BITS_TO_16BITS     d1, d3, d5, d7, d9, d17, q10, q14, q15  // 6 avail
2098    // horizon filtered
2099    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
2100    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18  //output to q9[0]
2101    vst1.u8 d18, [r2]!              //write 8Byte
2102    UNPACK_1_IN_8x16BITS_TO_8BITS   d19, d20, d21, q10 //output to d19[0]
2103    vst1.u8 {d19[0]}, [r2], r3  //write 8th Byte
2104    vpop        {q4}
2105    pop     {r4}
2106WELS_ASM_FUNC_END
2107
2108
2109WELS_ASM_FUNC_BEGIN McHorVer22Width5_neon
2110    push        {r4}
2111    vpush       {q4}
2112    ldr         r4, [sp, #20]
2113
2114    sub         r0, #2              //src[-2]
2115    sub         r0, r0, r1, lsl #1  //src[-2*src_stride-2]
2116    pld         [r0]
2117    pld         [r0, r1]
2118
2119    vmov.u16    q14, #0x0014        // 20
2120    vld1.u8 {q0}, [r0], r1  //use 10(5+5), =src[-2]
2121    vld1.u8 {q1}, [r0], r1  //use 10(5+5), =src[-1]
2122
2123    pld         [r0]
2124    pld         [r0, r1]
2125    vshr.u16    q15, q14, #2        // 5
2126
2127    vld1.u8 {q2}, [r0], r1  //use 10(5+5), =src[0]
2128    vld1.u8 {q3}, [r0], r1  //use 10(5+5), =src[1]
2129    pld         [r0]
2130    pld         [r0, r1]
2131    vld1.u8 {q4}, [r0], r1  //use 10(5+5), =src[2]
2132    sub         r3, #4
2133
2134w5_hv_mc_luma_loop:
2135
2136    vld1.u8 {q8}, [r0], r1  //use 10(5+5), =src[3]
2137    //the 1st row
2138    pld         [r0]
2139    // vertical filtered into q9/q10
2140    FILTER_6TAG_8BITS_TO_16BITS     d0, d2, d4, d6, d8, d16, q9, q14, q15
2141    FILTER_6TAG_8BITS_TO_16BITS     d1, d3, d5, d7, d9, d17, q10, q14, q15
2142    // horizon filtered
2143    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
2144    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18
2145    vst1.u32 {d18[0]}, [r2]!              //write 4Byte
2146    vst1.u8 {d18[4]}, [r2], r3  //write 5th Byte
2147
2148    vld1.u8 {q0}, [r0], r1      //read 2nd row
2149    //the 2nd row
2150    pld         [r0]
2151    // vertical filtered into q9/q10
2152    FILTER_6TAG_8BITS_TO_16BITS     d2, d4, d6, d8, d16, d0, q9, q14, q15
2153    FILTER_6TAG_8BITS_TO_16BITS     d3, d5, d7, d9, d17, d1, q10, q14, q15
2154    // horizon filtered
2155    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
2156    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18
2157    vst1.u32 {d18[0]}, [r2]!              //write 4Byte
2158    vst1.u8 {d18[4]}, [r2], r3  //write 5th Byte
2159
2160    vld1.u8 {q1}, [r0], r1      //read 3rd row
2161    //the 3rd row
2162    pld         [r0]
2163    // vertical filtered into q9/q10
2164    FILTER_6TAG_8BITS_TO_16BITS     d4, d6, d8, d16, d0, d2, q9, q14, q15
2165    FILTER_6TAG_8BITS_TO_16BITS     d5, d7, d9, d17, d1, d3, q10, q14, q15
2166    // horizon filtered
2167    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
2168    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18
2169    vst1.u32 {d18[0]}, [r2]!              //write 4Byte
2170    vst1.u8 {d18[4]}, [r2], r3  //write 5th Byte
2171
2172    vld1.u8 {q2}, [r0], r1      //read 4th row
2173    //the 4th row
2174    pld         [r0]
2175    // vertical filtered into q9/q10
2176    FILTER_6TAG_8BITS_TO_16BITS     d6, d8, d16, d0, d2, d4, q9, q14, q15
2177    FILTER_6TAG_8BITS_TO_16BITS     d7, d9, d17, d1, d3, d5, q10, q14, q15
2178    // horizon filtered
2179    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
2180    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18
2181    vst1.u32 {d18[0]}, [r2]!          //write 4Byte
2182    vst1.u8 {d18[4]}, [r2], r3  //write 5th Byte
2183
2184    //q4~q8, q0~q2, --> q0~q4
2185    vswp    q0, q4
2186    vswp    q2, q4
2187    vmov    q3, q1
2188    vmov    q1, q8
2189
2190    sub     r4, #4
2191    cmp     r4, #1
2192    bne     w5_hv_mc_luma_loop
2193    //the last row
2194    vld1.u8 {q8}, [r0], r1  //use 10(5+5), =src[3]
2195    // vertical filtered into q9/q10
2196    FILTER_6TAG_8BITS_TO_16BITS     d0, d2, d4, d6, d8, d16, q9, q14, q15
2197    FILTER_6TAG_8BITS_TO_16BITS     d1, d3, d5, d7, d9, d17, q10, q14, q15
2198    // horizon filtered
2199    UNPACK_2_16BITS_TO_ABC  q9, q10, q11, q12, q13
2200    FILTER_3_IN_16BITS_TO_8BITS q11, q12, q13, d18
2201    vst1.u32 {d18[0]}, [r2]!              //write 4Byte
2202    vst1.u8 {d18[4]}, [r2], r3  //write 5th Byte
2203    vpop        {q4}
2204    pop     {r4}
2205WELS_ASM_FUNC_END
2206
2207
2208WELS_ASM_FUNC_BEGIN PixStrideAvgWidthEq16_neon
2209    push        {r4, r5, r6}
2210    ldr         r4, [sp, #12]
2211    ldr         r5, [sp, #16]
2212    ldr         r6, [sp, #20]
2213
2214enc_w16_pix_avg_loop:
2215    vld1.u8     {q0}, [r2], r3
2216    vld1.u8     {q1}, [r4], r5
2217    vld1.u8     {q2}, [r2], r3
2218    vld1.u8     {q3}, [r4], r5
2219
2220    vld1.u8     {q8}, [r2], r3
2221    vld1.u8     {q9}, [r4], r5
2222    vld1.u8     {q10}, [r2], r3
2223    vld1.u8     {q11}, [r4], r5
2224
2225    AVERAGE_TWO_8BITS       d0, d0, d2
2226    AVERAGE_TWO_8BITS       d1, d1, d3
2227    vst1.u8     {q0}, [r0], r1
2228
2229    AVERAGE_TWO_8BITS       d4, d4, d6
2230    AVERAGE_TWO_8BITS       d5, d5, d7
2231    vst1.u8     {q2}, [r0], r1
2232
2233    AVERAGE_TWO_8BITS       d16, d16, d18
2234    AVERAGE_TWO_8BITS       d17, d17, d19
2235    vst1.u8     {q8}, [r0], r1
2236
2237    AVERAGE_TWO_8BITS       d20, d20, d22
2238    AVERAGE_TWO_8BITS       d21, d21, d23
2239    vst1.u8     {q10}, [r0], r1
2240
2241    sub         r6, #4
2242    cmp         r6, #0
2243    bne         enc_w16_pix_avg_loop
2244
2245    pop     {r4, r5, r6}
2246WELS_ASM_FUNC_END
2247
2248
2249WELS_ASM_FUNC_BEGIN PixStrideAvgWidthEq8_neon
2250    push        {r4, r5, r6}
2251    ldr         r4, [sp, #12]
2252    ldr         r5, [sp, #16]
2253    ldr         r6, [sp, #20]
2254enc_w8_pix_avg_loop:
2255
2256    vld1.u8     {d0}, [r2], r3
2257    vld1.u8     {d2}, [r4], r5
2258    vld1.u8     {d1}, [r2], r3
2259    vld1.u8     {d3}, [r4], r5
2260
2261    AVERAGE_TWO_8BITS       d0, d0, d2
2262    AVERAGE_TWO_8BITS       d1, d1, d3
2263    vst1.u8     {d0}, [r0], r1
2264    vst1.u8     {d1}, [r0], r1
2265
2266    vld1.u8     {d4}, [r2], r3
2267    vld1.u8     {d6}, [r4], r5
2268    vld1.u8     {d5}, [r2], r3
2269    vld1.u8     {d7}, [r4], r5
2270
2271    AVERAGE_TWO_8BITS       d4, d4, d6
2272    AVERAGE_TWO_8BITS       d5, d5, d7
2273    vst1.u8     {d4}, [r0], r1
2274    vst1.u8     {d5}, [r0], r1
2275
2276    sub         r6, #4
2277    cmp         r6, #0
2278    bne         enc_w8_pix_avg_loop
2279
2280    pop     {r4, r5, r6}
2281WELS_ASM_FUNC_END
2282
2283#endif
2284