ref: b7a25df13f2641504d8a77e3ab0110ee25d75920
dir: /codec/common/deblocking_neon.S/
/*! * \copy * Copyright (c) 2013, Cisco Systems * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #ifdef HAVE_NEON .text #include "arm_arch_common_macro.S" #ifdef APPLE_IOS .macro JMP_IF_128BITS_IS_ZERO // { vorr.s16 $2, $0, $1 vmov r3, r2, $2 orr r3, r3, r2 cmp r3, #0 // } .endm // if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta ) .macro MASK_MATRIX // { input: p1, p0, q0, q1, alpha(be modified), beta; output: mask vabd.u8 $6, $1, $2 // abs( p0 - q0 ) vcgt.u8 $6, $4, $6 // mask = abs( p0 - q0 ) < alpha vabd.u8 $4, $0, $1 // abs( p1 - p0 ) vclt.u8 $4, $4, $5 // abs( p1 - p0 ) < beta vand.u8 $6, $6, $4 // 2nd mask & vabd.u8 $4, $3, $2 // abs( q1 - q0 ) vclt.u8 $4, $4, $5 // abs( q1 - q0 ) < beta vand.u8 $6, $6, $4 // 3rd mask & // } .endm //if( abs( p2 - p0 ) < beta ) //{ // pix[-2*xstride] = p1 + x264_clip3( (( p2 + ((p0 + q0 + 1)>> 1)) >> 1) - p1, -tc0[i], tc0[i] ); // tc++; //} .macro DIFF_LUMA_LT4_P1_Q1 // { input: p2, p1, p0, q0, beta, -tc0[i], tc0[i], mask_matrx; output: _clip3(p1'), tc++; vabd.u8 $9, $0, $2 // abs( p2 - p0 ) vclt.u8 $9, $9, $4 // abs( p2 - p0 ) < beta vrhadd.u8 $8, $2, $3 // ((p0 + q0 + 1)>> 1) vhadd.u8 $8, $0, $8 // (( p2 + ((p0 + q0 + 1)>> 1)) >> 1) vsub.s8 $8, $8, $1 // (( p2 + ((p0 + q0 + 1)>> 1)) >> 1) - p1 vmax.s8 $8, $8, $5 // >= -tc0[i] vmin.s8 $8, $8, $6 // <= tc0[i] vand.s8 $8, $8, $9 // mask, only [abs( p2 - p0 ) < beta] avail _clip3 vand.s8 $8, $8, $7 vadd.u8 $8, $1, $8 vabs.s8 $9, $9 // if( abs( p2 - p0 ) < beta ) tc++; // } .endm //delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3,-tc, tc ); .macro DIFF_LUMA_LT4_P0_Q0 // { input: p1, p0, q0, q1; output: _clip3(p0'); working q12,q13 vsubl.u8 $5, $0, $3 // (p1 - q1) vsubl.u8 $6, $2, $1 // (q0 - p0) vshl.s16 $6, $6, #2 vadd.s16 $5, $5, $6 // (p1 - q1) += ( q0 - p0 ) <<2 vrshrn.s16 $4, $5, #3 // } .endm //if( abs( p2 - p0 ) < beta ) /* p0', p1', p2' */ //{ // const int p3 = pix[-4*xstride]; // pix[-1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3; // pix[-2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2; // pix[-3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3; //} //else /* p0' */ // pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; .macro DIFF_LUMA_EQ4_P2P1P0 // { input: p3(output p1'), p2, p1, p0, q0, q1, select_matrix(output p0'), output p2'; // workin q4~q5; after filtered then p3/p2 useless! vaddl.u8 q4, $1, $2 // (p2 + p1) vaddl.u8 q5, $3, $4 // (p0 + q0) vadd.u16 q5, q4, q5 // p1'=(p2 + p1)+(p0 + q0) vaddl.u8 q4, $0, $1 // (p3 + p2) vshl.u16 q4, q4, #1 vadd.u16 q4, q5, q4 // p2'=2*(p3 + p2)+(p2 + p1)+(p0 + q0) vrshrn.u16 $0, q5, #2 // p1', prev p3 useless now vrshrn.u16 $7, q4, #3 // p2' vshl.u16 q5, q5, #1 // ((p2 + p1)+(p0 + q0))*2 vsubl.u8 q4, $5, $1 // (q1 - p2) vadd.u16 q5, q4,q5 // 5tags p0'=(q1 - p2)+((p2 + p1)+(p0 + q0))*2 vaddl.u8 q4, $2, $5 // (p1 + q1) vaddw.u8 q4, q4, $2 vaddw.u8 q4, q4, $3 // 3tags p0'=2*p1+(p0 + q1) vrshrn.u16 d10,q5, #3 // 5tags vrshrn.u16 d8, q4, #2 // 3tags vbsl.u8 $6, d10, d8 // p0' // } .endm .macro DIFF_LUMA_EQ4_MASK // { input: px', px, mask_matrix; working q4 vmov $3, $2 vbsl.u8 $3, $0, $1 // } .endm // ( (p1 << 1) + p0 + q1 + 2 ) >> 2 .macro DIFF_CHROMA_EQ4_P0Q0 // { input: p1, p0, q0, q1; working q4/q5/q6; output: p0'_d, q0'_d vaddl.u8 $4, $0, $3 // (p1 + q1) vaddw.u8 $5, $4, $1 vaddw.u8 $6, $4, $2 vaddw.u8 $5, $5, $0 // p0'=(p1 + q1)+(p0+p1) // vaddw.u8 $6, $4, $2 vaddw.u8 $6, $6, $3 // q0'=(p1 + q1)+(q0+q1) vrshrn.u16 $7, $5, #2 vrshrn.u16 $8, $6, #2 // } .endm .macro LORD_CHROMA_DATA_4 // { input: 4xCb_addr, 4xCr_addr, working r0~r2 vld4.u8 {$0[$8],$1[$8],$2[$8],$3[$8]}, [r0], r2 // Cb vld4.u8 {$4[$8],$5[$8],$6[$8],$7[$8]}, [r1], r2 // Cr // } .endm .macro STORE_CHROMA_DATA_4 // { input: 4xCb_addr, 4xCr_addr, working r0~r2 vst4.u8 {$0[$8],$1[$8],$2[$8],$3[$8]}, [r0], r2 // Cb vst4.u8 {$4[$8],$5[$8],$6[$8],$7[$8]}, [r1], r2 // Cr // } .endm .macro LORD_LUMA_DATA_3 // { input: 3xluma_addr, working r0~r2 vld3.u8 {$0[$6],$1[$6],$2[$6]}, [r2], r1 // 0::pix[-3];1::pix[-2];2::pix[-1]; vld3.u8 {$3[$6],$4[$6],$5[$6]}, [r0], r1 // 3::pix[0]; 4::pix[1]; 5::pix[2]; // } .endm .macro STORE_LUMA_DATA_4 // { input: 4xluma, working r0~r2 vst4.u8 {$0[$4],$1[$4],$2[$4],$3[$4]}, [r0], r1 // 0::pix[-2];1::pix[-1];2::pix[0]; 3::pix[1] vst4.u8 {$0[$5],$1[$5],$2[$5],$3[$5]}, [r2], r1 // } .endm .macro LORD_LUMA_DATA_4 // { input: 4xluma_addr, working r0r1r3 vld4.u8 {$0[$8],$1[$8],$2[$8],$3[$8]}, [r3], r1 // 0::pix[-4];1::pix[-3];2::pix[-2];3::pix[-1] vld4.u8 {$4[$8],$5[$8],$6[$8],$7[$8]}, [r0], r1 // 4::pix[0]; 5::pix[1]; 6::pix[2]; 7::pix[3]; // } .endm .macro STORE_LUMA_DATA_3 // { input: 3xluma_addr, working r0~r2 vst3.u8 {$0[$6],$1[$6],$2[$6]}, [r3], r1 // 0::pix[-3];1::pix[-2];2::pix[-1]; vst3.u8 {$3[$6],$4[$6],$5[$6]}, [r0], r1 // 3::pix[0]; 4::pix[1]; 5::pix[2]; // } .endm .macro EXTRACT_DELTA_INTO_TWO_PART // { input: delta (output abs minus part), working (output plus part) vcge.s8 $1, $0, #0 vand $1, $0, $1 // select original (+part) vsub.s8 $0, $1, $0 // select original -(-part) // } .endm #else .macro JMP_IF_128BITS_IS_ZERO arg0, arg1, arg2 // { vorr.s16 \arg2, \arg0, \arg1 vmov r3, r2, \arg2 orr r3, r3, r2 cmp r3, #0 // } .endm // if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta ) .macro MASK_MATRIX arg0, arg1, arg2, arg3, arg4, arg5, arg6 // { input: p1, p0, q0, q1, alpha(be modified), beta; output: mask vabd.u8 \arg6, \arg1, \arg2 // abs( p0 - q0 ) vcgt.u8 \arg6, \arg4, \arg6 // mask = abs( p0 - q0 ) < alpha vabd.u8 \arg4, \arg0, \arg1 // abs( p1 - p0 ) vclt.u8 \arg4, \arg4, \arg5 // abs( p1 - p0 ) < beta vand.u8 \arg6, \arg6, \arg4 // 2nd mask & vabd.u8 \arg4, \arg3, \arg2 // abs( q1 - q0 ) vclt.u8 \arg4, \arg4, \arg5 // abs( q1 - q0 ) < beta vand.u8 \arg6, \arg6, \arg4 // 3rd mask & // } .endm //if( abs( p2 - p0 ) < beta ) //{ // pix[-2*xstride] = p1 + x264_clip3( (( p2 + ((p0 + q0 + 1)>> 1)) >> 1) - p1, -tc0[i], tc0[i] ); // tc++; //} .macro DIFF_LUMA_LT4_P1_Q1 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9 // { input: p2, p1, p0, q0, beta, -tc0[i], tc0[i], mask_matrx; output: _clip3(p1'), tc++; vabd.u8 \arg9, \arg0, \arg2 // abs( p2 - p0 ) vclt.u8 \arg9, \arg9, \arg4 // abs( p2 - p0 ) < beta vrhadd.u8 \arg8, \arg2, \arg3 // ((p0 + q0 + 1)>> 1) vhadd.u8 \arg8, \arg0, \arg8 // (( p2 + ((p0 + q0 + 1)>> 1)) >> 1) vsub.s8 \arg8, \arg8, \arg1 // (( p2 + ((p0 + q0 + 1)>> 1)) >> 1) - p1 vmax.s8 \arg8, \arg8, \arg5 // >= -tc0[i] vmin.s8 \arg8, \arg8, \arg6 // <= tc0[i] vand.s8 \arg8, \arg8, \arg9 // mask, only [abs( p2 - p0 ) < beta] avail _clip3 vand.s8 \arg8, \arg8, \arg7 vadd.u8 \arg8, \arg1, \arg8 vabs.s8 \arg9, \arg9 // if( abs( p2 - p0 ) < beta ) tc++; // } .endm //delta = x264_clip3( (((q0 - p0 ) << 2) + (p1 - q1) + 4) >> 3,-tc, tc ); .macro DIFF_LUMA_LT4_P0_Q0 arg0, arg1, arg2, arg3, arg4, arg5, arg6 // { input: p1, p0, q0, q1; output: _clip3(p0'); working q12,q13 vsubl.u8 \arg5, \arg0, \arg3 // (p1 - q1) vsubl.u8 \arg6, \arg2, \arg1 // (q0 - p0) vshl.s16 \arg6, \arg6, #2 vadd.s16 \arg5, \arg5, \arg6 // (p1 - q1) += ( q0 - p0 ) <<2 vrshrn.s16 \arg4, \arg5, #3 // } .endm //if( abs( p2 - p0 ) < beta ) /* p0', p1', p2' */ //{ // const int p3 = pix[-4*xstride]; // pix[-1*xstride] = ( p2 + 2*p1 + 2*p0 + 2*q0 + q1 + 4 ) >> 3; // pix[-2*xstride] = ( p2 + p1 + p0 + q0 + 2 ) >> 2; // pix[-3*xstride] = ( 2*p3 + 3*p2 + p1 + p0 + q0 + 4 ) >> 3; //} //else /* p0' */ // pix[-1*xstride] = ( 2*p1 + p0 + q1 + 2 ) >> 2; .macro DIFF_LUMA_EQ4_P2P1P0 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7 // { input: p3(output p1'), p2, p1, p0, q0, q1, select_matrix(output p0'), output p2'; // workin q4~q5; after filtered then p3/p2 useless! vaddl.u8 q4, \arg1, \arg2 // (p2 + p1) vaddl.u8 q5, \arg3, \arg4 // (p0 + q0) vadd.u16 q5, q4, q5 // p1'=(p2 + p1)+(p0 + q0) vaddl.u8 q4, \arg0, \arg1 // (p3 + p2) vshl.u16 q4, q4, #1 vadd.u16 q4, q5, q4 // p2'=2*(p3 + p2)+(p2 + p1)+(p0 + q0) vrshrn.u16 \arg0, q5, #2 // p1', prev p3 useless now vrshrn.u16 \arg7, q4, #3 // p2' vshl.u16 q5, q5, #1 // ((p2 + p1)+(p0 + q0))*2 vsubl.u8 q4, \arg5, \arg1 // (q1 - p2) vadd.u16 q5, q4,q5 // 5tags p0'=(q1 - p2)+((p2 + p1)+(p0 + q0))*2 vaddl.u8 q4, \arg2, \arg5 // (p1 + q1) vaddw.u8 q4, q4, \arg2 vaddw.u8 q4, q4, \arg3 // 3tags p0'=2*p1+(p0 + q1) vrshrn.u16 d10,q5, #3 // 5tags vrshrn.u16 d8, q4, #2 // 3tags vbsl.u8 \arg6, d10, d8 // p0' // } .endm .macro DIFF_LUMA_EQ4_MASK arg0, arg1, arg2, arg3 // { input: px', px, mask_matrix; working q4 vmov \arg3, \arg2 vbsl.u8 \arg3, \arg0, \arg1 // } .endm // ( (p1 << 1) + p0 + q1 + 2 ) >> 2 .macro DIFF_CHROMA_EQ4_P0Q0 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 // { input: p1, p0, q0, q1; working q4/q5/q6; output: p0'_d, q0'_d vaddl.u8 \arg4, \arg0, \arg3 // (p1 + q1) vaddw.u8 \arg5, \arg4, \arg1 vaddw.u8 \arg6, \arg4, \arg2 vaddw.u8 \arg5, \arg5, \arg0 // p0'=(p1 + q1)+(p0+p1) // vaddw.u8 \arg6, \arg4, \arg2 vaddw.u8 \arg6, \arg6, \arg3 // q0'=(p1 + q1)+(q0+q1) vrshrn.u16 \arg7, \arg5, #2 vrshrn.u16 \arg8, \arg6, #2 // } .endm .macro LORD_CHROMA_DATA_4 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 // { input: 4xCb_addr, 4xCr_addr, working r0~r2 vld4.u8 {\arg0[\arg8],\arg1[\arg8],\arg2[\arg8],\arg3[\arg8]}, [r0], r2 // Cb vld4.u8 {\arg4[\arg8],\arg5[\arg8],\arg6[\arg8],\arg7[\arg8]}, [r1], r2 // Cr // } .endm .macro STORE_CHROMA_DATA_4 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 // { input: 4xCb_addr, 4xCr_addr, working r0~r2 vst4.u8 {\arg0[\arg8],\arg1[\arg8],\arg2[\arg8],\arg3[\arg8]}, [r0], r2 // Cb vst4.u8 {\arg4[\arg8],\arg5[\arg8],\arg6[\arg8],\arg7[\arg8]}, [r1], r2 // Cr // } .endm .macro LORD_LUMA_DATA_3 arg0, arg1, arg2, arg3, arg4, arg5, arg6 // { input: 3xluma_addr, working r0~r2 vld3.u8 {\arg0[\arg6],\arg1[\arg6],\arg2[\arg6]}, [r2], r1 // 0::pix[-3];1::pix[-2];2::pix[-1]; vld3.u8 {\arg3[\arg6],\arg4[\arg6],\arg5[\arg6]}, [r0], r1 // 3::pix[0]; 4::pix[1]; 5::pix[2]; // } .endm .macro STORE_LUMA_DATA_4 arg0, arg1, arg2, arg3, arg4, arg5 // { input: 4xluma, working r0~r2 vst4.u8 {\arg0[\arg4],\arg1[\arg4],\arg2[\arg4],\arg3[\arg4]}, [r0], r1 // 0::pix[-2];1::pix[-1];2::pix[0]; 3::pix[1] vst4.u8 {\arg0[\arg5],\arg1[\arg5],\arg2[\arg5],\arg3[\arg5]}, [r2], r1 // } .endm .macro LORD_LUMA_DATA_4 arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8 // { input: 4xluma_addr, working r0r1r3 vld4.u8 {\arg0[\arg8],\arg1[\arg8],\arg2[\arg8],\arg3[\arg8]}, [r3], r1 // 0::pix[-4];1::pix[-3];2::pix[-2];3::pix[-1] vld4.u8 {\arg4[\arg8],\arg5[\arg8],\arg6[\arg8],\arg7[\arg8]}, [r0], r1 // 4::pix[0]; 5::pix[1]; 6::pix[2]; 7::pix[3]; // } .endm .macro STORE_LUMA_DATA_3 arg0, arg1, arg2, arg3, arg4, arg5, arg6 // { input: 3xluma_addr, working r0~r2 vst3.u8 {\arg0[\arg6],\arg1[\arg6],\arg2[\arg6]}, [r3], r1 // 0::pix[-3];1::pix[-2];2::pix[-1]; vst3.u8 {\arg3[\arg6],\arg4[\arg6],\arg5[\arg6]}, [r0], r1 // 3::pix[0]; 4::pix[1]; 5::pix[2]; // } .endm .macro EXTRACT_DELTA_INTO_TWO_PART arg0, arg1 // { input: delta (output abs minus part), working (output plus part) vcge.s8 \arg1, \arg0, #0 vand \arg1, \arg0, \arg1 // select original (+part) vsub.s8 \arg0, \arg1, \arg0 // select original -(-part) // } .endm #endif //uint8_t *pix, int32_t stride, int32_t alpha, int32_t beta, uint8_t *tc WELS_ASM_FUNC_BEGIN DeblockLumaLt4V_neon vdup.u8 q11, r2 // alpha [0~255] vdup.u8 q9, r3 // q9:: beta [0~18] add r2, r1, r1, lsl #1 sub r2, r0, r2 // pix -= 3*src_stride] vld1.u8 {q0}, [r2], r1 // q0::p2 = pix[-3*xstride]; vld1.u8 {q3}, [r0], r1 // q3::q0 = pix[ 0*xstride]; vld1.u8 {q1}, [r2], r1 // q1::p1 = pix[-2*xstride]; vld1.u8 {q4}, [r0], r1 // q4::q1 = pix[ 1*xstride]; vld1.u8 {q2}, [r2] // q2::p0 = pix[-1*xstride]; vld1.u8 {q5}, [r0] // q5::q2 = pix[ 2*xstride]; sub r2, r2, r1 // r2 = pix-2*xstride // if( tc0[i] < 0 ) continue; else filter ldr r3, [sp, #0] vld1.s8 {d31}, [r3] // load 4 tc0[i] vdup.s8 d28, d31[0] vdup.s8 d30, d31[1] vdup.s8 d29, d31[2] vdup.s8 d31, d31[3] vtrn.32 d28, d30 vtrn.32 d29, d31 // q14::each 32 bits is 4x tc0[i] vcge.s8 q10, q14, #0 // q10::tc0[i] >= 0 // if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta ) MASK_MATRIX q1, q2, q3, q4, q11, q9, q15 // q15::mask matrix vand.u8 q10, q10, q15 // two mask // JMP_IF_128BITS_IS_ZERO d20, d21, d31 // beq lt4_end veor q15, q15 vsub.i8 q15,q15,q14 // q15::4x -tc0[i], min // input: p2, p1, p0, q0, beta, -tc0[i], tc0[i]; mask_matrx, output: _clip3(p1'), tc++; DIFF_LUMA_LT4_P1_Q1 q0, q1, q2, q3, q9, q15, q14, q10, q6, q12 // q6 = _clip3(p1') vst1.u8 {q6}, [r2], r1 DIFF_LUMA_LT4_P1_Q1 q5, q4, q3, q2, q9, q15, q14, q10, q7, q13 // q7 = _clip3(q1') vabs.s8 q12, q12 vabs.s8 q13, q13 // if( abs( p2 - p0 ) < beta ) tc++; vadd.u8 q14,q14,q12 vadd.u8 q14,q14,q13 // updated tc veor q15, q15 vsub.i8 q15,q15,q14 // updated -tc // input: p1, p0, q0, q1; output: _clip3(p0'); working q12,q13 DIFF_LUMA_LT4_P0_Q0 d2, d4, d6, d8, d16, q12, q13 DIFF_LUMA_LT4_P0_Q0 d3, d5, d7, d9, d17, q12, q13 //q8::delta vmax.s8 q8, q8, q15 // >= -tc0[i] vmin.s8 q8, q8, q14 // <= tc0[i] vand.s8 q8, q8, q10 EXTRACT_DELTA_INTO_TWO_PART q8, q9 vqadd.u8 q2, q2, q9 // clip_uint8( p0 + [+delta] ); p0' vqsub.u8 q2, q2, q8 // clip_uint8( p0 - [-delta] ); p0' vst1.u8 {q2}, [r2], r1 vqsub.u8 q3, q3, q9 // clip_uint8( q0 - [+delta] ); q0' vqadd.u8 q3, q3, q8 // clip_uint8( q0 + [-delta] ); q0' vst1.u8 {q3}, [r2] , r1 vst1.u8 {q7}, [r2] //lt4_end: WELS_ASM_FUNC_END //uint8_t *pix, int32_t stride, int32_t alpha, int32_t beta WELS_ASM_FUNC_BEGIN DeblockLumaEq4V_neon vdup.u8 q5, r2 // alpha [0~255] vdup.u8 q4, r3 // beta [0~18] sub r3, r0, r1, lsl #2 // pix -= 4*src_stride vld1.u8 {q8}, [r3], r1 // q8::p3 = pix[-4*xstride]; vld1.u8 {q12}, [r0], r1 // q12::q0 = pix[ 0*xstride]; vld1.u8 {q9}, [r3], r1 // q9::p2 = pix[-3*xstride]; vld1.u8 {q13}, [r0], r1 // q13::q1 = pix[ 1*xstride]; vld1.u8 {q10}, [r3], r1 // q10::p1 = pix[-2*xstride]; vld1.u8 {q14}, [r0], r1 // q14::q2 = pix[ 2*xstride]; vld1.u8 {q11}, [r3] // q11::p0 = pix[-1*xstride]; vld1.u8 {q15}, [r0] // q15::q3 = pix[ 3*xstride]; sub r3, r3, r1 , lsl #1 // r3 = pix-3*xstride // if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta ) MASK_MATRIX q10, q11, q12, q13, q5, q4, q6 // q6::mask matrix // JMP_IF_128BITS_IS_ZERO d12, d13, d0 // beq eq4_end // if(abs( p0 - q0 ) < ((alpha >> 2) + 2) ) mov r2, r2, lsr #2 add r2, r2, #2 vdup.u8 q5, r2 vabd.u8 q0, q11, q12 vclt.u8 q7, q0, q5 // q7::indicate // if( abs( p2 - p0 ) < beta ) vabd.u8 q1, q9, q11 vclt.u8 q1, q1, q4 vand.s8 q1, q1, q7 // q1::indicate [p0', p1', p2'] or [p0'] // if( abs( q2 - q0 ) < beta ) vabd.u8 q2, q14,q12 vclt.u8 q2, q2, q4 vand.s8 q2, q2, q7 // q2::indicate [q0', q1', q2'] or [q0'] vand.u8 q7, q7, q6 vmov q3, q1 // input: p3(output p1'), p2, p1, p0, q0, q1, select_matrix(output p0'), output p2'; // workin q4~q5; after filtered then p3/p2 useless! DIFF_LUMA_EQ4_P2P1P0 d16, d18, d20, d22, d24, d26, d2, d0 DIFF_LUMA_EQ4_P2P1P0 d17, d19, d21, d23, d25, d27, d3, d1 // q1(p0') q2(q0') only need ::if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta ) // q0(p2') q8(p1') q15(q1') q3(q2'); need more &&if(abs( p0 - q0 ) < ((alpha >> 2) + 2) )&&if( abs( p2 - p0 ) < beta ) vand.u8 q3, q7, q3 DIFF_LUMA_EQ4_MASK q0, q9, q3, q4 vst1.u8 {q4}, [r3], r1 DIFF_LUMA_EQ4_MASK q8,q10, q3, q4 vst1.u8 {q4}, [r3], r1 DIFF_LUMA_EQ4_MASK q1,q11, q6, q4 vst1.u8 {q4}, [r3], r1 vmov q0, q2 DIFF_LUMA_EQ4_P2P1P0 d30, d28, d26, d24, d22, d20, d4, d6 DIFF_LUMA_EQ4_P2P1P0 d31, d29, d27, d25, d23, d21, d5, d7 vand.u8 q0, q7, q0 DIFF_LUMA_EQ4_MASK q2, q12, q6, q4 vst1.u8 {q4}, [r3], r1 DIFF_LUMA_EQ4_MASK q15, q13, q0, q4 vst1.u8 {q4}, [r3], r1 DIFF_LUMA_EQ4_MASK q3, q14, q0, q4 vst1.u8 {q4}, [r3], r1 //eq4_end: WELS_ASM_FUNC_END //uint8_t *pix, int32_t stride, int32_t alpha, int32_t beta, uint8_t *tc WELS_ASM_FUNC_BEGIN DeblockLumaLt4H_neon vdup.u8 q11, r2 // alpha [0~255] vdup.u8 q9, r3 // q9:: beta [0~18] sub r2, r0, #3 // pix -= 3 LORD_LUMA_DATA_3 d0, d1, d2, d6, d7, d8, 0 LORD_LUMA_DATA_3 d0, d1, d2, d6, d7, d8, 1 LORD_LUMA_DATA_3 d0, d1, d2, d6, d7, d8, 2 LORD_LUMA_DATA_3 d0, d1, d2, d6, d7, d8, 3 LORD_LUMA_DATA_3 d0, d1, d2, d6, d7, d8, 4 LORD_LUMA_DATA_3 d0, d1, d2, d6, d7, d8, 5 LORD_LUMA_DATA_3 d0, d1, d2, d6, d7, d8, 6 LORD_LUMA_DATA_3 d0, d1, d2, d6, d7, d8, 7 LORD_LUMA_DATA_3 d3, d4, d5, d9, d10, d11, 0 LORD_LUMA_DATA_3 d3, d4, d5, d9, d10, d11, 1 LORD_LUMA_DATA_3 d3, d4, d5, d9, d10, d11, 2 LORD_LUMA_DATA_3 d3, d4, d5, d9, d10, d11, 3 LORD_LUMA_DATA_3 d3, d4, d5, d9, d10, d11, 4 LORD_LUMA_DATA_3 d3, d4, d5, d9, d10, d11, 5 LORD_LUMA_DATA_3 d3, d4, d5, d9, d10, d11, 6 LORD_LUMA_DATA_3 d3, d4, d5, d9, d10, d11, 7 // d0d1d2d6d7d8+d3d4d5d9d10d11 vswp d1, d2 vswp d3, d4 vswp d1, d4 vswp d7, d8 vswp d9, d10 vswp d7, d10 // q0::p2 = pix[-3*xstride]; // q1::p1 = pix[-2*xstride]; // q2::p0 = pix[-1*xstride]; // q3::q0 = pix[ 0*xstride]; // q4::q1 = pix[ 1*xstride]; // q5::q2 = pix[ 2*xstride]; sub r0, r0, r1, lsl #4 // pix -= 16*src_stride // if( tc0[i] < 0 ) continue; else filter ldr r3, [sp, #0] vld1.s8 {d31}, [r3] // load 4 tc0[i] vdup.s8 d28, d31[0] vdup.s8 d30, d31[1] vdup.s8 d29, d31[2] vdup.s8 d31, d31[3] vtrn.32 d28, d30 vtrn.32 d29, d31 // q14::each 32 bits is 4x tc0[i] vcge.s8 q10, q14, #0 // q10::tc0[i] >= 0 // if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta ) MASK_MATRIX q1, q2, q3, q4, q11, q9, q15 // q15::mask matrix vand.u8 q10, q10, q15 // two mask // JMP_IF_128BITS_IS_ZERO d20, d21, d31 // beq lt4_end veor q15, q15 vsub.i8 q15,q15,q14 // q15::4x -tc0[i], min // input: p2, p1, p0, q0, beta, -tc0[i], tc0[i]; mask_matrx, output: _clip3(p1'), tc++; DIFF_LUMA_LT4_P1_Q1 q0, q1, q2, q3, q9, q15, q14, q10, q6, q12 // q6 = _clip3(p1') DIFF_LUMA_LT4_P1_Q1 q5, q4, q3, q2, q9, q15, q14, q10, q7, q13 // q7 = _clip3(q1') vabs.s8 q12, q12 vabs.s8 q13, q13 // if( abs( p2 - p0 ) < beta ) tc++; vadd.u8 q14,q14,q12 vadd.u8 q14,q14,q13 // updated tc veor q15, q15 vsub.i8 q15,q15,q14 // updated -tc // input: p1, p0, q0, q1; output: _clip3(p0'); working q12,q13 DIFF_LUMA_LT4_P0_Q0 d2, d4, d6, d8, d16, q12, q13 DIFF_LUMA_LT4_P0_Q0 d3, d5, d7, d9, d17, q12, q13 //q8::delta vmax.s8 q8, q8, q15 // >= -tc0[i] vmin.s8 q8, q8, q14 // <= tc0[i] vand.s8 q8, q8, q10 EXTRACT_DELTA_INTO_TWO_PART q8, q9 vqadd.u8 q2, q2, q9 // clip_uint8( p0 + [+delta] ); p0' vqsub.u8 q2, q2, q8 // clip_uint8( p0 - [-delta] ); p0' vqsub.u8 q3, q3, q9 // clip_uint8( q0 - [+delta] ); q0' vqadd.u8 q3, q3, q8 // clip_uint8( q0 + [-delta] ); q0' sub r0, #2 add r2, r0, r1 lsl r1, #1 vmov q1, q6 vmov q4, q7 // q1,q2,q3,q4 vswp q2, q3 vswp d3, d6 vswp d5, d8 // d2~d5, d6~d7 STORE_LUMA_DATA_4 d2, d3, d4, d5, 0, 1 STORE_LUMA_DATA_4 d2, d3, d4, d5, 2, 3 STORE_LUMA_DATA_4 d2, d3, d4, d5, 4, 5 STORE_LUMA_DATA_4 d2, d3, d4, d5, 6, 7 STORE_LUMA_DATA_4 d6, d7, d8, d9, 0, 1 STORE_LUMA_DATA_4 d6, d7, d8, d9, 2, 3 STORE_LUMA_DATA_4 d6, d7, d8, d9, 4, 5 STORE_LUMA_DATA_4 d6, d7, d8, d9, 6, 7 //lt4_end: WELS_ASM_FUNC_END //uint8_t *pix, int32_t stride, int32_t alpha, int32_t beta WELS_ASM_FUNC_BEGIN DeblockLumaEq4H_neon vdup.u8 q5, r2 // alpha [0~255] vdup.u8 q4, r3 // beta [0~18] sub r3, r0, #4 // pix -= 4 LORD_LUMA_DATA_4 d16,d17,d18,d19,d24,d25,d26,d27,0 LORD_LUMA_DATA_4 d16,d17,d18,d19,d24,d25,d26,d27,1 LORD_LUMA_DATA_4 d16,d17,d18,d19,d24,d25,d26,d27,2 LORD_LUMA_DATA_4 d16,d17,d18,d19,d24,d25,d26,d27,3 LORD_LUMA_DATA_4 d16,d17,d18,d19,d24,d25,d26,d27,4 LORD_LUMA_DATA_4 d16,d17,d18,d19,d24,d25,d26,d27,5 LORD_LUMA_DATA_4 d16,d17,d18,d19,d24,d25,d26,d27,6 LORD_LUMA_DATA_4 d16,d17,d18,d19,d24,d25,d26,d27,7 LORD_LUMA_DATA_4 d20,d21,d22,d23,d28,d29,d30,d31,0 LORD_LUMA_DATA_4 d20,d21,d22,d23,d28,d29,d30,d31,1 LORD_LUMA_DATA_4 d20,d21,d22,d23,d28,d29,d30,d31,2 LORD_LUMA_DATA_4 d20,d21,d22,d23,d28,d29,d30,d31,3 LORD_LUMA_DATA_4 d20,d21,d22,d23,d28,d29,d30,d31,4 LORD_LUMA_DATA_4 d20,d21,d22,d23,d28,d29,d30,d31,5 LORD_LUMA_DATA_4 d20,d21,d22,d23,d28,d29,d30,d31,6 LORD_LUMA_DATA_4 d20,d21,d22,d23,d28,d29,d30,d31,7 vswp q9, q10 vswp d17,d18 vswp d21,d22 vswp q13,q14 vswp d25,d26 vswp d29,d30 sub r0, r0, r1 , lsl #4 // r0 -= 16*xstride // q8::p3 = pix[-4*xstride]; // q9::p2 = pix[-3*xstride]; // q10::p1 = pix[-2*xstride]; // q11::p0 = pix[-1*xstride]; // q12::q0 = pix[ 0*xstride]; // q13::q1 = pix[ 1*xstride]; // q14::q2 = pix[ 2*xstride]; // q15::q3 = pix[ 3*xstride]; // if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta ) MASK_MATRIX q10, q11, q12, q13, q5, q4, q6 // q6::mask matrix // JMP_IF_128BITS_IS_ZERO d12, d13, d0 // beq eq4_end // if(abs( p0 - q0 ) < ((alpha >> 2) + 2) ) mov r2, r2, lsr #2 add r2, r2, #2 vdup.u8 q5, r2 vabd.u8 q0, q11, q12 vclt.u8 q7, q0, q5 // q7::indicate // if( abs( p2 - p0 ) < beta ) vabd.u8 q1, q9, q11 vclt.u8 q1, q1, q4 vand.s8 q1, q1, q7 // q1::indicate [p0', p1', p2'] or [p0'] // if( abs( q2 - q0 ) < beta ) vabd.u8 q2, q14,q12 vclt.u8 q2, q2, q4 vand.s8 q2, q2, q7 // q2::indicate [q0', q1', q2'] or [q0'] vand.u8 q7, q7, q6 vmov q3, q1 // input: p3(output p1'), p2, p1, p0, q0, q1, select_matrix(output p0'), output p2'; // workin q4~q5; after filtered then p3/p2 useless! DIFF_LUMA_EQ4_P2P1P0 d16, d18, d20, d22, d24, d26, d2, d0 DIFF_LUMA_EQ4_P2P1P0 d17, d19, d21, d23, d25, d27, d3, d1 // q1(p0') q2(q0') only need ::if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta ) // q0(p2') q8(p1') q15(q1') q3(q2'); need more &&if(abs( p0 - q0 ) < ((alpha >> 2) + 2) )&&if( abs( p2 - p0 ) < beta ) vand.u8 q3, q7, q3 DIFF_LUMA_EQ4_MASK q0, q9, q3, q4 // p2' vmov q9, q4 // DIFF_LUMA_EQ4_MASK q8,q10, q3, q4 // p1' vbsl.u8 q3, q8, q10 DIFF_LUMA_EQ4_MASK q1,q11, q6, q8 // p0' vand.u8 q7, q7, q2 // input: q3(output q1'), q2, q1, q0, p0, p1, select_matrix(output q0'), output q2'; // workin q4~q5; after filtered then q3/q2 useless! DIFF_LUMA_EQ4_P2P1P0 d30, d28, d26, d24, d22, d20, d4, d0 DIFF_LUMA_EQ4_P2P1P0 d31, d29, d27, d25, d23, d21, d5, d1 // DIFF_LUMA_EQ4_MASK q2, q12, q6, q4 vbsl.u8 q6, q2, q12 DIFF_LUMA_EQ4_MASK q15, q13, q7, q4 // DIFF_LUMA_EQ4_MASK q0, q14, q7, q4 vbsl.u8 q7, q0, q14 // q9,q3,q8,q6,q4,q7 vmov q5, q6 vmov q2, q9 vmov q6, q4 vmov q4, q8 // q2,q3,q4,q5,q6,q7 vswp d8, d6 vswp d5, d7 vswp d5, d8 vswp d14, d12 vswp d11, d13 vswp d11, d14 sub r3, r0, #3 STORE_LUMA_DATA_3 d4,d5,d6,d10,d11,d12,0 STORE_LUMA_DATA_3 d4,d5,d6,d10,d11,d12,1 STORE_LUMA_DATA_3 d4,d5,d6,d10,d11,d12,2 STORE_LUMA_DATA_3 d4,d5,d6,d10,d11,d12,3 STORE_LUMA_DATA_3 d4,d5,d6,d10,d11,d12,4 STORE_LUMA_DATA_3 d4,d5,d6,d10,d11,d12,5 STORE_LUMA_DATA_3 d4,d5,d6,d10,d11,d12,6 STORE_LUMA_DATA_3 d4,d5,d6,d10,d11,d12,7 STORE_LUMA_DATA_3 d7,d8,d9,d13,d14,d15,0 STORE_LUMA_DATA_3 d7,d8,d9,d13,d14,d15,1 STORE_LUMA_DATA_3 d7,d8,d9,d13,d14,d15,2 STORE_LUMA_DATA_3 d7,d8,d9,d13,d14,d15,3 STORE_LUMA_DATA_3 d7,d8,d9,d13,d14,d15,4 STORE_LUMA_DATA_3 d7,d8,d9,d13,d14,d15,5 STORE_LUMA_DATA_3 d7,d8,d9,d13,d14,d15,6 STORE_LUMA_DATA_3 d7,d8,d9,d13,d14,d15,7 //eq4_end: WELS_ASM_FUNC_END //uint8_t *pix_cb, uint8_t *pix_cr, int32_t stride, int32_t alpha, int32_t beta, uint8_t *tc WELS_ASM_FUNC_BEGIN DeblockChromaLt4V_neon vdup.u8 q11, r3 // alpha [0~255] ldr r3, [sp, #0] sub r0, r0, r2 , lsl #1 // pix -= 2*src_stride sub r1, r1, r2, lsl #1 vdup.u8 q9, r3 // q9:: beta [0~18] ldr r3, [sp, #4] vld1.u8 {d0}, [r0], r2 // q0::p1 vld1.u8 {d1}, [r1], r2 vld1.u8 {d2}, [r0], r2 // q1::p0 vld1.u8 {d3}, [r1], r2 vld1.u8 {d4}, [r0], r2 // q2::q0 vld1.u8 {d5}, [r1], r2 vld1.u8 {d6}, [r0] // q3::q1 vld1.u8 {d7}, [r1] sub r0, r0, r2, lsl #1 // pix = [-1*src_stride] sub r1, r1, r2, lsl #1 // if( tc0[i] < 0 ) continue; else filter vld1.s8 {d15}, [r3] // load 4 tc0[i], each tc0[i] 2 bytes; d[x] Cb && d[x+1] Cr vmovl.u8 q6, d15 vshl.u64 d13,d12,#8 vorr d12,d13 vmov d13, d12 // q6::each 64 bits is 2x tc0[i] veor q7, q7 vsub.i8 q7,q7,q6 // q7::4x -tc0[i], min // if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta ) MASK_MATRIX q0, q1, q2, q3, q11, q9, q5 // q5::mask matrix // JMP_IF_128BITS_IS_ZERO d20, d21, d31 // beq lt4_end // input: p1, p0, q0, q1; output: _clip3(p0'); working q12,q13 DIFF_LUMA_LT4_P0_Q0 d0, d2, d4, d6, d8, q12, q13 DIFF_LUMA_LT4_P0_Q0 d1, d3, d5, d7, d9, q12, q13 //q4::delta vmax.s8 q4, q4, q7 // >= -tc0[i] vmin.s8 q4, q4, q6 // <= tc0[i] vand.s8 q4, q4, q5 vcge.s8 q6, q6, #0 // q6::tc0[i] >= 0 vand.s8 q4, q4, q6 EXTRACT_DELTA_INTO_TWO_PART q4, q5 vqadd.u8 q1, q1, q5 // clip_uint8( p0 + [+delta] ); p0' vqsub.u8 q1, q1, q4 // clip_uint8( p0 - [-delta] ); p0' vst1.u8 {d2}, [r0], r2 vst1.u8 {d3}, [r1], r2 vqsub.u8 q2, q2, q5 // clip_uint8( q0 - [+delta] ); q0' vqadd.u8 q2, q2, q4 // clip_uint8( q0 + [-delta] ); q0' vst1.u8 {d4}, [r0] vst1.u8 {d5}, [r1] //lt4_end: WELS_ASM_FUNC_END // uint8_t *pix_cb, uint8_t *pix_cr, int32_t stride, int32_t alpha, int32_t beta WELS_ASM_FUNC_BEGIN DeblockChromaEq4V_neon vdup.u8 q11, r3 // alpha [0~255] ldr r3, [sp, #0] sub r0, r0, r2 , lsl #1 // pix -= 2*src_stride sub r1, r1, r2, lsl #1 vdup.u8 q9, r3 // q9:: beta [0~18] vld1.u8 {d0}, [r0], r2 // q0::p1 vld1.u8 {d1}, [r1], r2 vld1.u8 {d2}, [r0], r2 // q1::p0 vld1.u8 {d3}, [r1], r2 vld1.u8 {d4}, [r0], r2 // q2::q0 vld1.u8 {d5}, [r1], r2 vld1.u8 {d6}, [r0] // q3::q1 vld1.u8 {d7}, [r1] sub r0, r0, r2, lsl #1 // pix = [-1*src_stride] sub r1, r1, r2, lsl #1 // if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta ) MASK_MATRIX q0, q1, q2, q3, q11, q9, q10 // q10::mask matrix, d20:Cb d21:Cr // JMP_IF_128BITS_IS_ZERO d20, d21, d31 // beq eq4_end vmov q11, q10 // ( (p1 << 1) + p0 + q1 + 2 ) >> 2 // ( (q1 << 1) + q0 + p1 + 2 ) >> 2 DIFF_CHROMA_EQ4_P0Q0 d0, d2, d4, d6, q4, q5, q6, d14, d0 // Cb::p0' q0' DIFF_CHROMA_EQ4_P0Q0 d1, d3, d5, d7, q12, q13, q14, d15, d1 // Cr::p0' q0' vbsl.u8 q10, q7, q1 // p0' vst1.u8 {d20}, [r0], r2 vst1.u8 {d21}, [r1], r2 vbsl.u8 q11, q0, q2 // q0' vst1.u8 {d22}, [r0] vst1.u8 {d23}, [r1] //eq4_end: WELS_ASM_FUNC_END //uint8_t *pix_cb, uint8_t *pix_cr, int32_t stride, int32_t alpha, int32_t beta, uint8_t *tc WELS_ASM_FUNC_BEGIN DeblockChromaLt4H_neon vdup.u8 q11, r3 // alpha [0~255] ldr r3, [sp, #0] sub r0, r0, #2 // pix [-2] vdup.u8 q9, r3 // q9:: beta [0~18] ldr r3, [sp, #4] sub r1, r1, #2 vld1.s8 {d15}, [r3] // load 4 tc0[i], each tc0[i] 2 bytes; d[x] Cb && d[x+1] Cr LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 0 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 1 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 2 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 3 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 4 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 5 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 6 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 7 // Cb:d0d1d2d3, Cr:d4d5d6d7 vswp q1, q2 vswp d1, d2 vswp d6, d5 // Cb:d0d2d4d6, Cr:d1d3d5d7 // if( tc0[i] < 0 ) continue; else filter vmovl.u8 q6, d15 vshl.u64 d13,d12,#8 vorr d12,d13 vmov d13, d12 // q6::each 64 bits is 2x tc0[i] veor q7, q7 vsub.i8 q7,q7,q6 // q7::4x -tc0[i], min // if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta ) MASK_MATRIX q0, q1, q2, q3, q11, q9, q5 // q5::mask matrix // JMP_IF_128BITS_IS_ZERO d20, d21, d31 // beq lt4_end // input: p1, p0, q0, q1; output: _clip3(p0'); working q12,q13 DIFF_LUMA_LT4_P0_Q0 d0, d2, d4, d6, d8, q12, q13 DIFF_LUMA_LT4_P0_Q0 d1, d3, d5, d7, d9, q12, q13 //q4::delta vmax.s8 q4, q4, q7 // >= -tc0[i] vmin.s8 q4, q4, q6 // <= tc0[i] vand.s8 q4, q4, q5 vcge.s8 q6, q6, #0 // q6::tc0[i] >= 0 vand.s8 q4, q4, q6 EXTRACT_DELTA_INTO_TWO_PART q4, q5 vqadd.u8 q1, q1, q5 // clip_uint8( p0 + [+delta] ); p0' vqsub.u8 q1, q1, q4 // clip_uint8( p0 - [-delta] ); p0' vqsub.u8 q2, q2, q5 // clip_uint8( q0 - [+delta] ); q0' vqadd.u8 q2, q2, q4 // clip_uint8( q0 + [-delta] ); q0' sub r0, r0, r2, lsl #3 // pix: 0th row [-2] sub r1, r1, r2, lsl #3 vswp d1, d2 vswp d6, d5 vswp q1, q2 // Cb:d0d1d2d3, Cr:d4d5d6d7 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 0 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 1 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 2 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 3 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 4 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 5 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 6 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 7 //lt4_end: WELS_ASM_FUNC_END // uint8_t *pix_cb, uint8_t *pix_cr, int32_t stride, int32_t alpha, int32_t beta WELS_ASM_FUNC_BEGIN DeblockChromaEq4H_neon vdup.u8 q11, r3 // alpha [0~255] ldr r3, [sp, #0] sub r0, r0, #2 // pix [-2] sub r1, r1, #2 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 0 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 1 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 2 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 3 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 4 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 5 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 6 LORD_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 7 // Cb:d0d1d2d3, Cr:d4d5d6d7 vswp q1, q2 vswp d1, d2 vswp d6, d5 // Cb:d0d2d4d6, Cr:d1d3d5d7 // if( abs( p0 - q0 ) < alpha && abs( p1 - p0 ) < beta && abs( q1 - q0 ) < beta ) vdup.u8 q9, r3 // q9:: beta [0~18] MASK_MATRIX q0, q1, q2, q3, q11, q9, q10 // q10::mask matrix, d20:Cb d21:Cr // JMP_IF_128BITS_IS_ZERO d20, d21, d31 // beq eq4_end vmov q11, q10 // ( (p1 << 1) + p0 + q1 + 2 ) >> 2 // ( (q1 << 1) + q0 + p1 + 2 ) >> 2 DIFF_CHROMA_EQ4_P0Q0 d0, d2, d4, d6, q8, q9, q12, d8, d10 // Cb::p0' q0' DIFF_CHROMA_EQ4_P0Q0 d1, d3, d5, d7, q13, q14, q15, d9, d11 // Cr::p0' q0' vbsl.u8 q10, q4, q1 // p0' vbsl.u8 q11, q5, q2 // q0' // q0 q10 q11 q3 sub r0, r0, r2, lsl #3 // pix: 0th row [-2] sub r1, r1, r2, lsl #3 vmov q1, q10 vmov q2, q11 vswp d1, d2 vswp d6, d5 vswp q1, q2 // Cb:d0d1d2d3, Cr:d4d5d6d7 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 0 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 1 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 2 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 3 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 4 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 5 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 6 STORE_CHROMA_DATA_4 d0, d1, d2, d3, d4, d5, d6, d7, 7 //eq4_end: WELS_ASM_FUNC_END // r0 int8_t* non_zero_count, WELS_ASM_FUNC_BEGIN enc_avc_non_zero_count_neon vld1.64 {d0-d2}, [r0] vceq.s8 q0, q0, #0 vceq.s8 d2, d2, #0 vmvn q0, q0 vmvn d2, d2 vabs.s8 q0, q0 vabs.s8 d2, d2 vst1.64 {d0-d2}, [r0] WELS_ASM_FUNC_END #endif