;****************************************************************************** ;* TTA DSP SIMD optimizations ;* ;* Copyright (C) 2014 James Almer ;* ;* This file is part of FFmpeg. ;* ;* FFmpeg is free software; you can redistribute it and/or ;* modify it under the terms of the GNU Lesser General Public ;* License as published by the Free Software Foundation; either ;* version 2.1 of the License, or (at your option) any later version. ;* ;* FFmpeg 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 ;* Lesser General Public License for more details. ;* ;* You should have received a copy of the GNU Lesser General Public ;* License along with FFmpeg; if not, write to the Free Software ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** %include "config_components.asm" %include "libavutil/x86/x86util.asm" SECTION_RODATA pd_n0113: dd ~0, ~1, ~1, ~3 pd_1224: dd 1, 2, 2, 4 SECTION .text %macro TTA_FILTER 2-3 INIT_XMM %1 cglobal tta%3_filter_process, 5,5,%2, qm, dx, dl, error, in, shift, round mova m2, [qmq ] mova m3, [qmq + 0x10] mova m4, [dxq ] mova m5, [dxq + 0x10] movd m1, [errorq] ; if (filter->error < 0) { SPLATD m1 ; for (int i = 0; i < 8; i++) psignd m0, m4, m1 ; filter->qm[i] -= filter->dx[i]; %if avx_enabled psignd m1, m5, m1 ; } else if (filter->error > 0) { %else SWAP 1, 6 psignd m1, m5, m6 ; } else if (filter->error > 0) { %endif paddd m2, m0 ; for (int i = 0; i < 8; i++) paddd m3, m1 ; filter->qm[i] += filter->dx[i]; mova [qmq ], m2 ; } mova [qmq + 0x10], m3 ; mova m0, [dlq ] mova m1, [dlq + 0x10] %if cpuflag(sse4) pmulld m2, m0 pmulld m3, m1 palignr m5, m4, 4 ; filter->dx[0] = filter->dx[1]; filter->dx[1] = filter->dx[2]; ; filter->dx[2] = filter->dx[3]; filter->dx[3] = filter->dx[4]; %else pshufd m6, m0, 0xb1 palignr m5, m4, 4 ; filter->dx[0] = filter->dx[1]; filter->dx[1] = filter->dx[2]; ; filter->dx[2] = filter->dx[3]; filter->dx[3] = filter->dx[4]; pshufd m4, m2, 0xb1 pmuludq m6, m4 pshufd m6, m6, 0xd8 pmuludq m2, m0 pshufd m2, m2, 0xd8 punpckldq m2, m6 pshufd m6, m1, 0xb1 pshufd m4, m3, 0xb1 pmuludq m6, m4 pshufd m6, m6, 0xd8 pmuludq m3, m1 pshufd m3, m3, 0xd8 punpckldq m3, m6 %endif movd m4, roundm ; int sum = filter->round + ; Using horizontal add (phaddd) seems to be slower than shuffling stuff around paddd m2, m3 ; filter->dl[0] * filter->qm[0] + pshufd m3, m2, 0xe ; filter->dl[1] * filter->qm[1] + paddd m2, m3 ; filter->dl[2] * filter->qm[2] + ; filter->dl[3] * filter->qm[3] + ; filter->dl[4] * filter->qm[4] + paddd m4, m2 ; filter->dl[5] * filter->qm[5] + pshufd m2, m2, 0x1 ; filter->dl[6] * filter->qm[6] + paddd m4, m2 ; filter->dl[7] * filter->qm[7]; palignr m2, m1, m0, 4 ; filter->dl[0] = filter->dl[1]; filter->dl[1] = filter->dl[2]; ; filter->dl[2] = filter->dl[3]; filter->dl[3] = filter->dl[4]; psrad m3, m1, 30 ; filter->dx[4] = ((filter->dl[4] >> 30) | 1); por m3, [pd_1224 ] ; filter->dx[5] = ((filter->dl[5] >> 30) | 2) & ~1; movd m0, inm ; pand m3, [pd_n0113] ; filter->dx[6] = ((filter->dl[6] >> 30) | 2) & ~1; ; filter->dx[7] = ((filter->dl[7] >> 30) | 4) & ~3; mova [dlq ], m2 mova [dxq ], m5 mova [dxq + 0x10], m3 ; notice that eax is r6 (round) on x64 and r0 (qm) otherwise; ; round and qm are no longer needed. %ifidn %3,enc movd m2, shiftm ; psrad m4, m2 ; psrldq m1, 4 ; dl5, dl6, dl7, 0 psubd m3, m0, m4 ; *in -= (sum >> filter->shift); movd eax, m3 ; movd [errorq], m3 ; filter->error = *in; %else movd [errorq], m0 ; filter->error = *in; movd m2, shiftm ; *in += (sum >> filter->shift); psrad m4, m2 ; psrldq m1, 4 ; dl5, dl6, dl7, 0 paddd m0, m4 ; movd eax, m0 ; %endif pshufd m2, m1, q3321 ; dl6, dl7, 0, 0 pshufd m0, m0, 0 paddd m1, m2 ; dl5+dl6, dl6+dl7, dl7, 0 psrldq m2, 4 ; dl7 paddd m1, m2 ; dl5+dl6+dl7, dl5+dl6+dl7, dl6+dl7, dl7 psubd m0, m1 mova [dlq + 0x10], m0 ; RET %endmacro %if CONFIG_TTA_DECODER TTA_FILTER ssse3, 7 TTA_FILTER sse4, 7-avx_enabled %endif %if CONFIG_TTA_ENCODER TTA_FILTER ssse3, 7, enc TTA_FILTER sse4, 7-avx_enabled, enc %endif