| @/****************************************************************************** |
| @ * |
| @ * 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 |
| |
| |