blob: c8edf3849dcbe030fffcb30f56f949387c3a8ab3 [file] [log] [blame]
@/******************************************************************************
@ *
@ * Copyright (C) 2015 The Android Open Source Project
@ *
@ * Licensed under the Apache License, Version 2.0 (the "License");
@ * you may not use this file except in compliance with the License.
@ * You may obtain a copy of the License at:
@ *
@ * http://www.apache.org/licenses/LICENSE-2.0
@ *
@ * Unless required by applicable law or agreed to in writing, software
@ * distributed under the License is distributed on an "AS IS" BASIS,
@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@ * See the License for the specific language governing permissions and
@ * limitations under the License.
@ *
@ *****************************************************************************
@ * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
@*/
@**
@******************************************************************************
@* @file
@* ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q.s
@*
@* @brief
@* Contains function definitions for inter prediction interpolation.
@*
@* @author
@* Mohit
@*
@* @par List of Functions:
@*
@* - ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q()
@*
@* @remarks
@* None
@*
@*******************************************************************************
@*
@* All the functions here are replicated from ih264_inter_pred_filters.c
@
@**
@**
@**
@*******************************************************************************
@*
@* @brief
@* This function implements a two stage cascaded six tap filter. It
@* applies the six tap filter in the horizontal direction on the
@* predictor values, followed by applying the same filter in the
@* vertical direction on the output of the first stage. It then averages
@* the output of the 1st stage and the output of the 2nd stage to obtain
@* the quarter pel values. The six tap filtering operation is described
@* in sec 8.4.2.2.1 titled "Luma sample interpolation process".
@*
@* @par Description:
@* This function is called to obtain pixels lying at the following
@* location (1/2,1/4) or (1/2,3/4). The function interpolates
@* the predictors first in the horizontal direction and then in the
@* vertical direction to output the (1/2,1/2). It then averages
@* the output of the 2nd stage and (1/2,1/2) value to obtain (1/2,1/4)
@* or (1/2,3/4) depending on the offset.
@*
@* @param[in] pu1_src
@* UWORD8 pointer to the source
@*
@* @param[out] pu1_dst
@* UWORD8 pointer to the destination
@*
@* @param[in] src_strd
@* integer source stride
@*
@* @param[in] dst_strd
@* integer destination stride
@*
@* @param[in] ht
@* integer height of the array
@*
@* @param[in] wd
@* integer width of the array
@*
@* @param[in] pu1_tmp: temporary buffer
@*
@* @param[in] dydx: x and y reference offset for qpel calculations
@*
@* @returns
@*
@* @remarks
@* None
@*
@*******************************************************************************
@*;
@void ih264_inter_pred_luma_horz_hpel_vert_qpel(UWORD8 *pu1_src,
@ UWORD8 *pu1_dst,
@ WORD32 src_strd,,
@ WORD32 dst_strd,
@ WORD32 ht,
@ WORD32 wd,
@ UWORD8* pu1_tmp,
@ UWORD32 dydx)
@**************Variables Vs Registers*****************************************
@ r0 => *pu1_src
@ r1 => *pu1_dst
@ r2 => src_strd
@ r3 => dst_strd
@ r4 => ht
@ r5 => wd
@ r7 => dydx
@ r9 => *pu1_tmp
.text
.p2align 2
.global ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q
ih264_inter_pred_luma_horz_hpel_vert_qpel_a9q:
stmfd sp!, {r4-r12, r14} @ store register values to stack
vstmdb sp!, {d8-d15} @push neon registers to stack
ldr r4, [sp, #104] @ loads ht
sub r0, r0, r2, lsl #1 @ pu1_src-2*src_strd
sub r0, r0, #2 @ pu1_src-2
ldr r5, [sp, #108] @ loads wd
ldr r7, [sp, #116] @ loads dydx
lsr r7, r7, #3 @ dydx >> 2 followed by dydx & 0x3 and dydx>>1 to obtain the deciding bit
ldr r9, [sp, #112] @ pu1_tmp
add r7, r7, #2
mov r6, #48
mla r7, r7, r6, r9
subs r12, r5, #4 @if wd=4 branch to loop_4
beq loop_4_start
subs r12, r5, #8 @if wd=8 branch to loop_8
beq loop_8_start
@when wd=16
vmov.u16 q11, #20 @ Filter coeff 0x14 into Q11
vmov.u16 q12, #5 @ Filter coeff 0x5 into Q12
add r8, r0, #8
add r14, r1, #8
add r10, r9, #8
mov r12, r4
add r11, r7, #8
loop_16_lowhalf_start:
vld1.32 {q0}, [r0], r2 @ row -2 load for horizontal filter
vext.8 d5, d0, d1, #5
vaddl.u8 q3, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q4, d2, d3
vext.8 d4, d0, d1, #4
vmla.u16 q3, q4, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q4, d1, d4
vld1.32 {q0}, [r0], r2 @ row -1 load for horizontal filter
vmls.u16 q3, q4, q12
vext.8 d5, d0, d1, #5
vaddl.u8 q4, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q5, d2, d3
vst1.32 {q3}, [r9], r6 @ store temp buffer 0
vext.8 d4, d0, d1, #4
vmla.u16 q4, q5, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q5, d1, d4
vld1.32 {q0}, [r0], r2 @ row 0 load for horizontal filter
vmls.u16 q4, q5, q12
vext.8 d5, d0, d1, #5
vaddl.u8 q5, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q6, d2, d3
vst1.32 {q4}, [r9], r6 @ store temp buffer 1
vext.8 d4, d0, d1, #4
vmla.u16 q5, q6, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q6, d1, d4
vld1.32 {q0}, [r0], r2 @ row 1 load for horizontal filter
vmls.u16 q5, q6, q12
vext.8 d5, d0, d1, #5
vaddl.u8 q6, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q7, d2, d3
vst1.32 {q5}, [r9], r6 @ store temp buffer 2
vext.8 d4, d0, d1, #4
vmla.u16 q6, q7, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q7, d1, d4
vld1.32 {q0}, [r0], r2 @ row 2 load for horizontal filter
vmls.u16 q6, q7, q12
vext.8 d5, d0, d1, #5
vaddl.u8 q7, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q8, d2, d3
vst1.32 {q6}, [r9], r6 @ store temp buffer 3
vext.8 d4, d0, d1, #4
vmla.u16 q7, q8, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q8, d1, d4
vmls.u16 q7, q8, q12
loop_16_lowhalf:
vld1.32 {q0}, [r0], r2 @ row 3 load for horizontal filter
vext.8 d5, d0, d1, #5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q8, d0, d5
vst1.32 {q7}, [r9], r6 @ store temp buffer 4
vaddl.u8 q9, d2, d3
vext.8 d4, d0, d1, #4
vmla.u16 q8, q9, q11
vext.8 d1, d0, d1, #1
vadd.s16 q14, q4, q7
vaddl.u8 q9, d1, d4
vadd.s16 q15, q5, q6
vmls.u16 q8, q9, q12
vld1.32 {q0}, [r0], r2 @ row 4 load for hoorizontal filter
vext.8 d5, d0, d1, #5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q10, d0, d5
vst1.32 {q8}, [r9], r6 @ store temp buffer r5
vaddl.s16 q9, d6, d16
vld1.32 {q13}, [r7], r6 @ load from temp buffer 0
vaddl.s16 q3, d7, d17
vqrshrun.s16 d26, q13, #5
vmlal.s16 q9, d30, d22
vmlsl.s16 q9, d28, d24
vmlal.s16 q3, d31, d22
vmlsl.s16 q3, d29, d24
vaddl.u8 q1, d2, d3
vext.8 d4, d0, d1, #4
vmla.u16 q10, q1, q11
vqrshrun.s32 d18, q9, #10
vext.8 d1, d0, d1, #1
vqrshrun.s32 d19, q3, #10
vadd.s16 q14, q5, q8
vaddl.u8 q1, d1, d4
vadd.s16 q15, q6, q7
vmls.u16 q10, q1, q12
vqmovn.u16 d18, q9
vld1.32 {q0}, [r0], r2 @ row 5 load for horizontal filter
vrhadd.u8 d26, d18, d26
vext.8 d5, d0, d1, #5
vext.8 d2, d0, d1, #2
vst1.32 {q10}, [r9], r6 @ store temp buffer r6
vaddl.s16 q9, d8, d20
vaddl.s16 q3, d9, d21
vld1.32 {q4}, [r7], r6 @load from temp buffer 1
vst1.32 d26, [r1], r3 @ store row 0
vmlal.s16 q9, d30, d22
vmlsl.s16 q9, d28, d24
vqrshrun.s16 d28, q4, #5
vmlal.s16 q3, d31, d22
vmlsl.s16 q3, d29, d24
vext.8 d3, d0, d1, #3
vaddl.u8 q4, d0, d5
vaddl.u8 q1, d2, d3
vqrshrun.s32 d18, q9, #10
vext.8 d4, d0, d1, #4
vqrshrun.s32 d19, q3, #10
vmla.u16 q4, q1, q11
vext.8 d1, d0, d1, #1
vadd.s16 q13, q6, q10
vaddl.u8 q1, d1, d4
vqmovn.u16 d18, q9
vadd.s16 q15, q7, q8
vmls.u16 q4, q1, q12
vld1.32 {q0}, [r0], r2 @ row 6 load for horizontal filter
vrhadd.u8 d28, d28, d18
vext.8 d5, d0, d1, #5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vst1.32 d28, [r1], r3 @ store row 1
vaddl.u8 q14, d0, d5
vst1.32 {q4}, [r9], r6 @ store temp buffer r7
vaddl.s16 q9, d10, d8
vaddl.s16 q3, d11, d9
vld1.32 {q5}, [r7], r6 @ load from temp buffer 2
vmlal.s16 q9, d30, d22
vmlsl.s16 q9, d26, d24
vmlal.s16 q3, d31, d22
vqrshrun.s16 d26, q5, #5
vmlsl.s16 q3, d27, d24
vaddl.u8 q1, d2, d3
vext.8 d4, d0, d1, #4
vmla.u16 q14, q1, q11
vqrshrun.s32 d18, q9, #10
vext.8 d1, d0, d1, #1
vqrshrun.s32 d19, q3, #10
vadd.s16 q5, q7, q4
vaddl.u8 q1, d1, d4
vadd.s16 q15, q8, q10
vmls.u16 q14, q1, q12
vqmovn.u16 d27, q9
vaddl.s16 q9, d12, d28
vaddl.s16 q3, d13, d29
vrhadd.u8 d26, d26, d27
vmlal.s16 q9, d30, d22
vmlsl.s16 q9, d10, d24
vmlal.s16 q3, d31, d22
vmlsl.s16 q3, d11, d24
vst1.32 d26, [r1], r3 @ store row 2
vst1.32 {q14}, [r9]
vqrshrun.s32 d18, q9, #10
vmov q5, q10
vld1.32 {q15}, [r7], r6 @ load from temp buffer 3
vqrshrun.s32 d19, q3, #10
subs r4, r4, #4
vqrshrun.s16 d30, q15, #5
vqmovn.u16 d18, q9
vmov q6, q4
vmov q3, q7
vrhadd.u8 d30, d18, d30
vmov q4, q8
vmov q7, q14
vst1.32 d30, [r1], r3 @ store row 3
bgt loop_16_lowhalf @ looping if height =16
loop_16_highhalf_start:
vld1.32 {q0}, [r8], r2
vext.8 d5, d0, d1, #5
vaddl.u8 q3, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q4, d2, d3
vext.8 d4, d0, d1, #4
vmla.u16 q3, q4, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q4, d1, d4
vld1.32 {q0}, [r8], r2
vmls.u16 q3, q4, q12
vext.8 d5, d0, d1, #5
vaddl.u8 q4, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q5, d2, d3
vst1.32 {q3}, [r10], r6
vext.8 d4, d0, d1, #4
vmla.u16 q4, q5, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q5, d1, d4
vld1.32 {q0}, [r8], r2
vmls.u16 q4, q5, q12
vext.8 d5, d0, d1, #5
vaddl.u8 q5, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q6, d2, d3
vst1.32 {q4}, [r10], r6
vext.8 d4, d0, d1, #4
vmla.u16 q5, q6, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q6, d1, d4
vld1.32 {q0}, [r8], r2
vmls.u16 q5, q6, q12
vext.8 d5, d0, d1, #5
vaddl.u8 q6, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q7, d2, d3
vst1.32 {q5}, [r10], r6
vext.8 d4, d0, d1, #4
vmla.u16 q6, q7, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q7, d1, d4
vld1.32 {q0}, [r8], r2
vmls.u16 q6, q7, q12
vext.8 d5, d0, d1, #5
vaddl.u8 q7, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q8, d2, d3
vst1.32 {q6}, [r10], r6
vext.8 d4, d0, d1, #4
vmla.u16 q7, q8, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q8, d1, d4
vmls.u16 q7, q8, q12
loop_16_highhalf:
vld1.32 {q0}, [r8], r2
vext.8 d5, d0, d1, #5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q8, d0, d5
vst1.32 {q7}, [r10], r6
vaddl.u8 q9, d2, d3
vext.8 d4, d0, d1, #4
vmla.u16 q8, q9, q11
vext.8 d1, d0, d1, #1
vadd.s16 q14, q4, q7
vaddl.u8 q9, d1, d4
vadd.s16 q15, q5, q6
vmls.u16 q8, q9, q12
vld1.32 {q0}, [r8], r2
vext.8 d5, d0, d1, #5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q10, d0, d5
vst1.32 {q8}, [r10], r6
vaddl.s16 q9, d6, d16
vld1.32 {q13}, [r11], r6
vaddl.s16 q3, d7, d17
vqrshrun.s16 d26, q13, #5
vmlal.s16 q9, d30, d22
vmlsl.s16 q9, d28, d24
vmlal.s16 q3, d31, d22
vmlsl.s16 q3, d29, d24
vaddl.u8 q1, d2, d3
vext.8 d4, d0, d1, #4
vmla.u16 q10, q1, q11
vqrshrun.s32 d18, q9, #10
vext.8 d1, d0, d1, #1
vqrshrun.s32 d19, q3, #10
vadd.s16 q14, q5, q8
vaddl.u8 q1, d1, d4
vadd.s16 q15, q6, q7
vmls.u16 q10, q1, q12
vqmovn.u16 d18, q9
vld1.32 {q0}, [r8], r2
vrhadd.u8 d26, d18, d26
vext.8 d5, d0, d1, #5
vext.8 d2, d0, d1, #2
vst1.32 {q10}, [r10], r6
vaddl.s16 q9, d8, d20
vaddl.s16 q3, d9, d21
vld1.32 {q4}, [r11], r6
vst1.32 d26, [r14], r3 @store row 0
vmlal.s16 q9, d30, d22
vmlsl.s16 q9, d28, d24
vqrshrun.s16 d28, q4, #5
vmlal.s16 q3, d31, d22
vmlsl.s16 q3, d29, d24
vext.8 d3, d0, d1, #3
vaddl.u8 q4, d0, d5
vaddl.u8 q1, d2, d3
vqrshrun.s32 d18, q9, #10
vext.8 d4, d0, d1, #4
vqrshrun.s32 d19, q3, #10
vmla.u16 q4, q1, q11
vext.8 d1, d0, d1, #1
vadd.s16 q13, q6, q10
vaddl.u8 q1, d1, d4
vqmovn.u16 d18, q9
vadd.s16 q15, q7, q8
vmls.u16 q4, q1, q12
vld1.32 {q0}, [r8], r2
vrhadd.u8 d28, d28, d18
vext.8 d5, d0, d1, #5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vst1.32 d28, [r14], r3 @store row 1
vaddl.u8 q14, d0, d5
vst1.32 {q4}, [r10], r6
vaddl.s16 q9, d10, d8
vaddl.s16 q3, d11, d9
vld1.32 {q5}, [r11], r6
vmlal.s16 q9, d30, d22
vmlsl.s16 q9, d26, d24
vmlal.s16 q3, d31, d22
vqrshrun.s16 d26, q5, #5
vmlsl.s16 q3, d27, d24
vaddl.u8 q1, d2, d3
vext.8 d4, d0, d1, #4
vmla.u16 q14, q1, q11
vqrshrun.s32 d18, q9, #10
vext.8 d1, d0, d1, #1
vqrshrun.s32 d19, q3, #10
vadd.s16 q5, q7, q4
vaddl.u8 q1, d1, d4
vadd.s16 q15, q8, q10
vmls.u16 q14, q1, q12
vqmovn.u16 d27, q9
vaddl.s16 q9, d12, d28
vaddl.s16 q3, d13, d29
vrhadd.u8 d26, d26, d27
vmlal.s16 q9, d30, d22
vmlsl.s16 q9, d10, d24
vmlal.s16 q3, d31, d22
vmlsl.s16 q3, d11, d24
vst1.32 d26, [r14], r3 @ store row 2
vst1.32 {q14}, [r10]
vqrshrun.s32 d18, q9, #10
vmov q5, q10
vld1.32 {q15}, [r11], r6
vqrshrun.s32 d19, q3, #10
subs r12, r12, #4
vqrshrun.s16 d30, q15, #5
vqmovn.u16 d18, q9
vmov q6, q4
vmov q3, q7
vrhadd.u8 d30, d18, d30
vmov q4, q8
vmov q7, q14
vst1.32 d30, [r14], r3 @ store row 3
bgt loop_16_highhalf @ looping if height = 8 or 16
b end_func
loop_8_start:
vmov.u16 q11, #20 @ Filter coeff 20 into Q11
vmov.u16 q12, #5 @ Filter coeff 5 into Q12
vld1.32 {q0}, [r0], r2 @ row -2 load for horizontal filter
vext.8 d5, d0, d1, #5
vaddl.u8 q3, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q4, d2, d3
vext.8 d4, d0, d1, #4
vmla.u16 q3, q4, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q4, d1, d4
vld1.32 {q0}, [r0], r2 @ row -1 load for horizontal filter
vmls.u16 q3, q4, q12
vext.8 d5, d0, d1, #5
vaddl.u8 q4, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q5, d2, d3
vst1.32 {q3}, [r9], r6 @ store temp buffer 0
vext.8 d4, d0, d1, #4
vmla.u16 q4, q5, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q5, d1, d4
vld1.32 {q0}, [r0], r2 @ row 0 load for horizontal filter
vmls.u16 q4, q5, q12
vext.8 d5, d0, d1, #5
vaddl.u8 q5, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q6, d2, d3
vst1.32 {q4}, [r9], r6 @ store temp buffer 1
vext.8 d4, d0, d1, #4
vmla.u16 q5, q6, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q6, d1, d4
vld1.32 {q0}, [r0], r2 @ row 1 load for horizontal filter
vmls.u16 q5, q6, q12
vext.8 d5, d0, d1, #5
vaddl.u8 q6, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q7, d2, d3
vst1.32 {q5}, [r9], r6 @ store temp buffer 2
vext.8 d4, d0, d1, #4
vmla.u16 q6, q7, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q7, d1, d4
vld1.32 {q0}, [r0], r2 @ row 2 load for horizontal filter
vmls.u16 q6, q7, q12
vext.8 d5, d0, d1, #5
vaddl.u8 q7, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q8, d2, d3
vst1.32 {q6}, [r9], r6 @ store temp buffer 3
vext.8 d4, d0, d1, #4
vmla.u16 q7, q8, q11
vext.8 d1, d0, d1, #1
vaddl.u8 q8, d1, d4
vmls.u16 q7, q8, q12
loop_8:
vld1.32 {q0}, [r0], r2 @ row 3 load for horizontal filter
vext.8 d5, d0, d1, #5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q8, d0, d5
vst1.32 {q7}, [r9], r6 @ store temp buffer 4
vaddl.u8 q9, d2, d3
vext.8 d4, d0, d1, #4
vmla.u16 q8, q9, q11
vext.8 d1, d0, d1, #1
vadd.s16 q14, q4, q7
vaddl.u8 q9, d1, d4
vadd.s16 q15, q5, q6
vmls.u16 q8, q9, q12
vld1.32 {q0}, [r0], r2 @ row 4 load for hoorizontal filter
vext.8 d5, d0, d1, #5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q10, d0, d5
vst1.32 {q8}, [r9], r6 @ store temp buffer r5
vaddl.s16 q9, d6, d16
vld1.32 {q13}, [r7], r6 @ load from temp buffer 0
vaddl.s16 q3, d7, d17
vqrshrun.s16 d26, q13, #5
vmlal.s16 q9, d30, d22
vmlsl.s16 q9, d28, d24
vmlal.s16 q3, d31, d22
vmlsl.s16 q3, d29, d24
vaddl.u8 q1, d2, d3
vext.8 d4, d0, d1, #4
vmla.u16 q10, q1, q11
vqrshrun.s32 d18, q9, #10
vext.8 d1, d0, d1, #1
vqrshrun.s32 d19, q3, #10
vadd.s16 q14, q5, q8
vaddl.u8 q1, d1, d4
vadd.s16 q15, q6, q7
vmls.u16 q10, q1, q12
vqmovn.u16 d18, q9
vld1.32 {q0}, [r0], r2 @ row 5 load for horizontal filter
vrhadd.u8 d26, d18, d26
vext.8 d5, d0, d1, #5
vext.8 d2, d0, d1, #2
vst1.32 {q10}, [r9], r6 @ store temp buffer r6
vaddl.s16 q9, d8, d20
vaddl.s16 q3, d9, d21
vld1.32 {q4}, [r7], r6 @load from temp buffer 1
vst1.32 d26, [r1], r3 @ store row 0
vmlal.s16 q9, d30, d22
vmlsl.s16 q9, d28, d24
vqrshrun.s16 d28, q4, #5
vmlal.s16 q3, d31, d22
vmlsl.s16 q3, d29, d24
vext.8 d3, d0, d1, #3
vaddl.u8 q4, d0, d5
vaddl.u8 q1, d2, d3
vqrshrun.s32 d18, q9, #10
vext.8 d4, d0, d1, #4
vqrshrun.s32 d19, q3, #10
vmla.u16 q4, q1, q11
vext.8 d1, d0, d1, #1
vadd.s16 q13, q6, q10
vaddl.u8 q1, d1, d4
vqmovn.u16 d18, q9
vadd.s16 q15, q7, q8
vmls.u16 q4, q1, q12
vld1.32 {q0}, [r0], r2 @ row 6 load for horizontal filter
vrhadd.u8 d28, d28, d18
vext.8 d5, d0, d1, #5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vst1.32 d28, [r1], r3 @ store row 1
vaddl.u8 q14, d0, d5
vst1.32 {q4}, [r9], r6 @ store temp buffer r7
vaddl.s16 q9, d10, d8
vaddl.s16 q3, d11, d9
vld1.32 {q5}, [r7], r6 @ load from temp buffer 2
vmlal.s16 q9, d30, d22
vmlsl.s16 q9, d26, d24
vmlal.s16 q3, d31, d22
vqrshrun.s16 d26, q5, #5
vmlsl.s16 q3, d27, d24
vaddl.u8 q1, d2, d3
vext.8 d4, d0, d1, #4
vmla.u16 q14, q1, q11
vqrshrun.s32 d18, q9, #10
vext.8 d1, d0, d1, #1
vqrshrun.s32 d19, q3, #10
vadd.s16 q5, q7, q4
vaddl.u8 q1, d1, d4
vadd.s16 q15, q8, q10
vmls.u16 q14, q1, q12
vqmovn.u16 d27, q9
vaddl.s16 q9, d12, d28
vaddl.s16 q3, d13, d29
vrhadd.u8 d26, d26, d27
vmlal.s16 q9, d30, d22
vmlsl.s16 q9, d10, d24
vmlal.s16 q3, d31, d22
vmlsl.s16 q3, d11, d24
vst1.32 d26, [r1], r3 @ store row 2
vst1.32 {q14}, [r9]
vqrshrun.s32 d18, q9, #10
vmov q5, q10
vld1.32 {q15}, [r7], r6 @ load from temp buffer 3
vqrshrun.s32 d19, q3, #10
subs r4, r4, #4
vqrshrun.s16 d30, q15, #5
vqmovn.u16 d18, q9
vmov q6, q4
vmov q3, q7
vrhadd.u8 d30, d18, d30
vmov q4, q8
vmov q7, q14
vst1.32 d30, [r1], r3 @ store row 3
bgt loop_8 @if height =8 or 16 loop
b end_func
loop_4_start:
vmov.u16 d22, #20 @ Filter coeff 20 into D22
vmov.u16 d23, #5 @ Filter coeff 5 into D23
vld1.32 {q0}, [r0], r2 @row -2 load
vext.8 d5, d0, d1, #5
vaddl.u8 q3, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q4, d2, d3
vext.8 d4, d0, d1, #4
vmla.u16 d6, d8, d22
vext.8 d1, d0, d1, #1
vaddl.u8 q4, d1, d4
vld1.32 {q0}, [r0], r2 @ row -1 load
vmls.u16 d6, d8, d23
vext.8 d5, d0, d1, #5
vaddl.u8 q4, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q5, d2, d3
vst1.32 d6, [r9], r6 @ store temp buffer 0
vext.8 d4, d0, d1, #4
vmla.u16 d8, d10, d22
vext.8 d1, d0, d1, #1
vaddl.u8 q5, d1, d4
vld1.32 {q0}, [r0], r2 @ row 0 load
vmls.u16 d8, d10, d23
vext.8 d5, d0, d1, #5
vaddl.u8 q5, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q6, d2, d3
vst1.32 d8, [r9], r6 @ store temp buffer 1
vext.8 d4, d0, d1, #4
vmla.u16 d10, d12, d22
vext.8 d1, d0, d1, #1
vaddl.u8 q6, d1, d4
vld1.32 {q0}, [r0], r2 @ row 1 load
vmls.u16 d10, d12, d23
vext.8 d5, d0, d1, #5
vaddl.u8 q6, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q7, d2, d3
vst1.32 d10, [r9], r6 @ store temp buffer 2
vext.8 d4, d0, d1, #4
vmla.u16 d12, d14, d22
vext.8 d1, d0, d1, #1
vaddl.u8 q7, d1, d4
vld1.32 {q0}, [r0], r2 @ row 2 load
vmls.u16 d12, d14, d23
vext.8 d5, d0, d1, #5
vaddl.u8 q7, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q8, d2, d3
vext.8 d4, d0, d1, #4
vmla.u16 d14, d16, d22
vext.8 d1, d0, d1, #1
vaddl.u8 q8, d1, d4
vst1.32 d12, [r9], r6 @ store temp buffer 3
vmls.u16 d14, d16, d23
loop_4:
vld1.32 {q0}, [r0], r2 @ row 3 load
vext.8 d5, d0, d1, #5
vaddl.u8 q8, d0, d5
vext.8 d2, d0, d1, #2
vext.8 d3, d0, d1, #3
vaddl.u8 q9, d2, d3
vst1.32 d14, [r9], r6 @ store temp buffer 4
vext.8 d4, d0, d1, #4
vmla.u16 d16, d18, d22
vext.8 d1, d0, d1, #1
vaddl.u8 q9, d1, d4
vadd.s16 d2, d10, d12
vmls.u16 d16, d18, d23
vadd.s16 d3, d8, d14
vld1.32 {q9}, [r0], r2 @ row 4 load
vext.8 d25, d18, d19, #5
vaddl.u8 q13, d18, d25
vext.8 d20, d18, d19, #2
vst1.32 d16, [r9], r6 @ store temp buffer 5
vaddl.s16 q0, d6, d16
vmlal.s16 q0, d2, d22
vext.8 d21, d18, d19, #3
vaddl.u8 q14, d20, d21
vext.8 d24, d18, d19, #4
vmlsl.s16 q0, d3, d23
vmla.u16 d26, d28, d22
vext.8 d19, d18, d19, #1
vaddl.u8 q14, d19, d24
vadd.s16 d2, d12, d14
vmls.u16 d26, d28, d23
vqrshrun.s32 d0, q0, #0xa
vadd.s16 d3, d10, d16
vld1.32 {q9}, [r0], r2 @ row 5 load
vext.8 d25, d18, d19, #5
vqmovn.u16 d11, q0
vaddl.u8 q14, d18, d25
vst1.32 d26, [r9], r6 @ store temp buffer 6
@Q3 available here
vld1.32 d6, [r7], r6 @ load from temp buffer 0
vld1.32 d7, [r7], r6 @ load from temp buffer 1
vqrshrun.s16 d9, q3, #5
vext.8 d20, d18, d19, #2
vaddl.s16 q0, d8, d26
vmlal.s16 q0, d2, d22
vext.8 d21, d18, d19, #3
vaddl.u8 q3, d20, d21
vext.8 d24, d18, d19, #4
vmlsl.s16 q0, d3, d23
vmla.u16 d28, d6, d22
vext.8 d19, d18, d19, #1
vaddl.u8 q3, d19, d24
vadd.s16 d2, d14, d16
vmls.u16 d28, d6, d23
vqrshrun.s32 d0, q0, #0xa
vadd.s16 d3, d12, d26
vld1.32 {q9}, [r0], r2 @ row 6 load
vext.8 d25, d18, d19, #5
vqmovn.u16 d13, q0
vtrn.32 d11, d13
vaddl.s16 q0, d10, d28
vrhadd.u8 d9, d9, d11
vst1.32 d28, [r9], r6 @ store temp buffer 7
vmlal.s16 q0, d2, d22
vaddl.u8 q15, d18, d25
vst1.32 d9[0], [r1], r3 @ store row 0
vext.8 d20, d18, d19, #2
vst1.32 d9[1], [r1], r3 @ store row 1
vext.8 d21, d18, d19, #3
vmlsl.s16 q0, d3, d23
vaddl.u8 q4, d20, d21
vext.8 d24, d18, d19, #4
vmla.u16 d30, d8, d22
vext.8 d19, d18, d19, #1
vaddl.u8 q4, d19, d24
vqrshrun.s32 d0, q0, #0xa
vadd.s16 d2, d16, d26
vmls.u16 d30, d8, d23
vqmovn.u16 d4, q0
vadd.s16 d3, d14, d28
vaddl.s16 q0, d12, d30
vst1.32 d30, [r9]
vmlal.s16 q0, d2, d22
vld1.32 d8, [r7], r6 @ load from temp buffer 2
vld1.32 d9, [r7], r6 @ load from temp buffer 3
vmlsl.s16 q0, d3, d23
subs r4, r4, #4
vqrshrun.s16 d10, q4, #5
vmov d12, d28
vqrshrun.s32 d0, q0, #0xa
vmov d6, d14
vmov d8, d16
vqmovn.u16 d5, q0
vtrn.32 d4, d5
vrhadd.u8 d4, d4, d10
vmov d10, d26
vmov d14, d30
vst1.32 d4[0], [r1], r3 @ store row 2
vst1.32 d4[1], [r1], r3 @ store row 3
bgt loop_4
end_func:
vldmia sp!, {d8-d15} @ Restore neon registers that were saved
ldmfd sp!, {r4-r12, pc} @Restoring registers from stack