1342 lines
42 KiB
ArmAsm
Executable File
1342 lines
42 KiB
ArmAsm
Executable File
/*!
|
|
* \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
|
|
|
|
#ifdef APPLE_IOS
|
|
//in: $0(const) $1 $2; out:$3 $4
|
|
//used register: r6, r7, q0, q1
|
|
.macro BS_NZC_CHECK
|
|
//vld1.8 {d0,d1}, [$0]
|
|
vld1.8 {d0,d1}, [$0, :64]
|
|
/* Arrenge the input data --- TOP */
|
|
ands r6, $1, #2
|
|
beq bs_nzc_check_jump0
|
|
|
|
sub r6, $0, $2, lsl #4
|
|
sub r6, $2, lsl #3
|
|
add r6, #12
|
|
vld1.32 d3[1], [r6]
|
|
|
|
bs_nzc_check_jump0:
|
|
vext.8 q1, q1, q0, #12
|
|
vadd.u8 $3, q0, q1
|
|
|
|
|
|
/* Arrenge the input data --- LEFT */
|
|
ands r6, $1, #1
|
|
beq bs_nzc_check_jump1
|
|
|
|
sub r6, $0, #21
|
|
add r7, r6, #4
|
|
vld1.8 d3[4], [r6]
|
|
add r6, r7, #4
|
|
vld1.8 d3[5], [r7]
|
|
add r7, r6, #4
|
|
vld1.8 d3[6], [r6]
|
|
vld1.8 d3[7], [r7]
|
|
|
|
bs_nzc_check_jump1:
|
|
vzip.8 d0, d1
|
|
vzip.8 d0, d1
|
|
vext.8 q1, q1, q0, #12
|
|
vadd.u8 $4, q0, q1
|
|
|
|
.endm
|
|
|
|
|
|
//in: $0(const) $1 $2; out:$3 $4
|
|
//used register: r6, r7, q0, q1
|
|
.macro BS_REF_INDEX_CHECK
|
|
//vld1.8 {d0,d1}, [$0]
|
|
vld1.8 {d0,d1}, [$0, :128]
|
|
/* Arrenge the input data --- TOP */
|
|
ands r6, $1, #2
|
|
beq bs_ref_index_check_jump0
|
|
|
|
sub r6, $0, $2, lsl #4
|
|
add r6, #12
|
|
vld1.32 d3[1], [r6]
|
|
|
|
bs_ref_index_check_jump0:
|
|
vext.8 q1, q1, q0, #12
|
|
vabd.u8 $3, q0, q1
|
|
|
|
|
|
/* Arrenge the input data --- LEFT */
|
|
ands r6, $1, #1
|
|
beq bs_ref_index_check_jump1
|
|
|
|
sub r6, $0, #13
|
|
add r7, r6, #4
|
|
vld1.8 d3[4], [r6]
|
|
add r6, r7, #4
|
|
vld1.8 d3[5], [r7]
|
|
add r7, r6, #4
|
|
vld1.8 d3[6], [r6]
|
|
vld1.8 d3[7], [r7]
|
|
|
|
bs_ref_index_check_jump1:
|
|
vzip.8 d0, d1
|
|
vzip.8 d0, d1
|
|
vext.8 q1, q1, q0, #12
|
|
vabd.u8 $4, q0, q1
|
|
.endmacro
|
|
|
|
.macro BS_COMPARE_MV //in: $0,$1(const),$2(const),$3(const),$4(const); out:$5, $6
|
|
mov r6, #4
|
|
vabd.s16 q5, $0, $1
|
|
vabd.s16 q6, $1, $2
|
|
vdup.s16 $0, r6
|
|
vabd.s16 q7, $2, $3
|
|
vabd.s16 q8, $3, $4
|
|
|
|
vcge.s16 q5, $0
|
|
vcge.s16 q6, $0
|
|
vcge.s16 q7, $0
|
|
vcge.s16 q8, $0
|
|
|
|
vpadd.i16 d10, d10, d11
|
|
vpadd.i16 d11, d12, d13
|
|
vpadd.i16 d12, d14, d15
|
|
vpadd.i16 d13, d16, d17
|
|
|
|
vaddhn.i16 $5, q5, q5
|
|
vaddhn.i16 $6, q6, q6
|
|
.endmacro
|
|
|
|
//in: $0(const) $1 $2; out:$3 $4 $5 $6
|
|
//used register: r6, r7, q0, q1, q2, q3, q4
|
|
.macro BS_MV_CHECK
|
|
//vldm $0, {q0,q1,q2,q3}
|
|
vld1.32 {q0,q1}, [$0, :128]
|
|
add r6, $0, #32
|
|
vld1.32 {q2,q3}, [r6, :128]
|
|
|
|
/* Arrenge the input data --- TOP */
|
|
ands r6, $1, #2
|
|
beq bs_mv_check_jump0
|
|
|
|
sub r6, $0, $2, lsl #6
|
|
add r6, #48
|
|
vld1.8 {d8, d9}, [r6]
|
|
|
|
bs_mv_check_jump0:
|
|
BS_COMPARE_MV q4, q0, q1, q2, q3, $3, $4
|
|
|
|
/* Arrenge the input data --- LEFT */
|
|
ands r6, $1, #1
|
|
beq bs_mv_check_jump1
|
|
|
|
sub r6, $0, #52
|
|
//mov r7, #16
|
|
add r7, r6, #16
|
|
vld1.32 d8[0], [r6]
|
|
add r6, r7, #16
|
|
vld1.32 d8[1], [r7]
|
|
add r7, r6, #16
|
|
vld1.32 d9[0], [r6]
|
|
vld1.32 d9[1], [r7]
|
|
|
|
bs_mv_check_jump1:
|
|
vzip.32 q0, q2
|
|
vzip.32 q1, q3
|
|
vzip.32 q0, q1
|
|
vzip.32 q2, q3
|
|
BS_COMPARE_MV q4, q0, q1, q2, q3, $5, $6
|
|
.endmacro
|
|
#else
|
|
//in: $0(const) $1 $2; out:$3 $4
|
|
//used register: r6, r7, q0, q1
|
|
.macro BS_NZC_CHECK arg0, arg1, arg2, arg3, arg4
|
|
//vld1.8 {d0,d1}, [\arg0]
|
|
vld1.8 {d0,d1}, [\arg0, :64]
|
|
/* Arrenge the input data --- TOP */
|
|
ands r6, \arg1, #2
|
|
beq bs_nzc_check_jump0
|
|
|
|
sub r6, \arg0, \arg2, lsl #4
|
|
sub r6, \arg2, lsl #3
|
|
add r6, #12
|
|
vld1.32 d3[1], [r6]
|
|
|
|
bs_nzc_check_jump0:
|
|
vext.8 q1, q1, q0, #12
|
|
vadd.u8 \arg3, q0, q1
|
|
|
|
|
|
/* Arrenge the input data --- LEFT */
|
|
ands r6, \arg1, #1
|
|
beq bs_nzc_check_jump1
|
|
|
|
sub r6, \arg0, #21
|
|
add r7, r6, #4
|
|
vld1.8 d3[4], [r6]
|
|
add r6, r7, #4
|
|
vld1.8 d3[5], [r7]
|
|
add r7, r6, #4
|
|
vld1.8 d3[6], [r6]
|
|
vld1.8 d3[7], [r7]
|
|
|
|
bs_nzc_check_jump1:
|
|
vzip.8 d0, d1
|
|
vzip.8 d0, d1
|
|
vext.8 q1, q1, q0, #12
|
|
vadd.u8 \arg4, q0, q1
|
|
|
|
.endm
|
|
|
|
|
|
//in: \arg0(const) \arg1 \arg2; out:\arg3 \arg4
|
|
//used register: r6, r7, q0, q1
|
|
.macro BS_REF_INDEX_CHECK arg0, arg1, arg2, arg3, arg4
|
|
//vld1.8 {d0,d1}, [\arg0]
|
|
vld1.8 {d0,d1}, [\arg0, :128]
|
|
/* Arrenge the input data --- TOP */
|
|
ands r6, \arg1, #2
|
|
beq bs_ref_index_check_jump0
|
|
|
|
sub r6, \arg0, \arg2, lsl #4
|
|
add r6, #12
|
|
vld1.32 d3[1], [r6]
|
|
|
|
bs_ref_index_check_jump0:
|
|
vext.8 q1, q1, q0, #12
|
|
vabd.u8 \arg3, q0, q1
|
|
|
|
|
|
/* Arrenge the input data --- LEFT */
|
|
ands r6, \arg1, #1
|
|
beq bs_ref_index_check_jump1
|
|
|
|
sub r6, \arg0, #13
|
|
add r7, r6, #4
|
|
vld1.8 d3[4], [r6]
|
|
add r6, r7, #4
|
|
vld1.8 d3[5], [r7]
|
|
add r7, r6, #4
|
|
vld1.8 d3[6], [r6]
|
|
vld1.8 d3[7], [r7]
|
|
|
|
bs_ref_index_check_jump1:
|
|
vzip.8 d0, d1
|
|
vzip.8 d0, d1
|
|
vext.8 q1, q1, q0, #12
|
|
vabd.u8 \arg4, q0, q1
|
|
.endm
|
|
|
|
//in: \arg0,\arg1(const),\arg2(const),\arg3(const),\arg4(const); out:\arg5, \arg6
|
|
.macro BS_COMPARE_MV arg0, arg1, arg2, arg3, arg4, arg5, arg6
|
|
|
|
mov r6, #4
|
|
vabd.s16 q5, \arg0, \arg1
|
|
vabd.s16 q6, \arg1, \arg2
|
|
vdup.s16 \arg0, r6
|
|
vabd.s16 q7, \arg2, \arg3
|
|
vabd.s16 q8, \arg3, \arg4
|
|
|
|
vcge.s16 q5, \arg0
|
|
vcge.s16 q6, \arg0
|
|
vcge.s16 q7, \arg0
|
|
vcge.s16 q8, \arg0
|
|
|
|
vpadd.i16 d10, d10, d11
|
|
vpadd.i16 d11, d12, d13
|
|
vpadd.i16 d12, d14, d15
|
|
vpadd.i16 d13, d16, d17
|
|
|
|
vaddhn.i16 \arg5, q5, q5
|
|
vaddhn.i16 \arg6, q6, q6
|
|
.endm
|
|
|
|
//in: \arg0(const) \arg1 \arg2; out:\arg3 \arg4 \arg5 \arg6
|
|
//used register: r6, r7, q0, q1, q2, q3, q4
|
|
.macro BS_MV_CHECK arg0, arg1, arg2, arg3, arg4, arg5, arg6
|
|
//vldm \arg0, {q0,q1,q2,q3}
|
|
vld1.32 {q0,q1}, [\arg0, :128]
|
|
add r6, \arg0, #32
|
|
vld1.32 {q2,q3}, [r6, :128]
|
|
|
|
/* Arrenge the input data --- TOP */
|
|
ands r6, \arg1, #2
|
|
beq bs_mv_check_jump0
|
|
|
|
sub r6, \arg0, \arg2, lsl #6
|
|
add r6, #48
|
|
vld1.8 {d8, d9}, [r6]
|
|
|
|
bs_mv_check_jump0:
|
|
BS_COMPARE_MV q4, q0, q1, q2, q3, \arg3, \arg4
|
|
|
|
/* Arrenge the input data --- LEFT */
|
|
ands r6, \arg1, #1
|
|
beq bs_mv_check_jump1
|
|
|
|
sub r6, \arg0, #52
|
|
//mov r7, #16
|
|
add r7, r6, #16
|
|
vld1.32 d8[0], [r6]
|
|
add r6, r7, #16
|
|
vld1.32 d8[1], [r7]
|
|
add r7, r6, #16
|
|
vld1.32 d9[0], [r6]
|
|
vld1.32 d9[1], [r7]
|
|
|
|
bs_mv_check_jump1:
|
|
vzip.32 q0, q2
|
|
vzip.32 q1, q3
|
|
vzip.32 q0, q1
|
|
vzip.32 q2, q3
|
|
BS_COMPARE_MV q4, q0, q1, q2, q3, \arg5, \arg6
|
|
.endm
|
|
#endif
|
|
/*
|
|
* void deblocking_BS_calc_neon(int8_t *pNzc,
|
|
* int8_t *pRef_index,
|
|
* int16_t *pMv[],
|
|
* int32_t boundry_flag,
|
|
* int32_t mb_width,
|
|
* uint8_t *bS);
|
|
*
|
|
* r0 = cur_layer->nzc[cur_mb_xy]
|
|
* r1 = cur_layer->ref_index[0][cur_mb_xy]
|
|
* r2 = cur_layer->mv[0][cur_mb_xy]
|
|
* r3 = boundry_flag (LEFT_FLAG/TOP_FLAG)
|
|
* r4 = cur_layer->mb_width
|
|
* r5 = BS[8][4] save all of the BS value for whole MB(16*16)
|
|
*/
|
|
|
|
WELS_ASM_FUNC_BEGIN deblocking_BS_calc_neon
|
|
|
|
stmdb sp!, {r4-r7}
|
|
|
|
ldr r4, [sp, #16] //Save mb_width to r4
|
|
ldr r5, [sp, #20] //Save BS to r5
|
|
|
|
/* Checking the nzc status */
|
|
BS_NZC_CHECK r0, r3, r4, q14, q15 //q14,q15 save the nzc status
|
|
|
|
/* Checking the nzc_rs status */
|
|
//BS_NZC_CHECK r1, r4, q12, q13 //q12,q13 save the mzc_rs status
|
|
|
|
/* For checking bS[I] = 2 */
|
|
mov r6, #2
|
|
//vqadd.u8 q14, q12
|
|
//vqadd.u8 q15, q13
|
|
vcgt.s8 q14, q14, #0
|
|
vdup.u8 q0, r6
|
|
vcgt.s8 q15, q15, #0
|
|
|
|
vand.u8 q14, q14, q0 //q14 save the nzc check result all the time --- for dir is top
|
|
vand.u8 q15, q15, q0 //q15 save the nzc check result all the time --- for dir is left
|
|
|
|
|
|
/* Checking the ref_index status*/
|
|
BS_REF_INDEX_CHECK r1, r3, r4, q12, q13 //q12,q13 save the ref_index status
|
|
|
|
vcgt.s8 q12, q12, #0
|
|
vcgt.s8 q13, q13, #0
|
|
|
|
/* Checking the mv status*/
|
|
BS_MV_CHECK r2, r3, r4, d20, d21, d22, d23//q10, q11 save the mv status
|
|
|
|
/* For checking bS[I] = 1 */
|
|
mov r6, #1
|
|
vqadd.u8 q12, q10
|
|
vdup.u8 q0, r6
|
|
vqadd.u8 q13, q11
|
|
|
|
vand.u8 q12, q12, q0 //q12 save the nzc check result all the time --- for dir is top
|
|
vand.u8 q13, q13, q0 //q13 save the nzc check result all the time --- for dir is left
|
|
|
|
|
|
/* Check bS[I] is '1' or '2' */
|
|
vmax.u8 q1, q12, q14
|
|
vmax.u8 q0, q13, q15
|
|
|
|
//vstm r5, {q0, q1}
|
|
vst1.32 {q0, q1}, [r5]
|
|
ldmia sp!, {r4-r7}
|
|
WELS_ASM_FUNC_END
|
|
/*====== deblocking_BS_calc_neon End ======*/
|
|
#endif
|