vpx_convolve8_avg_neon_asm.asm revision 91037db265ecdd914a26e056cf69207b4f50924e
191037db265ecdd914a26e056cf69207b4f50924ehkuang;
291037db265ecdd914a26e056cf69207b4f50924ehkuang;  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
391037db265ecdd914a26e056cf69207b4f50924ehkuang;
491037db265ecdd914a26e056cf69207b4f50924ehkuang;  Use of this source code is governed by a BSD-style license
591037db265ecdd914a26e056cf69207b4f50924ehkuang;  that can be found in the LICENSE file in the root of the source
691037db265ecdd914a26e056cf69207b4f50924ehkuang;  tree. An additional intellectual property rights grant can be found
791037db265ecdd914a26e056cf69207b4f50924ehkuang;  in the file PATENTS.  All contributing project authors may
891037db265ecdd914a26e056cf69207b4f50924ehkuang;  be found in the AUTHORS file in the root of the source tree.
991037db265ecdd914a26e056cf69207b4f50924ehkuang;
1091037db265ecdd914a26e056cf69207b4f50924ehkuang
1191037db265ecdd914a26e056cf69207b4f50924ehkuang
1291037db265ecdd914a26e056cf69207b4f50924ehkuang    ; These functions are only valid when:
1391037db265ecdd914a26e056cf69207b4f50924ehkuang    ; x_step_q4 == 16
1491037db265ecdd914a26e056cf69207b4f50924ehkuang    ; w%4 == 0
1591037db265ecdd914a26e056cf69207b4f50924ehkuang    ; h%4 == 0
1691037db265ecdd914a26e056cf69207b4f50924ehkuang    ; taps == 8
1791037db265ecdd914a26e056cf69207b4f50924ehkuang    ; VP9_FILTER_WEIGHT == 128
1891037db265ecdd914a26e056cf69207b4f50924ehkuang    ; VP9_FILTER_SHIFT == 7
1991037db265ecdd914a26e056cf69207b4f50924ehkuang
2091037db265ecdd914a26e056cf69207b4f50924ehkuang    EXPORT  |vp9_convolve8_avg_horiz_neon|
2191037db265ecdd914a26e056cf69207b4f50924ehkuang    EXPORT  |vp9_convolve8_avg_vert_neon|
2291037db265ecdd914a26e056cf69207b4f50924ehkuang    IMPORT  |vp9_convolve8_avg_horiz_c|
2391037db265ecdd914a26e056cf69207b4f50924ehkuang    IMPORT  |vp9_convolve8_avg_vert_c|
2491037db265ecdd914a26e056cf69207b4f50924ehkuang    ARM
2591037db265ecdd914a26e056cf69207b4f50924ehkuang    REQUIRE8
2691037db265ecdd914a26e056cf69207b4f50924ehkuang    PRESERVE8
2791037db265ecdd914a26e056cf69207b4f50924ehkuang
2891037db265ecdd914a26e056cf69207b4f50924ehkuang    AREA ||.text||, CODE, READONLY, ALIGN=2
2991037db265ecdd914a26e056cf69207b4f50924ehkuang
3091037db265ecdd914a26e056cf69207b4f50924ehkuang    ; Multiply and accumulate by q0
3191037db265ecdd914a26e056cf69207b4f50924ehkuang    MACRO
3291037db265ecdd914a26e056cf69207b4f50924ehkuang    MULTIPLY_BY_Q0 $dst, $src0, $src1, $src2, $src3, $src4, $src5, $src6, $src7
3391037db265ecdd914a26e056cf69207b4f50924ehkuang    vmull.s16 $dst, $src0, d0[0]
3491037db265ecdd914a26e056cf69207b4f50924ehkuang    vmlal.s16 $dst, $src1, d0[1]
3591037db265ecdd914a26e056cf69207b4f50924ehkuang    vmlal.s16 $dst, $src2, d0[2]
3691037db265ecdd914a26e056cf69207b4f50924ehkuang    vmlal.s16 $dst, $src3, d0[3]
3791037db265ecdd914a26e056cf69207b4f50924ehkuang    vmlal.s16 $dst, $src4, d1[0]
3891037db265ecdd914a26e056cf69207b4f50924ehkuang    vmlal.s16 $dst, $src5, d1[1]
3991037db265ecdd914a26e056cf69207b4f50924ehkuang    vmlal.s16 $dst, $src6, d1[2]
4091037db265ecdd914a26e056cf69207b4f50924ehkuang    vmlal.s16 $dst, $src7, d1[3]
4191037db265ecdd914a26e056cf69207b4f50924ehkuang    MEND
4291037db265ecdd914a26e056cf69207b4f50924ehkuang
4391037db265ecdd914a26e056cf69207b4f50924ehkuang; r0    const uint8_t *src
4491037db265ecdd914a26e056cf69207b4f50924ehkuang; r1    int src_stride
4591037db265ecdd914a26e056cf69207b4f50924ehkuang; r2    uint8_t *dst
4691037db265ecdd914a26e056cf69207b4f50924ehkuang; r3    int dst_stride
4791037db265ecdd914a26e056cf69207b4f50924ehkuang; sp[]const int16_t *filter_x
4891037db265ecdd914a26e056cf69207b4f50924ehkuang; sp[]int x_step_q4
4991037db265ecdd914a26e056cf69207b4f50924ehkuang; sp[]const int16_t *filter_y ; unused
5091037db265ecdd914a26e056cf69207b4f50924ehkuang; sp[]int y_step_q4           ; unused
5191037db265ecdd914a26e056cf69207b4f50924ehkuang; sp[]int w
5291037db265ecdd914a26e056cf69207b4f50924ehkuang; sp[]int h
5391037db265ecdd914a26e056cf69207b4f50924ehkuang
5491037db265ecdd914a26e056cf69207b4f50924ehkuang|vp9_convolve8_avg_horiz_neon| PROC
5591037db265ecdd914a26e056cf69207b4f50924ehkuang    push            {r4-r10, lr}
5691037db265ecdd914a26e056cf69207b4f50924ehkuang
5791037db265ecdd914a26e056cf69207b4f50924ehkuang    sub             r0, r0, #3              ; adjust for taps
5891037db265ecdd914a26e056cf69207b4f50924ehkuang
5991037db265ecdd914a26e056cf69207b4f50924ehkuang    ldr             r4, [sp, #36]           ; x_step_q4
6091037db265ecdd914a26e056cf69207b4f50924ehkuang    ldr             r5, [sp, #32]           ; filter_x
6191037db265ecdd914a26e056cf69207b4f50924ehkuang    cmp             r4, #16
6291037db265ecdd914a26e056cf69207b4f50924ehkuang    bne             call_horiz_c_convolve   ; x_step_q4 != 16
6391037db265ecdd914a26e056cf69207b4f50924ehkuang
6491037db265ecdd914a26e056cf69207b4f50924ehkuang    ldr             r6, [sp, #48]           ; w
6591037db265ecdd914a26e056cf69207b4f50924ehkuang    ldr             r7, [sp, #52]           ; h
6691037db265ecdd914a26e056cf69207b4f50924ehkuang
6791037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.s16        {q0}, [r5]              ; filter_x
6891037db265ecdd914a26e056cf69207b4f50924ehkuang
6991037db265ecdd914a26e056cf69207b4f50924ehkuang    add             r8, r1, r1, lsl #1      ; src_stride * 3
7091037db265ecdd914a26e056cf69207b4f50924ehkuang    add             r8, r8, #4              ; src_stride * 3 + 4
7191037db265ecdd914a26e056cf69207b4f50924ehkuang    rsb             r8, r8, #0              ; reset for src
7291037db265ecdd914a26e056cf69207b4f50924ehkuang
7391037db265ecdd914a26e056cf69207b4f50924ehkuang    add             r4, r3, r3, lsl #1      ; dst_stride * 3
7491037db265ecdd914a26e056cf69207b4f50924ehkuang    sub             r4, r4, #4              ; dst_stride * 3 - 4
7591037db265ecdd914a26e056cf69207b4f50924ehkuang    rsb             r4, r4, #0              ; reset for dst
7691037db265ecdd914a26e056cf69207b4f50924ehkuang
7791037db265ecdd914a26e056cf69207b4f50924ehkuang    sub             r9, r1, #8              ; post increment for src load
7891037db265ecdd914a26e056cf69207b4f50924ehkuang
7991037db265ecdd914a26e056cf69207b4f50924ehkuang    rsb             r1, r6, r1, lsl #2      ; reset src for outer loop
8091037db265ecdd914a26e056cf69207b4f50924ehkuang    rsb             r12, r6, r3, lsl #2     ; reset dst for outer loop
8191037db265ecdd914a26e056cf69207b4f50924ehkuang
8291037db265ecdd914a26e056cf69207b4f50924ehkuang    mov             r10, r6                 ; w loop counter
8391037db265ecdd914a26e056cf69207b4f50924ehkuang
8491037db265ecdd914a26e056cf69207b4f50924ehkuangloop_horiz
8591037db265ecdd914a26e056cf69207b4f50924ehkuang    vld4.u8         {d24[0], d25[0], d26[0], d27[0]}, [r0]!
8691037db265ecdd914a26e056cf69207b4f50924ehkuang    vld4.u8         {d24[4], d25[4], d26[4], d27[4]}, [r0]!
8791037db265ecdd914a26e056cf69207b4f50924ehkuang    vld3.u8         {d28[0], d29[0], d30[0]}, [r0], r9
8891037db265ecdd914a26e056cf69207b4f50924ehkuang
8991037db265ecdd914a26e056cf69207b4f50924ehkuang    vld4.u8         {d24[1], d25[1], d26[1], d27[1]}, [r0]!
9091037db265ecdd914a26e056cf69207b4f50924ehkuang    vld4.u8         {d24[5], d25[5], d26[5], d27[5]}, [r0]!
9191037db265ecdd914a26e056cf69207b4f50924ehkuang    vld3.u8         {d28[1], d29[1], d30[1]}, [r0], r9
9291037db265ecdd914a26e056cf69207b4f50924ehkuang
9391037db265ecdd914a26e056cf69207b4f50924ehkuang    vld4.u8         {d24[2], d25[2], d26[2], d27[2]}, [r0]!
9491037db265ecdd914a26e056cf69207b4f50924ehkuang    vld4.u8         {d24[6], d25[6], d26[6], d27[6]}, [r0]!
9591037db265ecdd914a26e056cf69207b4f50924ehkuang    vld3.u8         {d28[2], d29[2], d30[2]}, [r0], r9
9691037db265ecdd914a26e056cf69207b4f50924ehkuang
9791037db265ecdd914a26e056cf69207b4f50924ehkuang    vld4.u8         {d24[3], d25[3], d26[3], d27[3]}, [r0]!
9891037db265ecdd914a26e056cf69207b4f50924ehkuang    vld4.u8         {d24[7], d25[7], d26[7], d27[7]}, [r0]!
9991037db265ecdd914a26e056cf69207b4f50924ehkuang    vld3.u8         {d28[3], d29[3], d30[3]}, [r0], r8
10091037db265ecdd914a26e056cf69207b4f50924ehkuang
10191037db265ecdd914a26e056cf69207b4f50924ehkuang    ; extract to s16
10291037db265ecdd914a26e056cf69207b4f50924ehkuang    vmovl.u8        q8, d24
10391037db265ecdd914a26e056cf69207b4f50924ehkuang    vmovl.u8        q9, d25
10491037db265ecdd914a26e056cf69207b4f50924ehkuang    vmovl.u8        q10, d26
10591037db265ecdd914a26e056cf69207b4f50924ehkuang    vmovl.u8        q11, d27
10691037db265ecdd914a26e056cf69207b4f50924ehkuang    vtrn.32         d28, d29 ; only the first half is populated
10791037db265ecdd914a26e056cf69207b4f50924ehkuang    vmovl.u8        q12, d28
10891037db265ecdd914a26e056cf69207b4f50924ehkuang    vmovl.u8        q13, d30
10991037db265ecdd914a26e056cf69207b4f50924ehkuang
11091037db265ecdd914a26e056cf69207b4f50924ehkuang    ; slightly out of order load to match the existing data
11191037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d6[0]}, [r2], r3
11291037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d7[0]}, [r2], r3
11391037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d6[1]}, [r2], r3
11491037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d7[1]}, [r2], r3
11591037db265ecdd914a26e056cf69207b4f50924ehkuang
11691037db265ecdd914a26e056cf69207b4f50924ehkuang    sub             r2, r2, r3, lsl #2      ; reset for store
11791037db265ecdd914a26e056cf69207b4f50924ehkuang
11891037db265ecdd914a26e056cf69207b4f50924ehkuang    ; src[] * filter_x
11991037db265ecdd914a26e056cf69207b4f50924ehkuang    MULTIPLY_BY_Q0 q1, d16, d18, d20, d22, d17, d19, d21, d23
12091037db265ecdd914a26e056cf69207b4f50924ehkuang    MULTIPLY_BY_Q0 q2, d18, d20, d22, d17, d19, d21, d23, d24
12191037db265ecdd914a26e056cf69207b4f50924ehkuang    MULTIPLY_BY_Q0 q14, d20, d22, d17, d19, d21, d23, d24, d25
12291037db265ecdd914a26e056cf69207b4f50924ehkuang    MULTIPLY_BY_Q0 q15, d22, d17, d19, d21, d23, d24, d25, d26
12391037db265ecdd914a26e056cf69207b4f50924ehkuang
12491037db265ecdd914a26e056cf69207b4f50924ehkuang    ; += 64 >> 7
12591037db265ecdd914a26e056cf69207b4f50924ehkuang    vqrshrun.s32    d2, q1, #7
12691037db265ecdd914a26e056cf69207b4f50924ehkuang    vqrshrun.s32    d3, q2, #7
12791037db265ecdd914a26e056cf69207b4f50924ehkuang    vqrshrun.s32    d4, q14, #7
12891037db265ecdd914a26e056cf69207b4f50924ehkuang    vqrshrun.s32    d5, q15, #7
12991037db265ecdd914a26e056cf69207b4f50924ehkuang
13091037db265ecdd914a26e056cf69207b4f50924ehkuang    ; saturate
13191037db265ecdd914a26e056cf69207b4f50924ehkuang    vqshrn.u16      d2, q1, #0
13291037db265ecdd914a26e056cf69207b4f50924ehkuang    vqshrn.u16      d3, q2, #0
13391037db265ecdd914a26e056cf69207b4f50924ehkuang
13491037db265ecdd914a26e056cf69207b4f50924ehkuang    ; transpose
13591037db265ecdd914a26e056cf69207b4f50924ehkuang    vtrn.16         d2, d3
13691037db265ecdd914a26e056cf69207b4f50924ehkuang    vtrn.32         d2, d3
13791037db265ecdd914a26e056cf69207b4f50924ehkuang    vtrn.8          d2, d3
13891037db265ecdd914a26e056cf69207b4f50924ehkuang    
13991037db265ecdd914a26e056cf69207b4f50924ehkuang    ; average the new value and the dst value
14091037db265ecdd914a26e056cf69207b4f50924ehkuang    vaddl.u8        q8, d2, d6
14191037db265ecdd914a26e056cf69207b4f50924ehkuang    vaddl.u8        q9, d3, d7
14291037db265ecdd914a26e056cf69207b4f50924ehkuang    vqrshrn.u16     d2, q8, #1
14391037db265ecdd914a26e056cf69207b4f50924ehkuang    vqrshrn.u16     d3, q9, #1
14491037db265ecdd914a26e056cf69207b4f50924ehkuang
14591037db265ecdd914a26e056cf69207b4f50924ehkuang    vst1.u32        {d2[0]}, [r2], r3
14691037db265ecdd914a26e056cf69207b4f50924ehkuang    vst1.u32        {d3[0]}, [r2], r3
14791037db265ecdd914a26e056cf69207b4f50924ehkuang    vst1.u32        {d2[1]}, [r2], r3
14891037db265ecdd914a26e056cf69207b4f50924ehkuang    vst1.u32        {d3[1]}, [r2], r4
14991037db265ecdd914a26e056cf69207b4f50924ehkuang
15091037db265ecdd914a26e056cf69207b4f50924ehkuang    subs            r6, r6, #4              ; w -= 4
15191037db265ecdd914a26e056cf69207b4f50924ehkuang    bgt             loop_horiz
15291037db265ecdd914a26e056cf69207b4f50924ehkuang
15391037db265ecdd914a26e056cf69207b4f50924ehkuang    ; outer loop
15491037db265ecdd914a26e056cf69207b4f50924ehkuang    mov             r6, r10                 ; restore w counter
15591037db265ecdd914a26e056cf69207b4f50924ehkuang    add             r0, r0, r1              ; src += src_stride * 4 - w
15691037db265ecdd914a26e056cf69207b4f50924ehkuang    add             r2, r2, r12             ; dst += dst_stride * 4 - w
15791037db265ecdd914a26e056cf69207b4f50924ehkuang    subs            r7, r7, #4              ; h -= 4
15891037db265ecdd914a26e056cf69207b4f50924ehkuang    bgt loop_horiz
15991037db265ecdd914a26e056cf69207b4f50924ehkuang
16091037db265ecdd914a26e056cf69207b4f50924ehkuang    pop             {r4-r10, pc}
16191037db265ecdd914a26e056cf69207b4f50924ehkuang
16291037db265ecdd914a26e056cf69207b4f50924ehkuangcall_horiz_c_convolve
16391037db265ecdd914a26e056cf69207b4f50924ehkuang    pop             {r4-r10, lr}
16491037db265ecdd914a26e056cf69207b4f50924ehkuang    add             r0, r0, #3              ; un-adjust for taps
16591037db265ecdd914a26e056cf69207b4f50924ehkuang    b               vp9_convolve8_avg_horiz_c
16691037db265ecdd914a26e056cf69207b4f50924ehkuang
16791037db265ecdd914a26e056cf69207b4f50924ehkuang
16891037db265ecdd914a26e056cf69207b4f50924ehkuang    ENDP
16991037db265ecdd914a26e056cf69207b4f50924ehkuang
17091037db265ecdd914a26e056cf69207b4f50924ehkuang|vp9_convolve8_avg_vert_neon| PROC
17191037db265ecdd914a26e056cf69207b4f50924ehkuang    push            {r4-r10, lr}
17291037db265ecdd914a26e056cf69207b4f50924ehkuang
17391037db265ecdd914a26e056cf69207b4f50924ehkuang    ; adjust for taps
17491037db265ecdd914a26e056cf69207b4f50924ehkuang    sub             r0, r0, r1
17591037db265ecdd914a26e056cf69207b4f50924ehkuang    sub             r0, r0, r1, lsl #1
17691037db265ecdd914a26e056cf69207b4f50924ehkuang
17791037db265ecdd914a26e056cf69207b4f50924ehkuang    ldr             r6, [sp, #44]           ; y_step_q4
17891037db265ecdd914a26e056cf69207b4f50924ehkuang    ldr             r7, [sp, #40]           ; filter_y
17991037db265ecdd914a26e056cf69207b4f50924ehkuang    cmp             r6, #16
18091037db265ecdd914a26e056cf69207b4f50924ehkuang    bne             call_vert_c_convolve    ; y_step_q4 != 16
18191037db265ecdd914a26e056cf69207b4f50924ehkuang
18291037db265ecdd914a26e056cf69207b4f50924ehkuang    ldr             r8, [sp, #48]           ; w
18391037db265ecdd914a26e056cf69207b4f50924ehkuang    ldr             r9, [sp, #52]           ; h
18491037db265ecdd914a26e056cf69207b4f50924ehkuang
18591037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.s16        {q0}, [r7]              ; filter_y
18691037db265ecdd914a26e056cf69207b4f50924ehkuang
18791037db265ecdd914a26e056cf69207b4f50924ehkuang    mov             r5, r1, lsl #1          ; src_stride * 2
18891037db265ecdd914a26e056cf69207b4f50924ehkuang    add             r5, r5, r1, lsl #3      ; src_stride * 10
18991037db265ecdd914a26e056cf69207b4f50924ehkuang    sub             r5, r5, #4              ; src_stride * 10 + 4
19091037db265ecdd914a26e056cf69207b4f50924ehkuang    rsb             r5, r5, #0              ; reset for src
19191037db265ecdd914a26e056cf69207b4f50924ehkuang
19291037db265ecdd914a26e056cf69207b4f50924ehkuang    add             r6, r3, r3, lsl #1      ; dst_stride * 3
19391037db265ecdd914a26e056cf69207b4f50924ehkuang    sub             r6, r6, #4              ; dst_stride * 3 - 4
19491037db265ecdd914a26e056cf69207b4f50924ehkuang    rsb             r6, r6, #0              ; reset for dst
19591037db265ecdd914a26e056cf69207b4f50924ehkuang
19691037db265ecdd914a26e056cf69207b4f50924ehkuang    rsb             r7, r8, r1, lsl #2      ; reset src for outer loop
19791037db265ecdd914a26e056cf69207b4f50924ehkuang    rsb             r12, r8, r3, lsl #2     ; reset dst for outer loop
19891037db265ecdd914a26e056cf69207b4f50924ehkuang
19991037db265ecdd914a26e056cf69207b4f50924ehkuang    mov             r10, r8                 ; w loop counter
20091037db265ecdd914a26e056cf69207b4f50924ehkuang
20191037db265ecdd914a26e056cf69207b4f50924ehkuangloop_vert
20291037db265ecdd914a26e056cf69207b4f50924ehkuang    ; always process a 4x4 block at a time
20391037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d16[0]}, [r0], r1
20491037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d16[1]}, [r0], r1
20591037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d18[0]}, [r0], r1
20691037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d18[1]}, [r0], r1
20791037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d20[0]}, [r0], r1
20891037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d20[1]}, [r0], r1
20991037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d22[0]}, [r0], r1
21091037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d22[1]}, [r0], r1
21191037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d24[0]}, [r0], r1
21291037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d24[1]}, [r0], r1
21391037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d26[0]}, [r0], r5
21491037db265ecdd914a26e056cf69207b4f50924ehkuang
21591037db265ecdd914a26e056cf69207b4f50924ehkuang    ; extract to s16
21691037db265ecdd914a26e056cf69207b4f50924ehkuang    vmovl.u8        q8, d16
21791037db265ecdd914a26e056cf69207b4f50924ehkuang    vmovl.u8        q9, d18
21891037db265ecdd914a26e056cf69207b4f50924ehkuang    vmovl.u8        q10, d20
21991037db265ecdd914a26e056cf69207b4f50924ehkuang    vmovl.u8        q11, d22
22091037db265ecdd914a26e056cf69207b4f50924ehkuang    vmovl.u8        q12, d24
22191037db265ecdd914a26e056cf69207b4f50924ehkuang    vmovl.u8        q13, d26
22291037db265ecdd914a26e056cf69207b4f50924ehkuang
22391037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d6[0]}, [r2], r3
22491037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d6[1]}, [r2], r3
22591037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d7[0]}, [r2], r3
22691037db265ecdd914a26e056cf69207b4f50924ehkuang    vld1.u32        {d7[1]}, [r2], r3
22791037db265ecdd914a26e056cf69207b4f50924ehkuang
22891037db265ecdd914a26e056cf69207b4f50924ehkuang    sub             r2, r2, r3, lsl #2      ; reset for store
22991037db265ecdd914a26e056cf69207b4f50924ehkuang
23091037db265ecdd914a26e056cf69207b4f50924ehkuang    ; src[] * filter_y
23191037db265ecdd914a26e056cf69207b4f50924ehkuang    MULTIPLY_BY_Q0 q1, d16, d17, d18, d19, d20, d21, d22, d23
23291037db265ecdd914a26e056cf69207b4f50924ehkuang    MULTIPLY_BY_Q0 q2, d17, d18, d19, d20, d21, d22, d23, d24
23391037db265ecdd914a26e056cf69207b4f50924ehkuang    MULTIPLY_BY_Q0 q14, d18, d19, d20, d21, d22, d23, d24, d25
23491037db265ecdd914a26e056cf69207b4f50924ehkuang    MULTIPLY_BY_Q0 q15, d19, d20, d21, d22, d23, d24, d25, d26
23591037db265ecdd914a26e056cf69207b4f50924ehkuang
23691037db265ecdd914a26e056cf69207b4f50924ehkuang    ; += 64 >> 7
23791037db265ecdd914a26e056cf69207b4f50924ehkuang    vqrshrun.s32    d2, q1, #7
23891037db265ecdd914a26e056cf69207b4f50924ehkuang    vqrshrun.s32    d3, q2, #7
23991037db265ecdd914a26e056cf69207b4f50924ehkuang    vqrshrun.s32    d4, q14, #7
24091037db265ecdd914a26e056cf69207b4f50924ehkuang    vqrshrun.s32    d5, q15, #7
24191037db265ecdd914a26e056cf69207b4f50924ehkuang
24291037db265ecdd914a26e056cf69207b4f50924ehkuang    ; saturate
24391037db265ecdd914a26e056cf69207b4f50924ehkuang    vqshrn.u16      d2, q1, #0
24491037db265ecdd914a26e056cf69207b4f50924ehkuang    vqshrn.u16      d3, q2, #0
24591037db265ecdd914a26e056cf69207b4f50924ehkuang
24691037db265ecdd914a26e056cf69207b4f50924ehkuang    ; average the new value and the dst value
24791037db265ecdd914a26e056cf69207b4f50924ehkuang    vaddl.u8        q8, d2, d6
24891037db265ecdd914a26e056cf69207b4f50924ehkuang    vaddl.u8        q9, d3, d7
24991037db265ecdd914a26e056cf69207b4f50924ehkuang    vqrshrn.u16     d2, q8, #1
25091037db265ecdd914a26e056cf69207b4f50924ehkuang    vqrshrn.u16     d3, q9, #1
25191037db265ecdd914a26e056cf69207b4f50924ehkuang
25291037db265ecdd914a26e056cf69207b4f50924ehkuang    vst1.u32        {d2[0]}, [r2], r3
25391037db265ecdd914a26e056cf69207b4f50924ehkuang    vst1.u32        {d2[1]}, [r2], r3
25491037db265ecdd914a26e056cf69207b4f50924ehkuang    vst1.u32        {d3[0]}, [r2], r3
25591037db265ecdd914a26e056cf69207b4f50924ehkuang    vst1.u32        {d3[1]}, [r2], r6
25691037db265ecdd914a26e056cf69207b4f50924ehkuang
25791037db265ecdd914a26e056cf69207b4f50924ehkuang    subs            r8, r8, #4              ; w -= 4
25891037db265ecdd914a26e056cf69207b4f50924ehkuang    bgt             loop_vert
25991037db265ecdd914a26e056cf69207b4f50924ehkuang
26091037db265ecdd914a26e056cf69207b4f50924ehkuang    ; outer loop
26191037db265ecdd914a26e056cf69207b4f50924ehkuang    mov             r8, r10                 ; restore w counter
26291037db265ecdd914a26e056cf69207b4f50924ehkuang    add             r0, r0, r7              ; src += 4 * src_stride - w
26391037db265ecdd914a26e056cf69207b4f50924ehkuang    add             r2, r2, r12             ; dst += 4 * dst_stride - w
26491037db265ecdd914a26e056cf69207b4f50924ehkuang    subs            r9, r9, #4              ; h -= 4
26591037db265ecdd914a26e056cf69207b4f50924ehkuang    bgt             loop_vert
26691037db265ecdd914a26e056cf69207b4f50924ehkuang
26791037db265ecdd914a26e056cf69207b4f50924ehkuang    pop             {r4-r10, pc}
26891037db265ecdd914a26e056cf69207b4f50924ehkuang
26991037db265ecdd914a26e056cf69207b4f50924ehkuangcall_vert_c_convolve
27091037db265ecdd914a26e056cf69207b4f50924ehkuang    pop             {r4-r10, lr}
27191037db265ecdd914a26e056cf69207b4f50924ehkuang    ; un-adjust for taps
27291037db265ecdd914a26e056cf69207b4f50924ehkuang    add             r0, r0, r1
27391037db265ecdd914a26e056cf69207b4f50924ehkuang    add             r0, r0, r1, lsl #1
27491037db265ecdd914a26e056cf69207b4f50924ehkuang    b               vp9_convolve8_avg_vert_c
27591037db265ecdd914a26e056cf69207b4f50924ehkuang
27691037db265ecdd914a26e056cf69207b4f50924ehkuang    ENDP
27791037db265ecdd914a26e056cf69207b4f50924ehkuang    END
278