/***************************************************************************** * Copyright (C) 2013-2020 MulticoreWare, Inc * * Authors: Dnyaneshwar G * Radhakrishnan VR * Min Chen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. * * This program is also available under a commercial proprietary license. * For more information, contact us at license @ x265.com. *****************************************************************************/ #include "asm.S" .section .rodata .align 4 .text .macro VAR_SQR_SUM qsqr_sum, qsqr_last, qsqr_temp, dsrc, num=0, vpadal=vpadal.u16 vmull.u8 \qsqr_temp, \dsrc, \dsrc vaddw.u8 q\num, q\num, \dsrc \vpadal \qsqr_sum, \qsqr_last .endm function x265_pixel_var_8x8_neon vld1.u8 {d16}, [r0], r1 vmull.u8 q1, d16, d16 vmovl.u8 q0, d16 vld1.u8 {d18}, [r0], r1 vmull.u8 q2, d18, d18 vaddw.u8 q0, q0, d18 vld1.u8 {d20}, [r0], r1 VAR_SQR_SUM q1, q1, q3, d20, 0, vpaddl.u16 vld1.u8 {d22}, [r0], r1 VAR_SQR_SUM q2, q2, q8, d22, 0, vpaddl.u16 vld1.u8 {d24}, [r0], r1 VAR_SQR_SUM q1, q3, q9, d24 vld1.u8 {d26}, [r0], r1 VAR_SQR_SUM q2, q8, q10, d26 vld1.u8 {d24}, [r0], r1 VAR_SQR_SUM q1, q9, q14, d24 vld1.u8 {d26}, [r0], r1 VAR_SQR_SUM q2, q10, q15, d26 vpaddl.u16 q8, q14 vpaddl.u16 q9, q15 vadd.u32 q1, q1, q8 vadd.u16 d0, d0, d1 vadd.u32 q1, q1, q9 vadd.u32 q1, q1, q2 vpaddl.u16 d0, d0 vadd.u32 d2, d2, d3 vpadd.u32 d0, d0, d2 vmov r0, r1, d0 bx lr endfunc function x265_pixel_var_16x16_neon veor.u8 q0, q0 veor.u8 q1, q1 veor.u8 q2, q2 veor.u8 q14, q14 veor.u8 q15, q15 mov ip, #4 .var16_loop: subs ip, ip, #1 vld1.u8 {q8}, [r0], r1 VAR_SQR_SUM q1, q14, q12, d16 VAR_SQR_SUM q2, q15, q13, d17 vld1.u8 {q9}, [r0], r1 VAR_SQR_SUM q1, q12, q14, d18 VAR_SQR_SUM q2, q13, q15, d19 vld1.u8 {q8}, [r0], r1 VAR_SQR_SUM q1, q14, q12, d16 VAR_SQR_SUM q2, q15, q13, d17 vld1.u8 {q9}, [r0], r1 VAR_SQR_SUM q1, q12, q14, d18 VAR_SQR_SUM q2, q13, q15, d19 bgt .var16_loop vpaddl.u16 q8, q14 vpaddl.u16 q9, q15 vadd.u32 q1, q1, q8 vadd.u16 d0, d0, d1 vadd.u32 q1, q1, q9 vadd.u32 q1, q1, q2 vpaddl.u16 d0, d0 vadd.u32 d2, d2, d3 vpadd.u32 d0, d0, d2 vmov r0, r1, d0 bx lr endfunc function x265_pixel_var_32x32_neon veor.u8 q0, q0 veor.u8 q1, q1 veor.u8 q2, q2 veor.u8 q14, q14 veor.u8 q15, q15 mov ip, #8 .var32_loop: subs ip, ip, #1 vld1.u8 {q8-q9}, [r0], r1 VAR_SQR_SUM q1, q14, q12, d16 VAR_SQR_SUM q2, q15, q13, d17 VAR_SQR_SUM q1, q12, q14, d18 VAR_SQR_SUM q2, q13, q15, d19 vld1.u8 {q8-q9}, [r0], r1 VAR_SQR_SUM q1, q14, q12, d16 VAR_SQR_SUM q2, q15, q13, d17 VAR_SQR_SUM q1, q12, q14, d18 VAR_SQR_SUM q2, q13, q15, d19 vld1.u8 {q8-q9}, [r0], r1 VAR_SQR_SUM q1, q14, q12, d16 VAR_SQR_SUM q2, q15, q13, d17 VAR_SQR_SUM q1, q12, q14, d18 VAR_SQR_SUM q2, q13, q15, d19 vld1.u8 {q8-q9}, [r0], r1 VAR_SQR_SUM q1, q14, q12, d16 VAR_SQR_SUM q2, q15, q13, d17 VAR_SQR_SUM q1, q12, q14, d18 VAR_SQR_SUM q2, q13, q15, d19 bgt .var32_loop vpaddl.u16 q8, q14 vpaddl.u16 q9, q15 vadd.u32 q1, q1, q8 vadd.u16 d0, d0, d1 vadd.u32 q1, q1, q9 vadd.u32 q1, q1, q2 vpaddl.u16 d0, d0 vadd.u32 d2, d2, d3 vpadd.u32 d0, d0, d2 vmov r0, r1, d0 bx lr endfunc function x265_pixel_var_64x64_neon sub r1, #32 veor.u8 q0, q0 veor.u8 q1, q1 veor.u8 q2, q2 veor.u8 q3, q3 veor.u8 q14, q14 veor.u8 q15, q15 mov ip, #16 .var64_loop: subs ip, ip, #1 vld1.u8 {q8-q9}, [r0]! VAR_SQR_SUM q1, q14, q12, d16 VAR_SQR_SUM q2, q15, q13, d17 VAR_SQR_SUM q1, q12, q14, d18 VAR_SQR_SUM q2, q13, q15, d19 vld1.u8 {q8-q9}, [r0], r1 VAR_SQR_SUM q1, q14, q12, d16, 3 VAR_SQR_SUM q2, q15, q13, d17, 3 VAR_SQR_SUM q1, q12, q14, d18, 3 VAR_SQR_SUM q2, q13, q15, d19, 3 vld1.u8 {q8-q9}, [r0]! VAR_SQR_SUM q1, q14, q12, d16 VAR_SQR_SUM q2, q15, q13, d17 VAR_SQR_SUM q1, q12, q14, d18 VAR_SQR_SUM q2, q13, q15, d19 vld1.u8 {q8-q9}, [r0], r1 VAR_SQR_SUM q1, q14, q12, d16, 3 VAR_SQR_SUM q2, q15, q13, d17, 3 VAR_SQR_SUM q1, q12, q14, d18, 3 VAR_SQR_SUM q2, q13, q15, d19, 3 vld1.u8 {q8-q9}, [r0]! VAR_SQR_SUM q1, q14, q12, d16 VAR_SQR_SUM q2, q15, q13, d17 VAR_SQR_SUM q1, q12, q14, d18 VAR_SQR_SUM q2, q13, q15, d19 vld1.u8 {q8-q9}, [r0], r1 VAR_SQR_SUM q1, q14, q12, d16, 3 VAR_SQR_SUM q2, q15, q13, d17, 3 VAR_SQR_SUM q1, q12, q14, d18, 3 VAR_SQR_SUM q2, q13, q15, d19, 3 vld1.u8 {q8-q9}, [r0]! VAR_SQR_SUM q1, q14, q12, d16 VAR_SQR_SUM q2, q15, q13, d17 VAR_SQR_SUM q1, q12, q14, d18 VAR_SQR_SUM q2, q13, q15, d19 vld1.u8 {q8-q9}, [r0], r1 VAR_SQR_SUM q1, q14, q12, d16, 3 VAR_SQR_SUM q2, q15, q13, d17, 3 VAR_SQR_SUM q1, q12, q14, d18, 3 VAR_SQR_SUM q2, q13, q15, d19, 3 bgt .var64_loop vpaddl.u16 q8, q14 vpaddl.u16 q9, q15 vadd.u32 q1, q1, q8 vadd.u32 q1, q1, q9 vadd.u32 q1, q1, q2 vpaddl.u16 d0, d0 vpaddl.u16 d1, d1 vpaddl.u16 d6, d6 vpaddl.u16 d7, d7 vadd.u32 d0, d1 vadd.u32 d6, d7 vadd.u32 d0, d6 vadd.u32 d2, d2, d3 vpadd.u32 d0, d0, d2 vmov r0, r1, d0 bx lr endfunc /* void getResidual4_neon(const pixel* fenc, const pixel* pred, int16_t* residual, intptr_t stride); * r0 - fenc * r1 - pred * r2 - residual * r3 - Stride */ function x265_getResidual4_neon lsl r12, r3, #1 .rept 2 vld1.u8 {d0}, [r0], r3 vld1.u8 {d1}, [r1], r3 vld1.u8 {d2}, [r0], r3 vld1.u8 {d3}, [r1], r3 vsubl.u8 q2, d0, d1 vsubl.u8 q3, d2, d3 vst1.s16 {d4}, [r2], r12 vst1.s16 {d6}, [r2], r12 .endr bx lr endfunc function x265_getResidual8_neon lsl r12, r3, #1 .rept 4 vld1.u8 {d0}, [r0], r3 vld1.u8 {d1}, [r1], r3 vld1.u8 {d2}, [r0], r3 vld1.u8 {d3}, [r1], r3 vsubl.u8 q2, d0, d1 vsubl.u8 q3, d2, d3 vst1.s16 {q2}, [r2], r12 vst1.s16 {q3}, [r2], r12 .endr bx lr endfunc function x265_getResidual16_neon lsl r12, r3, #1 .rept 8 vld1.u8 {d0, d1}, [r0], r3 vld1.u8 {d2, d3}, [r1], r3 vld1.u8 {d4, d5}, [r0], r3 vld1.u8 {d6, d7}, [r1], r3 vsubl.u8 q8, d0, d2 vsubl.u8 q9, d1, d3 vsubl.u8 q10, d4, d6 vsubl.u8 q11, d5, d7 vst1.s16 {q8, q9}, [r2], r12 vst1.s16 {q10, q11}, [r2], r12 .endr bx lr endfunc function x265_getResidual32_neon push {r4} lsl r12, r3, #1 sub r12, #32 mov r4, #4 loop_res32: subs r4, r4, #1 .rept 8 vld1.u8 {q0, q1}, [r0], r3 vld1.u8 {q2, q3}, [r1], r3 vsubl.u8 q8, d0, d4 vsubl.u8 q9, d1, d5 vsubl.u8 q10, d2, d6 vsubl.u8 q11, d3, d7 vst1.s16 {q8, q9}, [r2]! vst1.s16 {q10, q11}, [r2], r12 .endr bne loop_res32 pop {r4} bx lr endfunc // void pixel_sub_ps_neon(int16_t* a, intptr_t dstride, const pixel* b0, const pixel* b1, intptr_t sstride0, intptr_t sstride1) function x265_pixel_sub_ps_4x4_neon push {r4} lsl r1, r1, #1 ldr r4, [sp, #4] ldr r12, [sp, #8] .rept 2 vld1.u8 {d0}, [r2], r4 vld1.u8 {d1}, [r3], r12 vld1.u8 {d2}, [r2], r4 vld1.u8 {d3}, [r3], r12 vsubl.u8 q2, d0, d1 vsubl.u8 q3, d2, d3 vst1.s16 {d4}, [r0], r1 vst1.s16 {d6}, [r0], r1 .endr pop {r4} bx lr endfunc function x265_pixel_sub_ps_8x8_neon push {r4} lsl r1, r1, #1 ldr r4, [sp, #4] ldr r12, [sp, #8] .rept 4 vld1.u8 {d0}, [r2], r4 vld1.u8 {d1}, [r3], r12 vld1.u8 {d2}, [r2], r4 vld1.u8 {d3}, [r3], r12 vsubl.u8 q2, d0, d1 vsubl.u8 q3, d2, d3 vst1.s16 {q2}, [r0], r1 vst1.s16 {q3}, [r0], r1 .endr pop {r4} bx lr endfunc function x265_pixel_sub_ps_16x16_neon push {r4, r5} lsl r1, r1, #1 ldr r4, [sp, #8] ldr r12, [sp, #12] mov r5, #2 loop_sub16: subs r5, r5, #1 .rept 4 vld1.u8 {q0}, [r2], r4 vld1.u8 {q1}, [r3], r12 vld1.u8 {q2}, [r2], r4 vld1.u8 {q3}, [r3], r12 vsubl.u8 q8, d0, d2 vsubl.u8 q9, d1, d3 vsubl.u8 q10, d4, d6 vsubl.u8 q11, d5, d7 vst1.s16 {q8, q9}, [r0], r1 vst1.s16 {q10, q11}, [r0], r1 .endr bne loop_sub16 pop {r4, r5} bx lr endfunc function x265_pixel_sub_ps_32x32_neon push {r4, r5} lsl r1, r1, #1 ldr r4, [sp, #8] ldr r12, [sp, #12] sub r1, #32 mov r5, #8 loop_sub32: subs r5, r5, #1 .rept 4 vld1.u8 {q0, q1}, [r2], r4 vld1.u8 {q2, q3}, [r3], r12 vsubl.u8 q8, d0, d4 vsubl.u8 q9, d1, d5 vsubl.u8 q10, d2, d6 vsubl.u8 q11, d3, d7 vst1.s16 {q8, q9}, [r0]! vst1.s16 {q10, q11}, [r0], r1 .endr bne loop_sub32 pop {r4, r5} bx lr endfunc function x265_pixel_sub_ps_64x64_neon push {r4, r5} lsl r1, r1, #1 ldr r4, [sp, #8] ldr r12, [sp, #12] sub r1, #96 sub r4, #32 sub r12, #32 mov r5, #32 loop_sub64: subs r5, r5, #1 .rept 2 vld1.u8 {q0, q1}, [r2]! vld1.u8 {q2, q3}, [r2], r4 vld1.u8 {q8, q9}, [r3]! vld1.u8 {q10, q11}, [r3], r12 vsubl.u8 q12, d0, d16 vsubl.u8 q13, d1, d17 vsubl.u8 q14, d2, d18 vsubl.u8 q15, d3, d19 vsubl.u8 q0, d4, d20 vsubl.u8 q1, d5, d21 vsubl.u8 q2, d6, d22 vsubl.u8 q3, d7, d23 vst1.s16 {q12, q13}, [r0]! vst1.s16 {q14, q15}, [r0]! vst1.s16 {q0, q1}, [r0]! vst1.s16 {q2, q3}, [r0], r1 .endr bne loop_sub64 pop {r4, r5} bx lr endfunc // chroma sub_ps function x265_pixel_sub_ps_4x8_neon push {r4} lsl r1, r1, #1 ldr r4, [sp, #4] ldr r12, [sp, #8] .rept 4 vld1.u8 {d0}, [r2], r4 vld1.u8 {d1}, [r3], r12 vld1.u8 {d2}, [r2], r4 vld1.u8 {d3}, [r3], r12 vsubl.u8 q2, d0, d1 vsubl.u8 q3, d2, d3 vst1.s16 {d4}, [r0], r1 vst1.s16 {d6}, [r0], r1 .endr pop {r4} bx lr endfunc function x265_pixel_sub_ps_8x16_neon push {r4} lsl r1, r1, #1 ldr r4, [sp, #4] ldr r12, [sp, #8] .rept 8 vld1.u8 {d0}, [r2], r4 vld1.u8 {d1}, [r3], r12 vld1.u8 {d2}, [r2], r4 vld1.u8 {d3}, [r3], r12 vsubl.u8 q2, d0, d1 vsubl.u8 q3, d2, d3 vst1.s16 {q2}, [r0], r1 vst1.s16 {q3}, [r0], r1 .endr pop {r4} bx lr endfunc function x265_pixel_sub_ps_16x32_neon push {r4, r5} lsl r1, r1, #1 ldr r4, [sp, #8] ldr r12, [sp, #12] mov r5, #4 loop_sub_16x32: subs r5, r5, #1 .rept 4 vld1.u8 {q0}, [r2], r4 vld1.u8 {q1}, [r3], r12 vld1.u8 {q2}, [r2], r4 vld1.u8 {q3}, [r3], r12 vsubl.u8 q8, d0, d2 vsubl.u8 q9, d1, d3 vsubl.u8 q10, d4, d6 vsubl.u8 q11, d5, d7 vst1.s16 {q8, q9}, [r0], r1 vst1.s16 {q10, q11}, [r0], r1 .endr bne loop_sub_16x32 pop {r4, r5} bx lr endfunc function x265_pixel_sub_ps_32x64_neon push {r4, r5} lsl r1, r1, #1 ldr r4, [sp, #8] ldr r12, [sp, #12] sub r1, #32 mov r5, #16 loop_sub_32x64: subs r5, r5, #1 .rept 4 vld1.u8 {q0, q1}, [r2], r4 vld1.u8 {q2, q3}, [r3], r12 vsubl.u8 q8, d0, d4 vsubl.u8 q9, d1, d5 vsubl.u8 q10, d2, d6 vsubl.u8 q11, d3, d7 vst1.s16 {q8, q9}, [r0]! vst1.s16 {q10, q11}, [r0], r1 .endr bne loop_sub_32x64 pop {r4, r5} bx lr endfunc // void x265_pixel_add_ps_neon(pixel* a, intptr_t dstride, const pixel* b0, const int16_t* b1, intptr_t sstride0, intptr_t sstride1); function x265_pixel_add_ps_4x4_neon push {r4} ldr r4, [sp, #4] ldr r12, [sp, #8] lsl r12, #1 vmov.u16 q10, #255 veor.u16 q11, q11 veor.u16 d3, d3 veor.u16 d5, d5 .rept 2 vld1.u8 {d0}, [r2], r4 vld1.u8 {d1}, [r2], r4 vld1.s16 {d2}, [r3], r12 vld1.s16 {d4}, [r3], r12 vmovl.u8 q8, d0 vmovl.u8 q9, d1 vadd.s16 q1, q1, q8 vadd.s16 q2, q2, q9 vqmovun.s16 d0, q1 vqmovun.s16 d1, q2 vst1.32 {d0[0]}, [r0], r1 vst1.32 {d1[0]}, [r0], r1 .endr pop {r4} bx lr endfunc function x265_pixel_add_ps_8x8_neon push {r4} ldr r4, [sp, #4] ldr r12, [sp, #8] lsl r12, #1 vmov.u16 q10, #255 veor.u16 q11, q11 .rept 4 vld1.u8 {d0}, [r2], r4 vld1.u8 {d1}, [r2], r4 vld1.s16 {q8}, [r3], r12 vld1.s16 {q9}, [r3], r12 vmovl.u8 q1, d0 vmovl.u8 q2, d1 vadd.s16 q1, q1, q8 vadd.s16 q2, q2, q9 vqmovun.s16 d0, q1 vqmovun.s16 d1, q2 vst1.8 {d0}, [r0], r1 vst1.8 {d1}, [r0], r1 .endr pop {r4} bx lr endfunc .macro pixel_add_ps_16xN_neon h i function x265_pixel_add_ps_16x\h\()_neon push {r4, r5} ldr r4, [sp, #8] ldr r12, [sp, #12] lsl r12, #1 vmov.u16 q10, #255 veor.u16 q11, q11 mov r5, #\i loop_addps_16x\h\(): subs r5, #1 .rept 4 vld1.u8 {q0}, [r2], r4 vld1.u8 {q1}, [r2], r4 vld1.s16 {q8, q9}, [r3], r12 vld1.s16 {q12, q13}, [r3], r12 vmovl.u8 q2, d0 vmovl.u8 q3, d1 vmovl.u8 q0, d2 vmovl.u8 q1, d3 vadd.s16 q2, q2, q8 vadd.s16 q3, q3, q9 vadd.s16 q0, q0, q12 vadd.s16 q1, q1, q13 vqmovun.s16 d4, q2 vqmovun.s16 d5, q3 vqmovun.s16 d0, q0 vqmovun.s16 d1, q1 vst1.8 {d4, d5}, [r0], r1 vst1.8 {d0, d1}, [r0], r1 .endr bne loop_addps_16x\h pop {r4, r5} bx lr endfunc .endm pixel_add_ps_16xN_neon 16 2 pixel_add_ps_16xN_neon 32 4 .macro pixel_add_ps_32xN_neon h i function x265_pixel_add_ps_32x\h\()_neon push {r4, r5} ldr r4, [sp, #8] ldr r12, [sp, #12] lsl r12, #1 vmov.u16 q10, #255 veor.u16 q11, q11 mov r5, #\i sub r12, #32 loop_addps_32x\h\(): subs r5, #1 .rept 4 vld1.u8 {q0, q1}, [r2], r4 vld1.s16 {q8, q9}, [r3]! vld1.s16 {q12, q13}, [r3], r12 vmovl.u8 q2, d0 vmovl.u8 q3, d1 vmovl.u8 q14, d2 vmovl.u8 q15, d3 vadd.s16 q2, q2, q8 vadd.s16 q3, q3, q9 vadd.s16 q14, q14, q12 vadd.s16 q15, q15, q13 vqmovun.s16 d0, q2 vqmovun.s16 d1, q3 vqmovun.s16 d2, q14 vqmovun.s16 d3, q15 vst1.8 {q0, q1}, [r0], r1 .endr bne loop_addps_32x\h pop {r4, r5} bx lr endfunc .endm pixel_add_ps_32xN_neon 32 8 pixel_add_ps_32xN_neon 64 16 function x265_pixel_add_ps_64x64_neon push {r4, r5} vpush {q4, q5, q6, q7} ldr r4, [sp, #72] ldr r12, [sp, #76] lsl r12, #1 vmov.u16 q2, #255 veor.u16 q3, q3 mov r5, #32 sub r1, #32 sub r4, #32 sub r12, #96 loop_addps64: subs r5, #1 .rept 2 vld1.u8 {q0, q1}, [r2]! vld1.s16 {q8, q9}, [r3]! vld1.s16 {q10, q11}, [r3]! vld1.s16 {q12, q13}, [r3]! vld1.s16 {q14, q15}, [r3], r12 vmovl.u8 q4, d0 vmovl.u8 q5, d1 vmovl.u8 q6, d2 vmovl.u8 q7, d3 vadd.s16 q4, q4, q8 vadd.s16 q5, q5, q9 vadd.s16 q6, q6, q10 vadd.s16 q7, q7, q11 vqmovun.s16 d0, q4 vqmovun.s16 d1, q5 vqmovun.s16 d2, q6 vqmovun.s16 d3, q7 vst1.u8 {q0, q1}, [r0]! vld1.u8 {q0, q1}, [r2], r4 vmovl.u8 q4, d0 vmovl.u8 q5, d1 vmovl.u8 q6, d2 vmovl.u8 q7, d3 vadd.s16 q4, q4, q12 vadd.s16 q5, q5, q13 vadd.s16 q6, q6, q14 vadd.s16 q7, q7, q15 vqmovun.s16 d0, q4 vqmovun.s16 d1, q5 vqmovun.s16 d2, q6 vqmovun.s16 d3, q7 vst1.u8 {q0, q1}, [r0], r1 .endr bne loop_addps64 vpop {q4, q5, q6, q7} pop {r4, r5} bx lr endfunc // Chroma add_ps function x265_pixel_add_ps_4x8_neon push {r4} ldr r4, [sp, #4] ldr r12, [sp, #8] lsl r12, #1 vmov.u16 q10, #255 veor.u16 q11, q11 veor.u16 d3, d3 veor.u16 d5, d5 .rept 4 vld1.u8 {d0}, [r2], r4 vld1.u8 {d1}, [r2], r4 vld1.s16 {d2}, [r3], r12 vld1.s16 {d4}, [r3], r12 vmovl.u8 q8, d0 vmovl.u8 q9, d1 vadd.s16 q1, q1, q8 vadd.s16 q2, q2, q9 vqmovun.s16 d0, q1 vqmovun.s16 d1, q2 vst1.32 {d0[0]}, [r0], r1 vst1.32 {d1[0]}, [r0], r1 .endr pop {r4} bx lr endfunc function x265_pixel_add_ps_8x16_neon push {r4, r5} ldr r4, [sp, #8] ldr r12, [sp, #12] lsl r12, #1 vmov.u16 q10, #255 veor.u16 q11, q11 mov r5, #2 loop_add_8x16: subs r5, #1 .rept 4 vld1.u8 {d0}, [r2], r4 vld1.u8 {d1}, [r2], r4 vld1.s16 {q8}, [r3], r12 vld1.s16 {q9}, [r3], r12 vmovl.u8 q1, d0 vmovl.u8 q2, d1 vadd.s16 q1, q1, q8 vadd.s16 q2, q2, q9 vqmovun.s16 d0, q1 vqmovun.s16 d1, q2 vst1.8 {d0}, [r0], r1 vst1.8 {d1}, [r0], r1 .endr bne loop_add_8x16 pop {r4, r5} bx lr endfunc // void scale1D_128to64(pixel *dst, const pixel *src) function x265_scale1D_128to64_neon mov r12, #32 .rept 2 vld2.u8 {q8, q9}, [r1]! vld2.u8 {q10, q11}, [r1]! vld2.u8 {q12, q13}, [r1]! vld2.u8 {q14, q15}, [r1], r12 vrhadd.u8 q0, q8, q9 vrhadd.u8 q1, q10, q11 vrhadd.u8 q2, q12, q13 vrhadd.u8 q3, q14, q15 vst1.u8 {q0, q1}, [r0]! vst1.u8 {q2, q3}, [r0], r12 .endr bx lr endfunc // void scale2D_64to32(pixel* dst, const pixel* src, intptr_t stride) function x265_scale2D_64to32_neon sub r2, #32 mov r3, #16 loop_scale2D: subs r3, #1 .rept 2 vld2.8 {q8, q9}, [r1]! vld2.8 {q10, q11}, [r1], r2 vld2.8 {q12, q13}, [r1]! vld2.8 {q14, q15}, [r1], r2 vaddl.u8 q0, d16, d18 vaddl.u8 q1, d17, d19 vaddl.u8 q2, d20, d22 vaddl.u8 q3, d21, d23 vaddl.u8 q8, d24, d26 vaddl.u8 q9, d25, d27 vaddl.u8 q10, d28, d30 vaddl.u8 q11, d29, d31 vadd.u16 q0, q8 vadd.u16 q1, q9 vadd.u16 q2, q10 vadd.u16 q3, q11 vrshrn.u16 d16, q0, #2 vrshrn.u16 d17, q1, #2 vrshrn.u16 d18, q2, #2 vrshrn.u16 d19, q3, #2 vst1.8 {q8, q9}, [r0]! .endr bne loop_scale2D bx lr endfunc function x265_pixel_planecopy_cp_neon push {r4, r5, r6, r7} ldr r4, [sp, #4 * 4] ldr r5, [sp, #4 * 4 + 4] ldr r12, [sp, #4 * 4 + 8] vdup.8 q2, r12 sub r5, #1 .Loop_h: mov r6, r0 mov r12, r2 eor r7, r7 .Loop_w: vld1.u8 {q0}, [r6]! vshl.u8 q0, q0, q2 vst1.u8 {q0}, [r12]! add r7, #16 cmp r7, r4 blt .Loop_w add r0, r1 add r2, r3 subs r5, #1 bgt .Loop_h // handle last row mov r5, r4 lsr r5, #3 .LoopW8: vld1.u8 d0, [r0]! vshl.u8 d0, d0, d4 vst1.u8 d0, [r2]! subs r4, r4, #8 subs r5, #1 bgt .LoopW8 mov r5,#8 sub r5, r4 sub r0, r5 sub r2, r5 vld1.u8 d0, [r0] vshl.u8 d0, d0, d4 vst1.u8 d0, [r2] pop {r4, r5, r6, r7} bx lr endfunc //******* satd ******* .macro satd_4x4_neon vld1.32 {d1[]}, [r2], r3 vld1.32 {d0[]}, [r0,:32], r1 vld1.32 {d3[]}, [r2], r3 vld1.32 {d2[]}, [r0,:32], r1 vld1.32 {d1[1]}, [r2], r3 vld1.32 {d0[1]}, [r0,:32], r1 vld1.32 {d3[1]}, [r2], r3 vld1.32 {d2[1]}, [r0,:32], r1 vsubl.u8 q0, d0, d1 vsubl.u8 q1, d2, d3 SUMSUB_AB q2, q3, q0, q1 SUMSUB_ABCD d0, d2, d1, d3, d4, d5, d6, d7 HADAMARD 1, sumsub, q2, q3, q0, q1 HADAMARD 2, amax, q0,, q2, q3 HORIZ_ADD d0, d0, d1 .endm function x265_pixel_satd_4x4_neon satd_4x4_neon vmov.32 r0, d0[0] bx lr endfunc .macro LOAD_DIFF_8x4_1 q0 q1 q2 q3 vld1.32 {d1}, [r2], r3 vld1.32 {d0}, [r0,:64], r1 vsubl.u8 \q0, d0, d1 vld1.32 {d3}, [r2], r3 vld1.32 {d2}, [r0,:64], r1 vsubl.u8 \q1, d2, d3 vld1.32 {d5}, [r2], r3 vld1.32 {d4}, [r0,:64], r1 vsubl.u8 \q2, d4, d5 vld1.32 {d7}, [r2], r3 vld1.32 {d6}, [r0,:64], r1 vsubl.u8 \q3, d6, d7 .endm .macro x265_satd_4x8_8x4_end_neon vadd.s16 q0, q8, q10 vadd.s16 q1, q9, q11 vsub.s16 q2, q8, q10 vsub.s16 q3, q9, q11 vtrn.16 q0, q1 vadd.s16 q8, q0, q1 vtrn.16 q2, q3 vsub.s16 q9, q0, q1 vadd.s16 q10, q2, q3 vsub.s16 q11, q2, q3 vtrn.32 q8, q10 vabs.s16 q8, q8 vtrn.32 q9, q11 vabs.s16 q10, q10 vabs.s16 q9, q9 vabs.s16 q11, q11 vmax.u16 q0, q8, q10 vmax.u16 q1, q9, q11 vadd.u16 q0, q0, q1 HORIZ_ADD d0, d0, d1 .endm .macro pixel_satd_4x8_neon vld1.32 {d1[]}, [r2], r3 vld1.32 {d0[]}, [r0,:32], r1 vld1.32 {d3[]}, [r2], r3 vld1.32 {d2[]}, [r0,:32], r1 vld1.32 {d5[]}, [r2], r3 vld1.32 {d4[]}, [r0,:32], r1 vld1.32 {d7[]}, [r2], r3 vld1.32 {d6[]}, [r0,:32], r1 vld1.32 {d1[1]}, [r2], r3 vld1.32 {d0[1]}, [r0,:32], r1 vsubl.u8 q0, d0, d1 vld1.32 {d3[1]}, [r2], r3 vld1.32 {d2[1]}, [r0,:32], r1 vsubl.u8 q1, d2, d3 vld1.32 {d5[1]}, [r2], r3 vld1.32 {d4[1]}, [r0,:32], r1 vsubl.u8 q2, d4, d5 vld1.32 {d7[1]}, [r2], r3 SUMSUB_AB q8, q9, q0, q1 vld1.32 {d6[1]}, [r0,:32], r1 vsubl.u8 q3, d6, d7 SUMSUB_AB q10, q11, q2, q3 x265_satd_4x8_8x4_end_neon .endm function x265_pixel_satd_4x8_neon pixel_satd_4x8_neon vmov.32 r0, d0[0] bx lr endfunc function x265_pixel_satd_4x16_neon push {r4, r5} eor r4, r4 pixel_satd_4x8_neon vmov.32 r5, d0[0] add r4, r5 pixel_satd_4x8_neon vmov.32 r5, d0[0] add r0, r5, r4 pop {r4, r5} bx lr endfunc function x265_pixel_satd_4x32_neon push {r4, r5} eor r4, r4 .rept 4 pixel_satd_4x8_neon vmov.32 r5, d0[0] add r4, r5 .endr mov r0, r4 pop {r4, r5} bx lr endfunc function x265_pixel_satd_12x16_neon push {r4, r5, r6, r7} vpush {d8-d11} mov ip, lr mov r4, r0 mov r5, r2 eor r7, r7 pixel_satd_4x8_neon vmov.32 r6, d0[0] add r7, r6 pixel_satd_4x8_neon vmov.32 r6, d0[0] add r7, r6 add r0, r4, #4 add r2, r5, #4 pixel_satd_4x8_neon vmov.32 r6, d0[0] add r7, r6 pixel_satd_4x8_neon vmov.32 r6, d0[0] add r7, r6 add r0, r4, #8 add r2, r5, #8 pixel_satd_4x8_neon vmov.32 r6, d0[0] add r7, r6 pixel_satd_4x8_neon vmov.32 r6, d0[0] add r0, r7, r6 vpop {d8-d11} pop {r4, r5, r6, r7} mov lr, ip bx lr endfunc function x265_pixel_satd_12x32_neon push {r4, r5, r6, r7} vpush {d8-d11} mov ip, lr mov r4, r0 mov r5, r2 eor r7, r7 .rept 4 pixel_satd_4x8_neon vmov.32 r6, d0[0] add r7, r6 .endr add r0, r4, #4 add r2, r5, #4 .rept 4 pixel_satd_4x8_neon vmov.32 r6, d0[0] add r7, r6 .endr add r0, r4, #8 add r2, r5, #8 .rept 4 pixel_satd_4x8_neon vmov.32 r6, d0[0] add r7, r6 .endr mov r0, r7 vpop {d8-d11} pop {r4, r5, r6, r7} mov lr, ip bx lr endfunc function x265_pixel_satd_8x4_neon push {r4, r5, r6} mov r4, r0 mov r5, r2 satd_4x4_neon add r0, r4, #4 add r2, r5, #4 vmov.32 r6, d0[0] satd_4x4_neon vmov.32 r0, d0[0] add r0, r0, r6 pop {r4, r5, r6} bx lr endfunc function x265_pixel_satd_8x8_neon mov ip, lr push {r4, r5, r6, r7} eor r4, r4 mov r6, r0 mov r7, r2 pixel_satd_4x8_neon vmov.32 r5, d0[0] add r4, r5 add r0, r6, #4 add r2, r7, #4 pixel_satd_4x8_neon vmov.32 r5, d0[0] add r0, r4, r5 pop {r4, r5, r6, r7} mov lr, ip bx lr endfunc function x265_pixel_satd_8x12_neon push {r4, r5, r6, r7} mov r4, r0 mov r5, r2 eor r7, r7 satd_4x4_neon vmov.32 r6, d0[0] add r7, r6 add r0, r4, #4 add r2, r5, #4 satd_4x4_neon vmov.32 r6, d0[0] add r7, r6 .rept 2 sub r0, #4 sub r2, #4 mov r4, r0 mov r5, r2 satd_4x4_neon vmov.32 r6, d0[0] add r7, r6 add r0, r4, #4 add r2, r5, #4 satd_4x4_neon vmov.32 r6, d0[0] add r7, r6 .endr mov r0, r7 pop {r4, r5, r6, r7} bx lr endfunc function x265_pixel_satd_8x16_neon vpush {d8-d11} mov ip, lr bl x265_satd_8x8_neon vadd.u16 q4, q12, q13 vadd.u16 q5, q14, q15 bl x265_satd_8x8_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vpop {d8-d11} mov lr, ip vmov.32 r0, d0[0] bx lr endfunc function x265_pixel_satd_8x32_neon vpush {d8-d11} mov ip, lr bl x265_satd_8x8_neon vadd.u16 q4, q12, q13 vadd.u16 q5, q14, q15 .rept 3 bl x265_satd_8x8_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 .endr vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vpop {d8-d11} mov lr, ip vmov.32 r0, d0[0] bx lr endfunc function x265_pixel_satd_8x64_neon vpush {d8-d11} mov ip, lr bl x265_satd_8x8_neon vadd.u16 q4, q12, q13 vadd.u16 q5, q14, q15 .rept 7 bl x265_satd_8x8_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 .endr vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vpop {d8-d11} mov lr, ip vmov.32 r0, d0[0] bx lr endfunc function x265_satd_8x8_neon LOAD_DIFF_8x4_1 q8, q9, q10, q11 vld1.64 {d7}, [r2], r3 vld1.64 {d6}, [r0,:64], r1 vsubl.u8 q12, d6, d7 SUMSUB_AB q0, q1, q8, q9 vld1.64 {d17}, [r2], r3 vld1.64 {d16}, [r0,:64], r1 vsubl.u8 q13, d16, d17 SUMSUB_AB q2, q3, q10, q11 vld1.64 {d19}, [r2], r3 vld1.64 {d18}, [r0,:64], r1 vsubl.u8 q14, d18, d19 SUMSUB_AB q8, q10, q0, q2 vld1.64 {d1}, [r2], r3 vld1.64 {d0}, [r0,:64], r1 vsubl.u8 q15, d0, d1 SUMSUB_AB q9, q11, q1, q3 endfunc // one vertical hadamard pass and two horizontal function x265_satd_8x4v_8x8h_neon, export=0 SUMSUB_ABCD q0, q1, q2, q3, q12, q13, q14, q15 SUMSUB_AB q12, q14, q0, q2 SUMSUB_AB q13, q15, q1, q3 vtrn.16 q8, q9 vtrn.16 q10, q11 SUMSUB_AB q0, q1, q8, q9 SUMSUB_AB q2, q3, q10, q11 vtrn.16 q12, q13 vtrn.16 q14, q15 SUMSUB_AB q8, q9, q12, q13 SUMSUB_AB q10, q11, q14, q15 vtrn.32 q0, q2 vtrn.32 q1, q3 ABS2 q0, q2 ABS2 q1, q3 vtrn.32 q8, q10 vtrn.32 q9, q11 ABS2 q8, q10 ABS2 q9, q11 vmax.s16 q12, q0, q2 vmax.s16 q13, q1, q3 vmax.s16 q14, q8, q10 vmax.s16 q15, q9, q11 bx lr endfunc function x265_satd_16x4_neon, export=0 vld1.64 {d2-d3}, [r2], r3 vld1.64 {d0-d1}, [r0,:128], r1 vsubl.u8 q8, d0, d2 vsubl.u8 q12, d1, d3 vld1.64 {d6-d7}, [r2], r3 vld1.64 {d4-d5}, [r0,:128], r1 vsubl.u8 q9, d4, d6 vsubl.u8 q13, d5, d7 vld1.64 {d2-d3}, [r2], r3 vld1.64 {d0-d1}, [r0,:128], r1 vsubl.u8 q10, d0, d2 vsubl.u8 q14, d1, d3 vld1.64 {d6-d7}, [r2], r3 vld1.64 {d4-d5}, [r0,:128], r1 vsubl.u8 q11, d4, d6 vsubl.u8 q15, d5, d7 vadd.s16 q0, q8, q9 vsub.s16 q1, q8, q9 SUMSUB_AB q2, q3, q10, q11 SUMSUB_ABCD q8, q10, q9, q11, q0, q2, q1, q3 b x265_satd_8x4v_8x8h_neon endfunc function x265_pixel_satd_16x4_neon vpush {d8-d11} mov ip, lr bl x265_satd_16x4_neon vadd.u16 q4, q12, q13 vadd.u16 q5, q14, q15 vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vpop {d8-d11} mov lr, ip vmov.32 r0, d0[0] bx lr endfunc function x265_pixel_satd_16x8_neon vpush {d8-d11} mov ip, lr bl x265_satd_16x4_neon vadd.u16 q4, q12, q13 vadd.u16 q5, q14, q15 bl x265_satd_16x4_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vpop {d8-d11} mov lr, ip vmov.32 r0, d0[0] bx lr endfunc function x265_pixel_satd_16x12_neon vpush {d8-d11} mov ip, lr bl x265_satd_16x4_neon vadd.u16 q4, q12, q13 vadd.u16 q5, q14, q15 .rept 2 bl x265_satd_16x4_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 .endr vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vpop {d8-d11} mov lr, ip vmov.32 r0, d0[0] bx lr endfunc function x265_pixel_satd_16x16_neon vpush {d8-d11} mov ip, lr bl x265_satd_16x4_neon vadd.u16 q4, q12, q13 vadd.u16 q5, q14, q15 .rept 3 bl x265_satd_16x4_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 .endr vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vpop {d8-d11} mov lr, ip vmov.32 r0, d0[0] bx lr endfunc function x265_pixel_satd_16x24_neon vpush {d8-d11} mov ip, lr bl x265_satd_16x4_neon vadd.u16 q4, q12, q13 vadd.u16 q5, q14, q15 .rept 5 bl x265_satd_16x4_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 .endr vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vpop {d8-d11} mov lr, ip vmov.32 r0, d0[0] bx lr endfunc .macro pixel_satd_16x32_neon bl x265_satd_16x4_neon vadd.u16 q4, q12, q13 vadd.u16 q5, q14, q15 .rept 7 bl x265_satd_16x4_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 .endr .endm function x265_pixel_satd_16x32_neon vpush {d8-d11} mov ip, lr pixel_satd_16x32_neon vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vpop {d8-d11} mov lr, ip vmov.32 r0, d0[0] bx lr endfunc function x265_pixel_satd_16x64_neon push {r6, r7} vpush {d8-d11} mov ip, lr eor r7, r7 pixel_satd_16x32_neon vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vmov.32 r6, d0[0] add r7, r6 veor q4, q5 veor q5, q5 pixel_satd_16x32_neon vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vmov.32 r6, d0[0] add r0, r7, r6 vpop {d8-d11} pop {r6, r7} mov lr, ip bx lr endfunc function x265_pixel_satd_24x32_neon push {r4, r5, r6, r7} vpush {d8-d11} mov ip, lr eor r7, r7 mov r4, r0 mov r5, r2 .rept 3 veor q4, q4 veor q5, q5 .rept 4 bl x265_satd_8x8_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 .endr vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vmov.32 r6, d0[0] add r7, r6 add r4, #8 add r5, #8 mov r0, r4 mov r2, r5 .endr mov r0, r7 vpop {d8-d11} pop {r4, r5, r6, r7} mov lr, ip bx lr endfunc function x265_pixel_satd_24x64_neon push {r4, r5, r6, r7} vpush {d8-d11} mov ip, lr eor r7, r7 mov r4, r0 mov r5, r2 .rept 3 veor q4, q4 veor q5, q5 .rept 4 bl x265_satd_8x8_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 .endr vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vmov.32 r6, d0[0] add r7, r6 add r4, #8 add r5, #8 mov r0, r4 mov r2, r5 .endr sub r4, #24 sub r5, #24 add r0, r4, r1, lsl #5 add r2, r5, r3, lsl #5 mov r4, r0 mov r5, r2 .rept 3 veor q4, q4 veor q5, q5 .rept 4 bl x265_satd_8x8_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 .endr vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vmov.32 r6, d0[0] add r7, r6 add r4, #8 add r5, #8 mov r0, r4 mov r2, r5 .endr mov r0, r7 vpop {d8-d11} pop {r4, r5, r6, r7} mov lr, ip bx lr endfunc .macro pixel_satd_32x8 mov r4, r0 mov r5, r2 bl x265_satd_16x4_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 bl x265_satd_16x4_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 add r0, r4, #16 add r2, r5, #16 bl x265_satd_16x4_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 bl x265_satd_16x4_neon vadd.u16 q4, q4, q12 vadd.u16 q5, q5, q13 vadd.u16 q4, q4, q14 vadd.u16 q5, q5, q15 .endm function x265_pixel_satd_32x8_neon push {r4, r5} vpush {d8-d11} mov ip, lr veor q4, q4 veor q5, q5 pixel_satd_32x8 vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vmov.32 r0, d0[0] vpop {d8-d11} pop {r4, r5} mov lr, ip bx lr endfunc .macro satd_32x16_neon veor q4, q4 veor q5, q5 pixel_satd_32x8 sub r0, #16 sub r2, #16 pixel_satd_32x8 vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vmov.32 r6, d0[0] .endm function x265_pixel_satd_32x16_neon push {r4, r5, r6} vpush {d8-d11} mov ip, lr satd_32x16_neon mov r0, r6 vpop {d8-d11} pop {r4, r5, r6} mov lr, ip bx lr endfunc function x265_pixel_satd_32x24_neon push {r4, r5, r6} vpush {d8-d11} mov ip, lr satd_32x16_neon veor q4, q4 veor q5, q5 sub r0, #16 sub r2, #16 pixel_satd_32x8 vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vmov.32 r0, d0[0] add r0, r6 vpop {d8-d11} pop {r4, r5, r6} mov lr, ip bx lr endfunc function x265_pixel_satd_32x32_neon push {r4, r5, r6, r7} vpush {d8-d11} mov ip, lr eor r7, r7 satd_32x16_neon sub r0, #16 sub r2, #16 add r7, r6 satd_32x16_neon add r0, r7, r6 vpop {d8-d11} pop {r4, r5, r6, r7} mov lr, ip bx lr endfunc function x265_pixel_satd_32x48_neon push {r4, r5, r6, r7} vpush {d8-d11} mov ip, lr eor r7, r7 .rept 2 satd_32x16_neon sub r0, #16 sub r2, #16 add r7, r6 .endr satd_32x16_neon add r0, r7, r6 vpop {d8-d11} pop {r4, r5, r6, r7} mov lr, ip bx lr endfunc function x265_pixel_satd_32x64_neon push {r4, r5, r6, r7} vpush {d8-d11} mov ip, lr eor r7, r7 .rept 3 satd_32x16_neon sub r0, #16 sub r2, #16 add r7, r6 .endr satd_32x16_neon add r0, r7, r6 vpop {d8-d11} pop {r4, r5, r6, r7} mov lr, ip bx lr endfunc .macro satd_64x16_neon mov r8, r0 mov r9, r2 satd_32x16_neon add r7, r6 add r0, r8, #32 add r2, r9, #32 satd_32x16_neon add r7, r6 .endm function x265_pixel_satd_64x16_neon push {r4, r5, r6, r7, r8, r9} vpush {d8-d11} mov ip, lr eor r7, r7 satd_64x16_neon mov r0, r7 vpop {d8-d11} pop {r4, r5, r6, r7, r8, r9} mov lr, ip bx lr endfunc function x265_pixel_satd_64x32_neon push {r4, r5, r6, r7, r8, r9} vpush {d8-d11} mov ip, lr eor r7, r7 satd_64x16_neon sub r0, #48 sub r2, #48 satd_64x16_neon mov r0, r7 vpop {d8-d11} pop {r4, r5, r6, r7, r8, r9} mov lr, ip bx lr endfunc function x265_pixel_satd_64x48_neon push {r4, r5, r6, r7, r8, r9} vpush {d8-d11} mov ip, lr eor r7, r7 satd_64x16_neon sub r0, #48 sub r2, #48 satd_64x16_neon sub r0, #48 sub r2, #48 satd_64x16_neon mov r0, r7 vpop {d8-d11} pop {r4, r5, r6, r7, r8, r9} mov lr, ip bx lr endfunc function x265_pixel_satd_64x64_neon push {r4, r5, r6, r7, r8, r9} vpush {d8-d11} mov ip, lr eor r7, r7 satd_64x16_neon sub r0, #48 sub r2, #48 satd_64x16_neon sub r0, #48 sub r2, #48 satd_64x16_neon sub r0, #48 sub r2, #48 satd_64x16_neon mov r0, r7 vpop {d8-d11} pop {r4, r5, r6, r7, r8, r9} mov lr, ip bx lr endfunc function x265_pixel_satd_48x64_neon push {r4, r5, r6, r7, r8, r9} vpush {d8-d11} mov ip, lr eor r7, r7 mov r8, r0 mov r9, r2 .rept 3 satd_32x16_neon sub r0, #16 sub r2, #16 add r7, r6 .endr satd_32x16_neon add r7, r6 add r0, r8, #32 add r2, r9, #32 pixel_satd_16x32_neon vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vmov.32 r6, d0[0] add r7, r6 veor q4, q5 veor q5, q5 pixel_satd_16x32_neon vadd.u16 q0, q4, q5 HORIZ_ADD d0, d0, d1 vmov.32 r6, d0[0] add r0, r7, r6 vpop {d8-d11} pop {r4, r5, r6, r7, r8, r9} mov lr, ip bx lr endfunc .macro LOAD_DIFF_8x4 q0 q1 q2 q3 vld1.32 {d1}, [r2], r3 vld1.32 {d0}, [r0,:64], r1 vsubl.u8 \q0, d0, d1 vld1.32 {d3}, [r2], r3 vld1.32 {d2}, [r0,:64], r1 vsubl.u8 \q1, d2, d3 vld1.32 {d5}, [r2], r3 vld1.32 {d4}, [r0,:64], r1 vsubl.u8 \q2, d4, d5 vld1.32 {d7}, [r2], r3 vld1.32 {d6}, [r0,:64], r1 vsubl.u8 \q3, d6, d7 .endm .macro HADAMARD4_V r1, r2, r3, r4, t1, t2, t3, t4 SUMSUB_ABCD \t1, \t2, \t3, \t4, \r1, \r2, \r3, \r4 SUMSUB_ABCD \r1, \r3, \r2, \r4, \t1, \t3, \t2, \t4 .endm .macro sa8d_satd_8x8 satd= function x265_sa8d_\satd\()8x8_neon, export=0 LOAD_DIFF_8x4 q8, q9, q10, q11 vld1.64 {d7}, [r2], r3 SUMSUB_AB q0, q1, q8, q9 vld1.64 {d6}, [r0,:64], r1 vsubl.u8 q12, d6, d7 vld1.64 {d17}, [r2], r3 SUMSUB_AB q2, q3, q10, q11 vld1.64 {d16}, [r0,:64], r1 vsubl.u8 q13, d16, d17 vld1.64 {d19}, [r2], r3 SUMSUB_AB q8, q10, q0, q2 vld1.64 {d18}, [r0,:64], r1 vsubl.u8 q14, d18, d19 vld1.64 {d1}, [r2], r3 SUMSUB_AB q9, q11, q1, q3 vld1.64 {d0}, [r0,:64], r1 vsubl.u8 q15, d0, d1 HADAMARD4_V q12, q13, q14, q15, q0, q1, q2, q3 SUMSUB_ABCD q0, q8, q1, q9, q8, q12, q9, q13 SUMSUB_AB q2, q10, q10, q14 vtrn.16 q8, q9 SUMSUB_AB q3, q11, q11, q15 vtrn.16 q0, q1 SUMSUB_AB q12, q13, q8, q9 vtrn.16 q10, q11 SUMSUB_AB q8, q9, q0, q1 vtrn.16 q2, q3 SUMSUB_AB q14, q15, q10, q11 vadd.i16 q10, q2, q3 vtrn.32 q12, q14 vsub.i16 q11, q2, q3 vtrn.32 q13, q15 SUMSUB_AB q0, q2, q12, q14 vtrn.32 q8, q10 SUMSUB_AB q1, q3, q13, q15 vtrn.32 q9, q11 SUMSUB_AB q12, q14, q8, q10 SUMSUB_AB q13, q15, q9, q11 vswp d1, d24 ABS2 q0, q12 vswp d3, d26 ABS2 q1, q13 vswp d5, d28 ABS2 q2, q14 vswp d7, d30 ABS2 q3, q15 vmax.s16 q8, q0, q12 vmax.s16 q9, q1, q13 vmax.s16 q10, q2, q14 vmax.s16 q11, q3, q15 vadd.i16 q8, q8, q9 vadd.i16 q9, q10, q11 bx lr endfunc .endm sa8d_satd_8x8 function x265_pixel_sa8d_8x8_neon mov ip, lr bl x265_sa8d_8x8_neon vadd.u16 q0, q8, q9 HORIZ_ADD d0, d0, d1 mov lr, ip vmov.32 r0, d0[0] add r0, r0, #1 lsr r0, r0, #1 bx lr endfunc function x265_pixel_sa8d_8x16_neon push {r4, r5} mov ip, lr bl x265_sa8d_8x8_neon vadd.u16 q0, q8, q9 HORIZ_ADD d0, d0, d1 vmov.32 r5, d0[0] add r5, r5, #1 lsr r5, r5, #1 bl x265_sa8d_8x8_neon vadd.u16 q0, q8, q9 HORIZ_ADD d0, d0, d1 vmov.32 r4, d0[0] add r4, r4, #1 lsr r4, r4, #1 add r0, r4, r5 mov lr, ip pop {r4, r5} bx lr endfunc function x265_pixel_sa8d_16x16_neon vpush {d8 - d11} mov ip, lr bl x265_sa8d_8x8_neon vpaddl.u16 q4, q8 vpaddl.u16 q5, q9 bl x265_sa8d_8x8_neon vpadal.u16 q4, q8 vpadal.u16 q5, q9 sub r0, r0, r1, lsl #4 sub r2, r2, r3, lsl #4 add r0, r0, #8 add r2, r2, #8 bl x265_sa8d_8x8_neon vpadal.u16 q4, q8 vpadal.u16 q5, q9 bl x265_sa8d_8x8_neon vpaddl.u16 q8, q8 vpaddl.u16 q9, q9 vadd.u32 q0, q4, q8 vadd.u32 q1, q5, q9 vadd.u32 q0, q0, q1 vadd.u32 d0, d0, d1 vpadd.u32 d0, d0, d0 vpop {d8-d11} mov lr, ip vmov.32 r0, d0[0] add r0, r0, #1 lsr r0, r0, #1 bx lr endfunc function x265_quant_neon push {r4-r6} ldr r4, [sp, #3* 4] mov r12, #1 lsl r12, r4 vdup.s32 d0, r12 // q0 = 2^qbits neg r12, r4 vdup.s32 q1, r12 // q1= -qbits add r12, #8 vdup.s32 q2, r12 // q2= -qbits+8 ldr r4, [sp, #3* 4 + 4] vdup.s32 q3, r4 // q3= add ldr r4, [sp, #3* 4 + 8] // r4= numcoeff lsr r4, r4 ,#2 veor.s32 q4, q4 // q4= accumulate numsig eor r5, r5 veor.s32 q12, q12 .Loop_quant: vld1.s16 d16, [r0]! vmovl.s16 q9, d16 // q9= coef[blockpos] vclt.s32 q8, q9, #0 // q8= sign vabs.s32 q9, q9 // q9= level=abs(coef[blockpos]) vld1.s32 {q10}, [r1]! // q10= quantCoeff[blockpos] vmul.i32 q9, q9, q10 // q9 = tmplevel = abs(level) * quantCoeff[blockpos]; vadd.s32 q10, q9, q3 // q10= tmplevel+add vshl.s32 q10, q10, q1 // q10= level =(tmplevel+add) >> qbits vmls.s32 q9, q10, d0[0] // q10= tmplevel - (level << qBits) vshl.s32 q11, q9, q2 // q11= ((tmplevel - (level << qBits)) >> qBits8) vst1.s32 {q11}, [r2]! // store deltaU // numsig vceq.s32 q11, q10, q12 vadd.s32 q4, q11 add r5, #4 veor.s32 q11, q10, q8 vsub.s32 q11, q11, q8 vqmovn.s32 d16, q11 vst1.s16 d16, [r3]! subs r4, #1 bne .Loop_quant vadd.u32 d8, d9 vpadd.u32 d8, d8 vmov.32 r12, d8[0] add r0, r5, r12 pop {r4-r6} bx lr endfunc function x265_nquant_neon push {r4} neg r12, r3 vdup.s32 q0, r12 // q0= -qbits ldr r3, [sp, #1* 4] vdup.s32 q1, r3 // add ldr r3, [sp, #1* 4 + 4] // numcoeff lsr r3, r3 ,#2 veor.s32 q4, q4 // q4= accumulate numsig eor r4, r4 veor.s32 q12, q12 .Loop_nquant: vld1.s16 d16, [r0]! vmovl.s16 q9, d16 // q9= coef[blockpos] vclt.s32 q8, q9, #0 // q8= sign vabs.s32 q9, q9 // q9= level=abs(coef[blockpos]) vld1.s32 {q10}, [r1]! // q10= quantCoeff[blockpos] vmul.i32 q9, q9, q10 // q9 = tmplevel = abs(level) * quantCoeff[blockpos]; vadd.s32 q10, q9, q1 // q10= tmplevel+add vshl.s32 q10, q10, q0 // q10= level =(tmplevel+add) >> qbits // numsig vceq.s32 q11, q10, q12 vadd.s32 q4, q11 add r4, #4 veor.s32 q11, q10, q8 vsub.s32 q11, q11, q8 vqmovn.s32 d16, q11 vabs.s16 d17, d16 vst1.s16 d17, [r2]! subs r3, #1 bne .Loop_nquant vadd.u32 d8, d9 vpadd.u32 d8, d8 vmov.32 r12, d8[0] add r0, r4, r12 pop {r4} bx lr endfunc .macro sa8d_16x16 reg bl x265_sa8d_8x8_neon vpaddl.u16 q4, q8 vpaddl.u16 q5, q9 bl x265_sa8d_8x8_neon vpadal.u16 q4, q8 vpadal.u16 q5, q9 sub r0, r0, r1, lsl #4 sub r2, r2, r3, lsl #4 add r0, r0, #8 add r2, r2, #8 bl x265_sa8d_8x8_neon vpadal.u16 q4, q8 vpadal.u16 q5, q9 bl x265_sa8d_8x8_neon vpaddl.u16 q8, q8 vpaddl.u16 q9, q9 vadd.u32 q0, q4, q8 vadd.u32 q1, q5, q9 vadd.u32 q0, q0, q1 vadd.u32 d0, d0, d1 vpadd.u32 d0, d0, d0 vmov.32 \reg, d0[0] add \reg, \reg, #1 lsr \reg, \reg, #1 .endm function x265_pixel_sa8d_16x32_neon push {r4, r5} vpush {d8 - d11} mov ip, lr sa8d_16x16 r4 sub r0, r0, #8 sub r2, r2, #8 sa8d_16x16 r5 add r0, r4, r5 vpop {d8 - d11} pop {r4, r5} mov lr, ip bx lr endfunc function x265_pixel_sa8d_32x32_neon push {r4 - r7} vpush {d8 - d11} mov ip, lr sa8d_16x16 r4 sub r0, r0, r1, lsl #4 sub r2, r2, r3, lsl #4 add r0, r0, #8 add r2, r2, #8 sa8d_16x16 r5 sub r0, r0, #24 sub r2, r2, #24 sa8d_16x16 r6 sub r0, r0, r1, lsl #4 sub r2, r2, r3, lsl #4 add r0, r0, #8 add r2, r2, #8 sa8d_16x16 r7 add r4, r4, r5 add r6, r6, r7 add r0, r4, r6 vpop {d8 - d11} pop {r4 - r7} mov lr, ip bx lr endfunc function x265_pixel_sa8d_32x64_neon push {r4 - r10} vpush {d8 - d11} mov ip, lr mov r10, #4 eor r9, r9 .Loop_32: sa8d_16x16 r4 sub r0, r0, r1, lsl #4 sub r2, r2, r3, lsl #4 add r0, r0, #8 add r2, r2, #8 sa8d_16x16 r5 add r4, r4, r5 add r9, r9, r4 sub r0, r0, #24 sub r2, r2, #24 subs r10, #1 bgt .Loop_32 mov r0, r9 vpop {d8-d11} pop {r4-r10} mov lr, ip bx lr endfunc function x265_pixel_sa8d_64x64_neon push {r4-r10} vpush {d8-d11} mov ip, lr mov r10, #4 eor r9, r9 .Loop_1: sa8d_16x16 r4 sub r0, r0, r1, lsl #4 sub r2, r2, r3, lsl #4 add r0, r0, #8 add r2, r2, #8 sa8d_16x16 r5 sub r0, r0, r1, lsl #4 sub r2, r2, r3, lsl #4 add r0, r0, #8 add r2, r2, #8 sa8d_16x16 r6 sub r0, r0, r1, lsl #4 sub r2, r2, r3, lsl #4 add r0, r0, #8 add r2, r2, #8 sa8d_16x16 r7 add r4, r4, r5 add r6, r6, r7 add r8, r4, r6 add r9, r9, r8 sub r0, r0, #56 sub r2, r2, #56 subs r10, #1 bgt .Loop_1 mov r0, r9 vpop {d8-d11} pop {r4-r10} mov lr, ip bx lr endfunc /***** dequant_scaling*****/ // void dequant_scaling_c(const int16_t* quantCoef, const int32_t* deQuantCoef, int16_t* coef, int num, int per, int shift) function x265_dequant_scaling_neon push {r4, r5, r6, r7} ldr r4, [sp, #16] // per ldr r5, [sp, #20] //.shift add r5, #4 // shift + 4 lsr r3, #3 // num / 8 cmp r5, r4 blt skip mov r12, #1 sub r6, r5, r4 // shift - per sub r6, #1 // shift - per - 1 lsl r6, r12, r6 // 1 << shift - per - 1 (add) vdup.32 q0, r6 sub r7, r4, r5 // per - shift vdup.32 q3, r7 dequant_loop1: vld1.16 {q9}, [r0]! // quantCoef vld1.32 {q2}, [r1]! // deQuantCoef vld1.32 {q10}, [r1]! vmovl.s16 q1, d18 vmovl.s16 q9, d19 vmul.s32 q1, q2 // quantCoef * deQuantCoef vmul.s32 q9, q10 vadd.s32 q1, q0 // quantCoef * deQuantCoef + add vadd.s32 q9, q0 vshl.s32 q1, q3 vshl.s32 q9, q3 vqmovn.s32 d16, q1 // x265_clip3 vqmovn.s32 d17, q9 subs r3, #1 vst1.16 {q8}, [r2]! bne dequant_loop1 b 1f skip: sub r6, r4, r5 // per - shift vdup.16 q0, r6 dequant_loop2: vld1.16 {q9}, [r0]! // quantCoef vld1.32 {q2}, [r1]! // deQuantCoef vld1.32 {q10}, [r1]! vmovl.s16 q1, d18 vmovl.s16 q9, d19 vmul.s32 q1, q2 // quantCoef * deQuantCoef vmul.s32 q9, q10 vqmovn.s32 d16, q1 // x265_clip3 vqmovn.s32 d17, q9 vqshl.s16 q8, q0 // coefQ << per - shift subs r3, #1 vst1.16 {q8}, [r2]! bne dequant_loop2 1: pop {r4, r5, r6, r7} bx lr endfunc // void dequant_normal_c(const int16_t* quantCoef, int16_t* coef, int num, int scale, int shift) function x265_dequant_normal_neon ldr r12, [sp] // shift #if HIGH_BIT_DEPTH // NEVER TEST path cmp r3, #32768 lsrlt r3, #(BIT_DEPTH - 8) sublt r12, #(BIT_DEPTH - 8) #endif lsr r2, #4 // num / 16 neg r12, r12 vdup.16 q0, r3 vdup.32 q1, r12 .dqn_loop1: vld1.16 {d4-d7}, [r0]! vmull.s16 q8, d4, d0 vmull.s16 q9, d5, d0 vmull.s16 q10, d6, d0 vmull.s16 q11, d7, d0 vrshl.s32 q8, q1 vrshl.s32 q9, q1 vrshl.s32 q10, q1 vrshl.s32 q11, q1 vqmovn.s32 d16, q8 vqmovn.s32 d17, q9 vqmovn.s32 d18, q10 vqmovn.s32 d19, q11 subs r2, #1 vst1.16 {d16-d19}, [r1]! bgt .dqn_loop1 bx lr endfunc /********* ssim ***********/ // void x265_ssim_4x4x2_core_neon(const pixel* pix1, intptr_t stride1, const pixel* pix2, intptr_t stride2, int sums[2][4]); function x265_ssim_4x4x2_core_neon ldr r12, [sp] vld1.64 {d0}, [r0], r1 vld1.64 {d1}, [r0], r1 vld1.64 {d2}, [r0], r1 vld1.64 {d3}, [r0], r1 vld1.64 {d4}, [r2], r3 vld1.64 {d5}, [r2], r3 vld1.64 {d6}, [r2], r3 vld1.64 {d7}, [r2], r3 vpaddl.u8 q8, q0 vpadal.u8 q8, q1 vpaddl.u8 q9, q2 vpadal.u8 q9, q3 vadd.u16 d16, d17 vpaddl.u16 d16, d16 vadd.u16 d18, d19 vpaddl.u16 d17, d18 vmull.u8 q10, d0, d0 vmull.u8 q11, d1, d1 vmull.u8 q12, d2, d2 vmull.u8 q13, d3, d3 vpaddl.u16 q10, q10 vpadal.u16 q10, q11 vpadal.u16 q10, q12 vpadal.u16 q10, q13 vmull.u8 q9, d4, d4 vmull.u8 q11, d5, d5 vmull.u8 q12, d6, d6 vmull.u8 q13, d7, d7 vpadal.u16 q10, q9 vpadal.u16 q10, q11 vpadal.u16 q10, q12 vpadal.u16 q10, q13 vpadd.u32 d18, d20, d21 vmull.u8 q10, d0, d4 vmull.u8 q11, d1, d5 vmull.u8 q12, d2, d6 vmull.u8 q13, d3, d7 vpaddl.u16 q10, q10 vpadal.u16 q10, q11 vpadal.u16 q10, q12 vpadal.u16 q10, q13 vpadd.u32 d19, d20, d21 vst4.32 {d16-d19}, [r12] bx lr endfunc // int psyCost_pp(const pixel* source, intptr_t sstride, const pixel* recon, intptr_t rstride) function x265_psyCost_4x4_neon vld1.32 {d16[]}, [r0,:32], r1 // d16 = [A03 A02 A01 A00 A03 A02 A01 A00] vld1.32 {d17[]}, [r0,:32], r1 // d17 = [A13 A12 A11 A10 A13 A12 A11 A10] vld1.32 {d16[1]}, [r0,:32], r1 // d16 = [A23 A22 A21 A20 A03 A02 A01 A00] vld1.32 {d17[1]}, [r0,:32], r1 // d17 = [A33 A32 A31 A30 A13 A12 A11 A10] vld1.32 {d18[]}, [r2,:32], r3 // d18 = [B03 B02 B01 B00 B03 B02 B01 B00] vld1.32 {d19[]}, [r2,:32], r3 // d19 = [B13 B12 B11 B10 B13 B12 B11 B10] vld1.32 {d18[1]}, [r2,:32], r3 // d18 = [B23 B22 B21 B20 B03 B02 B01 B00] vld1.32 {d19[1]}, [r2,:32], r3 // d19 = [B33 B32 B31 B30 B13 B12 B11 B10] vaddl.u8 q2, d16, d17 // q2 = [2+3 0+1] vsubl.u8 q3, d16, d17 // q3 = [2-3 0-1] vaddl.u8 q12, d18, d19 vsubl.u8 q13, d18, d19 SUMSUB_ABCD d0, d2, d1, d3, d4, d5, d6, d7 // q0 = [(0-1)+(2-3) (0+1)+(2+3)], q1 = [(0-1)-(2-3) (0+1)-(2+3)] SUMSUB_ABCD d20, d22, d21, d23, d24, d25, d26, d27 // Hadamard-1D vtrn.16 q0, q1 vtrn.16 q10, q11 SUMSUB_AB q2, q3, q0, q1 // q2 = [((0-1)-(2-3))+((0-1)+(2-3)) ((0+1)-(2+3))+((0+1)+(2+3))], q3 = [((0-1)-(2-3))-((0-1)+(2-3)) ((0+1)-(2+3))-((0+1)+(2+3))] SUMSUB_AB q12, q13, q10, q11 // SAD Stage-0 vaddl.u8 q14, d16, d17 // q14 = [S23x4 S01x4] vaddl.u8 q15, d18, d19 // Hadamard-2D vtrn.32 q2, q3 vtrn.32 q12, q13 vabs.s16 q2, q2 vabs.s16 q12, q12 vabs.s16 q3, q3 vabs.s16 q13, q13 // SAD Stage-1 vadd.u16 d28, d29 // SAD: reduce to 4 elements vadd.u16 d30, d31 vmax.s16 q0, q2, q3 vmax.s16 q10, q12, q13 // SAD Stage-2 vpadd.u16 d28, d30 // SAD: reduce to 2 elements // SAD & SATD Final Stage vswp d1, d20 vadd.u16 q0, q10 vpaddl.u16 d28, d28 // d28 = SAD_DWORD[B A] vpadd.u16 d0, d1 vshr.u32 d28, #2 // d28 = SAD_DWORD[B A] >> 2 vpaddl.u16 d0, d0 // d0 = SATD_DWORD[B A] vsub.s32 d0, d28 // d0 = SATD - SAD vmov.32 r0, d0[0] vmov.32 r1, d0[1] subs r0, r1 rsbmi r0, r0, #0 bx lr endfunc function x265_psyCost_8x8_neon vpush {q4-q7} vld1.8 {d0}, [r0], r1 vld1.8 {d1}, [r0], r1 vmovl.u8 q8, d0 vld1.8 {d2}, [r0], r1 vmovl.u8 q9, d1 vld1.8 {d3}, [r0], r1 vmovl.u8 q10, d2 vld1.8 {d4}, [r0], r1 vmovl.u8 q11, d3 vld1.8 {d5}, [r0], r1 vmovl.u8 q12, d4 vld1.8 {d6}, [r0], r1 vmovl.u8 q13, d5 vld1.8 {d7}, [r0], r1 vmovl.u8 q14, d6 vmovl.u8 q15, d7 // SAD Stage-0 vadd.u16 q4, q8, q9 vadd.u16 q5, q10, q11 vadd.u16 q6, q12, q13 vadd.u16 q7, q14, q15 // SAD Stage-1 vadd.u16 q4, q5 vadd.u16 q6, q7 vadd.u16 q4, q6 vpadd.u16 d8, d9 vpaddl.u16 d8, d8 vpadd.u32 d8, d8 vshr.u32 d8, #2 // sa8d SUMSUB_AB q0, q1, q8, q9 SUMSUB_AB q2, q3, q10, q11 SUMSUB_AB q8, q10, q0, q2 SUMSUB_AB q9, q11, q1, q3 HADAMARD4_V q12, q13, q14, q15, q0, q1, q2, q3 SUMSUB_ABCD q0, q8, q1, q9, q8, q12, q9, q13 SUMSUB_AB q2, q10, q10, q14 vtrn.16 q8, q9 SUMSUB_AB q3, q11, q11, q15 vtrn.16 q0, q1 SUMSUB_AB q12, q13, q8, q9 vtrn.16 q10, q11 SUMSUB_AB q8, q9, q0, q1 vtrn.16 q2, q3 SUMSUB_AB q14, q15, q10, q11 vadd.i16 q10, q2, q3 vtrn.32 q12, q14 vsub.i16 q11, q2, q3 vtrn.32 q13, q15 SUMSUB_AB q0, q2, q12, q14 vtrn.32 q8, q10 SUMSUB_AB q1, q3, q13, q15 vtrn.32 q9, q11 SUMSUB_AB q12, q14, q8, q10 SUMSUB_AB q13, q15, q9, q11 vswp d1, d24 ABS2 q0, q12 vswp d3, d26 ABS2 q1, q13 vswp d5, d28 ABS2 q2, q14 vswp d7, d30 ABS2 q3, q15 vmax.s16 q8, q0, q12 vmax.s16 q9, q1, q13 vmax.s16 q10, q2, q14 vmax.s16 q11, q3, q15 vadd.i16 q8, q8, q9 vadd.i16 q9, q10, q11 vadd.u16 q0, q8, q9 vadd.u16 d0, d1 vpaddl.u16 d0, d0 vpadd.u32 d0, d0 vmov.32 r0, d0[0] add r0, r0, #1 lsr r0, r0, #1 //------------------------------------------------------------- vld1.8 d0, [r2], r3 vld1.8 d1, [r2], r3 vmovl.u8 q8, d0 vld1.8 d2, [r2], r3 vmovl.u8 q9, d1 vld1.8 d3, [r2], r3 vmovl.u8 q10, d2 vld1.8 d4, [r2], r3 vmovl.u8 q11, d3 vld1.8 d5, [r2], r3 vmovl.u8 q12, d4 vld1.8 d6, [r2], r3 vmovl.u8 q13, d5 vld1.8 d7, [r2], r3 vmovl.u8 q14, d6 vmovl.u8 q15, d7 // SAD Stage-0 vadd.u16 q5, q8, q9 vadd.u16 q6, q10, q11 vadd.u16 q7, q12, q13 vadd.u16 q0, q14, q15 // SAD Stage-1 vadd.u16 q5, q6 vadd.u16 q7, q0 vadd.u16 q5, q7 vadd.u16 d10, d11 vpaddl.u16 d10, d10 vpadd.u32 d10, d10 vshr.u32 d10, #2 // sa8d SUMSUB_AB q0, q1, q8, q9 SUMSUB_AB q2, q3, q10, q11 SUMSUB_AB q8, q10, q0, q2 SUMSUB_AB q9, q11, q1, q3 HADAMARD4_V q12, q13, q14, q15, q0, q1, q2, q3 SUMSUB_ABCD q0, q8, q1, q9, q8, q12, q9, q13 SUMSUB_AB q2, q10, q10, q14 vtrn.16 q8, q9 SUMSUB_AB q3, q11, q11, q15 vtrn.16 q0, q1 SUMSUB_AB q12, q13, q8, q9 vtrn.16 q10, q11 SUMSUB_AB q8, q9, q0, q1 vtrn.16 q2, q3 SUMSUB_AB q14, q15, q10, q11 vadd.i16 q10, q2, q3 vtrn.32 q12, q14 vsub.i16 q11, q2, q3 vtrn.32 q13, q15 SUMSUB_AB q0, q2, q12, q14 vtrn.32 q8, q10 SUMSUB_AB q1, q3, q13, q15 vtrn.32 q9, q11 SUMSUB_AB q12, q14, q8, q10 SUMSUB_AB q13, q15, q9, q11 vswp d1, d24 ABS2 q0, q12 vswp d3, d26 ABS2 q1, q13 vswp d5, d28 ABS2 q2, q14 vswp d7, d30 ABS2 q3, q15 vmax.s16 q8, q0, q12 vmax.s16 q9, q1, q13 vmax.s16 q10, q2, q14 vmax.s16 q11, q3, q15 vadd.i16 q8, q8, q9 vadd.i16 q9, q10, q11 vadd.u16 q0, q8, q9 vadd.u16 d0, d1 vpaddl.u16 d0, d0 vpadd.u32 d0, d0 vmov.32 r2, d0[0] add r2, r2, #1 lsr r2, r2, #1 // SAD & SA8D Final Stage vmov.32 r1, d8[0] sub r0, r1 vmov.32 r3, d10[0] sub r2, r3 cmp r0, r2 bgt subr0 sub r0, r2, r0 b end subr0: sub r0, r2 end: vpop {q4-q7} bx lr endfunc