///***************************************************************************** //* //* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore //* //* 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. //* //*****************************************************************************/ ///** //******************************************************************************* //* @file //* ihevc_intra_pred_filters_planar.s //* //* @brief //* contains function definitions for inter prediction interpolation. //* functions are coded using neon intrinsics and can be compiled using //* rvct //* //* @author //* akshaya mukund //* //* @par list of functions: //* //* //* @remarks //* none //* //******************************************************************************* //*/ ///** //******************************************************************************* //* //* @brief //* luma intraprediction filter for planar input //* //* @par description: //* //* @param[in] pu1_ref //* 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] pi1_coeff //* word8 pointer to the planar coefficients //* //* @param[in] nt //* size of tranform block //* //* @param[in] mode //* type of filtering //* //* @returns //* //* @remarks //* none //* //******************************************************************************* //*/ //void ihevc_intra_pred_luma_planar(uword8* pu1_ref, // word32 src_strd, // uword8* pu1_dst, // word32 dst_strd, // word32 nt, // word32 mode, // word32 pi1_coeff) //**************variables vs registers***************************************** //x0 => *pu1_ref //x1 => src_strd //x2 => *pu1_dst //x3 => dst_strd //stack contents from #40 // nt // mode // pi1_coeff .text .align 4 .include "ihevc_neon_macros.s" .globl ihevc_intra_pred_luma_planar_av8 .extern gau1_ihevc_planar_factor .extern gau1_ihevc_planar_factor_1 .type ihevc_intra_pred_luma_planar_av8, %function ihevc_intra_pred_luma_planar_av8: // stmfd sp!, {x4-x12, x14} //stack stores the values of the arguments stp x19, x20,[sp,#-16]! adrp x11, :got:gau1_ihevc_planar_factor //loads table of coeffs ldr x11, [x11, #:got_lo12:gau1_ihevc_planar_factor] clz w5,w4 sub x20, x5, #32 neg x5, x20 dup v29.8h,w5 neg v29.8h, v29.8h //shr value (so vneg) dup v2.8b,w4 //nt dup v16.8h,w4 //nt sub x6, x4, #1 //nt-1 add x6, x6, x0 ldr w7, [x6] sxtw x7,w7 dup v0.8b,w7 //src[nt-1] add x6, x4, x4,lsl #1 //3nt add x6, x6, #1 //3nt + 1 add x6, x6, x0 ldr w7, [x6] sxtw x7,w7 dup v1.8b,w7 //src[3nt+1] add x6, x4, x4 //2nt add x14, x6, #1 //2nt+1 sub x6, x6, #1 //2nt-1 add x6, x6, x0 //&src[2nt-1] add x14, x14, x0 //&src[2nt+1] mov x8, #1 //row+1 (row is first 0) sub x9, x4, x8 //nt-1-row (row is first 0) dup v5.8b,w8 //row + 1 dup v6.8b,w9 //nt - 1 - row mov v7.8b, v5.8b //mov #1 to d7 to used for inc for row+1 and dec for nt-1-row add x12, x11, #1 //coeffs (to be reloaded after every row) mov x1, x4 //nt (row counter) (dec after every row) mov x5, x2 //dst (to be reloaded after every row and inc by dst_strd) mov x10, #8 //increment for the coeffs mov x0, x14 //&src[2nt+1] (to be reloaded after every row) cmp x4, #4 beq tf_sz_4 //@ ========== ***************** ===================== prolog: tf_sz_8_16_32: mov x7, x4 //column counter (set to no of cols) lsr x9, x4, #3 //divide nt by 8 mul x7, x7, x9 //multiply width * height adrp x5, :got:gau1_ihevc_planar_factor_1 //loads table of coeffs ldr x5, [x5, #:got_lo12:gau1_ihevc_planar_factor_1] sub x6, x6, #7 mov x8, x2 lsl x9, x3, #3 //4*stride sub x20, x9, #8 //8-4*stride neg x9, x20 mov x10, x4 //nt sub x10, x10, #8 //nt - 8 col_loop_8_16_32: ld1 {v17.8b},[x12] //(1-8)load 8 coeffs [col+1] dup v27.8h,w4 //(1) ld1 {v4.8b},[x6] //(1-8)src[2nt-1-row] sub v19.8b, v2.8b , v17.8b //(1-8)[nt-1-col] umlal v27.8h, v5.8b, v0.8b //(1)(row+1) * src[nt-1] ld1 {v3.8b},[x14] //(1-8)load 8 src[2nt+1+col] umlal v27.8h, v17.8b, v1.8b //(1)(col+1) * src[3nt+1] dup v20.8b, v4.b[7] //(1) umlal v27.8h, v6.8b, v3.8b //(1)(nt-1-row) * src[2nt+1+col] dup v21.8b, v4.b[6] //(2) umlal v27.8h, v19.8b, v20.8b //(1)(nt-1-col) * src[2nt-1-row] dup v30.8h,w4 //(2) add v5.8b, v5.8b , v7.8b //(1) sub v6.8b, v6.8b , v7.8b //(1) dup v22.8b, v4.b[5] //(3) umlal v30.8h, v5.8b, v0.8b //(2) dup v28.8h,w4 //(3) umlal v30.8h, v17.8b, v1.8b //(2) umlal v30.8h, v6.8b, v3.8b //(2) umlal v30.8h, v19.8b, v21.8b //(2) sshl v27.8h, v27.8h, v29.8h //(1)shr add v5.8b, v5.8b , v7.8b //(2) sub v6.8b, v6.8b , v7.8b //(2) xtn v27.8b, v27.8h //(1) umlal v28.8h, v5.8b, v0.8b //(3) dup v23.8b, v4.b[4] //(4) umlal v28.8h, v17.8b, v1.8b //(3) dup v25.8h,w4 //(4) umlal v28.8h, v6.8b, v3.8b //(3) st1 {v27.8b},[x2], x3 //(1)str 8 values umlal v28.8h, v19.8b, v22.8b //(3) sshl v30.8h, v30.8h, v29.8h //(2)shr add v5.8b, v5.8b , v7.8b //(3) sub v6.8b, v6.8b , v7.8b //(3) xtn v30.8b, v30.8h //(2) umlal v25.8h, v5.8b, v0.8b //(4) dup v20.8b, v4.b[3] //(5) umlal v25.8h, v17.8b, v1.8b //(4) dup v16.8h,w4 //(5) umlal v25.8h, v6.8b, v3.8b //(4) st1 {v30.8b},[x2], x3 //(2)str 8 values umlal v25.8h, v19.8b, v23.8b //(4) sshl v28.8h, v28.8h, v29.8h //(3)shr add v5.8b, v5.8b , v7.8b //(4) sub v6.8b, v6.8b , v7.8b //(4) xtn v28.8b, v28.8h //(3) umlal v16.8h, v5.8b, v0.8b //(5) dup v21.8b, v4.b[2] //(6) umlal v16.8h, v17.8b, v1.8b //(5) dup v18.8h,w4 //(6) umlal v16.8h, v6.8b, v3.8b //(5) st1 {v28.8b},[x2], x3 //(3)str 8 values umlal v16.8h, v19.8b, v20.8b //(5) sshl v25.8h, v25.8h, v29.8h //(4)shr add v5.8b, v5.8b , v7.8b //(5) sub v6.8b, v6.8b , v7.8b //(5) xtn v25.8b, v25.8h //(4) umlal v18.8h, v5.8b, v0.8b //(6) dup v22.8b, v4.b[1] //(7) umlal v18.8h, v17.8b, v1.8b //(6) dup v26.8h,w4 //(7) umlal v18.8h, v6.8b, v3.8b //(6) st1 {v25.8b},[x2], x3 //(4)str 8 values umlal v18.8h, v19.8b, v21.8b //(6) sshl v16.8h, v16.8h, v29.8h //(5)shr add v5.8b, v5.8b , v7.8b //(6) sub v6.8b, v6.8b , v7.8b //(6) xtn v16.8b, v16.8h //(5) umlal v26.8h, v5.8b, v0.8b //(7) dup v23.8b, v4.b[0] //(8) umlal v26.8h, v17.8b, v1.8b //(7) dup v24.8h,w4 //(8) umlal v26.8h, v6.8b, v3.8b //(7) st1 {v16.8b},[x2], x3 //(5)str 8 values umlal v26.8h, v19.8b, v22.8b //(7) sshl v18.8h, v18.8h, v29.8h //(6)shr add v5.8b, v5.8b , v7.8b //(7) sub v6.8b, v6.8b , v7.8b //(7) xtn v18.8b, v18.8h //(6) umlal v24.8h, v5.8b, v0.8b //(8) umlal v24.8h, v17.8b, v1.8b //(8) umlal v24.8h, v6.8b, v3.8b //(8) st1 {v18.8b},[x2], x3 //(6)str 8 values umlal v24.8h, v19.8b, v23.8b //(8) sshl v26.8h, v26.8h, v29.8h //(7)shr subs x7, x7, #8 beq epilog subs x1, x1, #8 //row counter add x20, x12, #8 //col inc csel x12, x20, x12,gt add x20, x14, #8 //also for col inc csel x14, x20, x14,gt csel x1, x4, x1,le //nt reloaded (refresh the value) add x20, x11, #1 //x12 reset csel x12, x20, x12,le csel x14, x0, x14,le //x14 reset ld1 {v17.8b},[x12] //(1n)(1-8)load 8 coeffs [col+1] sub x20, x6, #8 //for next set of rows csel x6, x20, x6,le ld1 {v3.8b},[x14] //(1n)(1-8)load 8 src[2nt+1+col] add x20, x5, #8 csel x5, x20, x5,le dup v27.8h,w4 //(1n)(1) ld1 {v5.8b},[x5] ld1 {v4.8b},[x6] //(1n)(1-8)src[2nt-1-row] sub v19.8b, v2.8b , v17.8b //(1n)(1-8)[nt-1-col] dup v20.8b, v4.b[7] //(1n)(1) sub v6.8b, v2.8b , v5.8b beq epilog kernel_plnr: cmp x1, #0 // (cond loop) sshl v24.8h, v24.8h, v29.8h //(8)shr xtn v26.8b, v26.8h //(7) umlal v27.8h, v5.8b, v0.8b //(1)(row+1) * src[nt-1] xtn v24.8b, v24.8h //(8) umlal v27.8h, v17.8b, v1.8b //(1)(col+1) * src[3nt+1] dup v21.8b, v4.b[6] //(2) umlal v27.8h, v6.8b, v3.8b //(1)(nt-1-row) * src[2nt+1+col] dup v30.8h,w4 //(2) umlal v27.8h, v19.8b, v20.8b //(1)(nt-1-col) * src[2nt-1-row] st1 {v26.8b},[x2], x3 //(7)str 8 values add v5.8b, v5.8b , v7.8b //(1) st1 {v24.8b},[x2], x3 //(8)str 8 values sub v6.8b, v6.8b , v7.8b //(1) add x20, x2, x9 //since more cols to fill, dst + 8 - 6*strd (cond loop) csel x2, x20, x2,gt umlal v30.8h, v5.8b, v0.8b //(2) sub x20, x2, x10 //else go to next set of rows, dst - (nt-8) (cond loop) csel x2, x20, x2,le umlal v30.8h, v17.8b, v1.8b //(2) dup v22.8b, v4.b[5] //(3) umlal v30.8h, v6.8b, v3.8b //(2) dup v28.8h,w4 //(3) umlal v30.8h, v19.8b, v21.8b //(2) sshl v27.8h, v27.8h, v29.8h //(1)shr add v5.8b, v5.8b , v7.8b //(2) csel x1, x4, x1,le //nt reloaded (refresh the value) (cond loop) sub v6.8b, v6.8b , v7.8b //(2) subs x1, x1, #8 //row counter (loop) xtn v27.8b, v27.8h //(1) umlal v28.8h, v5.8b, v0.8b //(3) dup v23.8b, v4.b[4] //(4) umlal v28.8h, v17.8b, v1.8b //(3) dup v25.8h,w4 //(4) umlal v28.8h, v6.8b, v3.8b //(3) st1 {v27.8b},[x2], x3 //(1)str 8 values umlal v28.8h, v19.8b, v22.8b //(3) sshl v30.8h, v30.8h, v29.8h //(2)shr add v5.8b, v5.8b , v7.8b //(3) sub v6.8b, v6.8b , v7.8b //(3) xtn v30.8b, v30.8h //(2) umlal v25.8h, v5.8b, v0.8b //(4) dup v20.8b, v4.b[3] //(5) umlal v25.8h, v17.8b, v1.8b //(4) dup v16.8h,w4 //(5) umlal v25.8h, v6.8b, v3.8b //(4) st1 {v30.8b},[x2], x3 //(2)str 8 values umlal v25.8h, v19.8b, v23.8b //(4) sshl v28.8h, v28.8h, v29.8h //(3)shr add v5.8b, v5.8b , v7.8b //(4) sub v6.8b, v6.8b , v7.8b //(4) xtn v28.8b, v28.8h //(3) umlal v16.8h, v5.8b, v0.8b //(5) dup v21.8b, v4.b[2] //(6) umlal v16.8h, v17.8b, v1.8b //(5) dup v18.8h,w4 //(6) umlal v16.8h, v6.8b, v3.8b //(5) st1 {v28.8b},[x2], x3 //(3)str 8 values umlal v16.8h, v19.8b, v20.8b //(5) add x20, x11, #1 //x12 reset (cond loop) csel x12, x20, x12,le sshl v25.8h, v25.8h, v29.8h //(4)shr add x20, x12, #8 //col inc (cond loop) csel x12, x20, x12,gt add v5.8b, v5.8b , v7.8b //(5) add x20, x14, #8 //also for col inc (cond loop) csel x14, x20, x14,gt sub v6.8b, v6.8b , v7.8b //(5) xtn v25.8b, v25.8h //(4) umlal v18.8h, v5.8b, v0.8b //(6) dup v22.8b, v4.b[1] //(7) umlal v18.8h, v17.8b, v1.8b //(6) dup v26.8h,w4 //(7) umlal v18.8h, v6.8b, v3.8b //(6) st1 {v25.8b},[x2], x3 //(4)str 8 values umlal v18.8h, v19.8b, v21.8b //(6) csel x14, x0, x14,le //x14 reset (cond loop) sshl v16.8h, v16.8h, v29.8h //(5)shr sub x20, x6, #8 //for next set of rows (cond loop) csel x6, x20, x6,le add v5.8b, v5.8b , v7.8b //(6) add x20, x5, #8 // (cond loop) csel x5, x20, x5,le sub v6.8b, v6.8b , v7.8b //(6) xtn v16.8b, v16.8h //(5) umlal v26.8h, v5.8b, v0.8b //(7) dup v23.8b, v4.b[0] //(8) umlal v26.8h, v17.8b, v1.8b //(7) dup v24.8h,w4 //(8) umlal v26.8h, v6.8b, v3.8b //(7) st1 {v16.8b},[x2], x3 //(5)str 8 values umlal v26.8h, v19.8b, v22.8b //(7) ld1 {v4.8b},[x6] //(1n)(1-8)src[2nt-1-row] sshl v18.8h, v18.8h, v29.8h //(6)shr add v5.8b, v5.8b , v7.8b //(7) sub v6.8b, v6.8b , v7.8b //(7) xtn v18.8b, v18.8h //(6) umlal v24.8h, v5.8b, v0.8b //(8) ld1 {v5.8b},[x5] //(row+1 value) umlal v24.8h, v17.8b, v1.8b //(8) dup v20.8b, v4.b[7] //(1n)(1) umlal v24.8h, v6.8b, v3.8b //(8) st1 {v18.8b},[x2], x3 //(6)str 8 values umlal v24.8h, v19.8b, v23.8b //(8) ld1 {v17.8b},[x12] //(1n)(1-8)load 8 coeffs [col+1] sub v6.8b, v2.8b , v5.8b //(nt-1-row) value subs x7, x7, #8 //col counter ld1 {v3.8b},[x14] //(1n)(1-8)load 8 src[2nt+1+col] sshl v26.8h, v26.8h, v29.8h //(7)shr dup v27.8h,w4 //(1n)(1) sub v19.8b, v2.8b , v17.8b //(1n)(1-8)[nt-1-col] bne kernel_plnr epilog: xtn v26.8b, v26.8h //(7) st1 {v26.8b},[x2], x3 //(7)str 8 values sshl v24.8h, v24.8h, v29.8h //(8)shr xtn v24.8b, v24.8h //(8) st1 {v24.8b},[x2], x3 //(8)str 8 values //@ ========== ***************** ===================== beq end_loop tf_sz_4: ld1 {v25.8b},[x14] //load src[2nt+1+col] ld1 {v17.8b},[x12], x10 //load 8 coeffs [col+1] loop_sz_4: mov x10, #4 //reduce inc to #4 for 4x4 ldr w7, [x6], #-1 //src[2nt-1-row] (dec to take into account row) sxtw x7,w7 dup v4.8b,w7 //src[2nt-1-row] sub v19.8b, v2.8b , v17.8b //[nt-1-col] umull v27.8h, v5.8b, v0.8b //(row+1) * src[nt-1] umlal v27.8h, v6.8b, v25.8b //(nt-1-row) * src[2nt+1+col] umlal v27.8h, v17.8b, v1.8b //(col+1) * src[3nt+1] umlal v27.8h, v19.8b, v4.8b //(nt-1-col) * src[2nt-1-row] // vadd.i16 q6, q6, q8 @add (nt) // vshl.s16 q6, q6, q7 @shr // vmovn.i16 d12, q6 rshrn v27.8b, v27.8h,#3 st1 {v27.s}[0],[x2], x3 add v5.8b, v5.8b , v7.8b //row++ [(row+1)++] sub v6.8b, v6.8b , v7.8b //[nt-1-row]-- subs x1, x1, #1 bne loop_sz_4 end_loop: // ldmfd sp!,{x4-x12,x15} //reload the registers from sp ldp x19, x20,[sp],#16 ret